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

Last change on this file since 1329 was 1325, checked in by seregin, 10 years ago

port rev 4403

  • Property svn:eol-style set to native
File size: 167.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license.
5 *
6 * Copyright (c) 2010-2015, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncGOP.cpp
35    \brief    GOP encoder class
36*/
37
38#include <list>
39#include <algorithm>
40#include <functional>
41
42#include "TEncTop.h"
43#include "TEncGOP.h"
44#include "TEncAnalyze.h"
45#include "libmd5/MD5.h"
46#include "TLibCommon/SEI.h"
47#include "TLibCommon/NAL.h"
48#include "NALwrite.h"
49#include <time.h>
50#include <math.h>
51#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()
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 _SUMMARY_OUT_
2936  m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE, bitDepths);
2937#endif
2938#if _SUMMARY_PIC_
2939  m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE, bitDepths, 'I');
2940  m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE, bitDepths, 'P');
2941  m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE, bitDepths, 'B');
2942#endif
2943
2944  if(isField)
2945  {
2946    //-- interlaced summary
2947    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
2948    m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());
2949    // prior to the above statement, the interlace analyser does not contain the correct total number of bits.
2950
2951    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
2952    m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2953
2954#if _SUMMARY_OUT_
2955    m_gcAnalyzeAll_in.printSummary(chFmt, printSequenceMSE, bitDepths);
2956#endif
2957  }
2958
2959  printf("\nRVM: %.3lf\n" , xCalculateRVM());
2960}
2961
2962Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist )
2963{
2964  Bool bCalcDist = false;
2965  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
2966  m_pcLoopFilter->loopFilterPic( pcPic );
2967
2968  if (!bCalcDist)
2969  {
2970#if SVC_EXTENSION
2971    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getSlice(0)->getBitDepths());
2972#else
2973    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getPicSym()->getSPS().getBitDepths());
2974#endif
2975  }
2976}
2977
2978// ====================================================================================================================
2979// Protected member functions
2980// ====================================================================================================================
2981
2982
2983Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, Bool isField )
2984{
2985  assert( iNumPicRcvd > 0 );
2986  //  Exception for the first frames
2987  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
2988  {
2989    m_iGopSize    = 1;
2990  }
2991  else
2992  {
2993    m_iGopSize    = m_pcCfg->getGOPSize();
2994  }
2995  assert (m_iGopSize > 0);
2996
2997  return;
2998}
2999
3000
3001Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
3002                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
3003                         Int                       iNumPicRcvd,
3004                         Int                       iTimeOffset,
3005                         TComPic*&                 rpcPic,
3006                         TComPicYuv*&              rpcPicYuvRecOut,
3007                         Int                       pocCurr,
3008                         Bool                      isField)
3009{
3010  Int i;
3011  //  Rec. output
3012  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
3013
3014  if (isField && pocCurr > 1 && m_iGopSize!=1)
3015  {
3016    iTimeOffset--;
3017  }
3018
3019  for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
3020  {
3021    iterPicYuvRec--;
3022  }
3023
3024  rpcPicYuvRecOut = *(iterPicYuvRec);
3025
3026  //  Current pic.
3027  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
3028  while (iterPic != rcListPic.end())
3029  {
3030    rpcPic = *(iterPic);
3031    rpcPic->setCurrSliceIdx(0);
3032    if (rpcPic->getPOC() == pocCurr)
3033    {
3034      break;
3035    }
3036    iterPic++;
3037  }
3038
3039  assert (rpcPic != NULL);
3040  assert (rpcPic->getPOC() == pocCurr);
3041
3042  return;
3043}
3044
3045UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1, const BitDepths &bitDepths)
3046{
3047  UInt64  uiTotalDiff = 0;
3048
3049  for(Int chan=0; chan<pcPic0 ->getNumberValidComponents(); chan++)
3050  {
3051    const ComponentID ch=ComponentID(chan);
3052    Pel*  pSrc0   = pcPic0 ->getAddr(ch);
3053    Pel*  pSrc1   = pcPic1 ->getAddr(ch);
3054    UInt  uiShift     = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepths.recon[toChannelType(ch)]-8);
3055
3056    const Int   iStride = pcPic0->getStride(ch);
3057    const Int   iWidth  = pcPic0->getWidth(ch);
3058    const Int   iHeight = pcPic0->getHeight(ch);
3059
3060    for(Int y = 0; y < iHeight; y++ )
3061    {
3062      for(Int x = 0; x < iWidth; x++ )
3063      {
3064        Intermediate_Int iTemp = pSrc0[x] - pSrc1[x];
3065        uiTotalDiff += UInt64((iTemp*iTemp) >> uiShift);
3066      }
3067      pSrc0 += iStride;
3068      pSrc1 += iStride;
3069    }
3070  }
3071
3072  return uiTotalDiff;
3073}
3074
3075#if VERBOSE_RATE
3076static const Char* nalUnitTypeToString(NalUnitType type)
3077{
3078  switch (type)
3079  {
3080    case NAL_UNIT_CODED_SLICE_TRAIL_R:    return "TRAIL_R";
3081    case NAL_UNIT_CODED_SLICE_TRAIL_N:    return "TRAIL_N";
3082    case NAL_UNIT_CODED_SLICE_TSA_R:      return "TSA_R";
3083    case NAL_UNIT_CODED_SLICE_TSA_N:      return "TSA_N";
3084    case NAL_UNIT_CODED_SLICE_STSA_R:     return "STSA_R";
3085    case NAL_UNIT_CODED_SLICE_STSA_N:     return "STSA_N";
3086    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
3087    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
3088    case NAL_UNIT_CODED_SLICE_BLA_N_LP:   return "BLA_N_LP";
3089    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
3090    case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
3091    case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
3092    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
3093    case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
3094    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
3095    case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
3096    case NAL_UNIT_VPS:                    return "VPS";
3097    case NAL_UNIT_SPS:                    return "SPS";
3098    case NAL_UNIT_PPS:                    return "PPS";
3099    case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
3100    case NAL_UNIT_EOS:                    return "EOS";
3101    case NAL_UNIT_EOB:                    return "EOB";
3102    case NAL_UNIT_FILLER_DATA:            return "FILLER";
3103    case NAL_UNIT_PREFIX_SEI:             return "SEI";
3104    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
3105    default:                              return "UNK";
3106  }
3107}
3108#endif
3109
3110Void 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 )
3111{
3112  xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3113
3114  //In case of field coding, compute the interlaced PSNR for both fields
3115  if(isField)
3116  {
3117    Bool bothFieldsAreEncoded = false;
3118    Int correspondingFieldPOC = pcPic->getPOC();
3119    Int currentPicGOPPoc = m_pcCfg->getGOPEntry(iGOPid).m_POC;
3120    if(pcPic->getPOC() == 0)
3121    {
3122      // particular case for POC 0 and 1.
3123      // If they are not encoded first and separately from other pictures, we need to change this
3124      // POC 0 is always encoded first then POC 1 is encoded
3125      bothFieldsAreEncoded = false;
3126    }
3127    else if(pcPic->getPOC() == 1)
3128    {
3129      // if we are at POC 1, POC 0 has been encoded for sure
3130      correspondingFieldPOC = 0;
3131      bothFieldsAreEncoded = true;
3132    }
3133    else
3134    {
3135      if(pcPic->getPOC()%2 == 1)
3136      {
3137        correspondingFieldPOC -= 1; // all odd POC are associated with the preceding even POC (e.g poc 1 is associated to poc 0)
3138        currentPicGOPPoc      -= 1;
3139      }
3140      else
3141      {
3142        correspondingFieldPOC += 1; // all even POC are associated with the following odd POC (e.g poc 0 is associated to poc 1)
3143        currentPicGOPPoc      += 1;
3144      }
3145      for(Int i = 0; i < m_iGopSize; i ++)
3146      {
3147        if(m_pcCfg->getGOPEntry(i).m_POC == currentPicGOPPoc)
3148        {
3149          bothFieldsAreEncoded = m_pcCfg->getGOPEntry(i).m_isEncoded;
3150          break;
3151        }
3152      }
3153    }
3154
3155    if(bothFieldsAreEncoded)
3156    {
3157      //get complementary top field
3158      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
3159      while ((*iterPic)->getPOC() != correspondingFieldPOC)
3160      {
3161        iterPic ++;
3162      }
3163      TComPic* correspondingFieldPic = *(iterPic);
3164
3165      if( (pcPic->isTopField() && isFieldTopFieldFirst) || (!pcPic->isTopField() && !isFieldTopFieldFirst))
3166      {
3167        xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getPicYuvRec(), correspondingFieldPic->getPicYuvRec(), snr_conversion, printFrameMSE );
3168      }
3169      else
3170      {
3171        xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getPicYuvRec(), pcPic->getPicYuvRec(), snr_conversion, printFrameMSE );
3172      }
3173    }
3174  }
3175}
3176
3177Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3178{
3179  Double  dPSNR[MAX_NUM_COMPONENT];
3180
3181  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3182  {
3183    dPSNR[i]=0.0;
3184  }
3185
3186  TComPicYuv cscd;
3187  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3188  {
3189    cscd.create(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat(), pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), 0, false);
3190    TVideoIOYuv::ColourSpaceConvert(*pcPicD, cscd, conversion, false);
3191  }
3192  TComPicYuv &picd=(conversion==IPCOLOURSPACE_UNCHANGED)?*pcPicD : cscd;
3193
3194  //===== calculate PSNR =====
3195  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3196
3197  for(Int chan=0; chan<pcPicD->getNumberValidComponents(); chan++)
3198  {
3199    const ComponentID ch=ComponentID(chan);
3200    const TComPicYuv *pOrgPicYuv =(conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg() : pcPic ->getPicYuvOrg();
3201    const Pel*  pOrg       = pOrgPicYuv->getAddr(ch);
3202    const Int   iOrgStride = pOrgPicYuv->getStride(ch);
3203    Pel*  pRec             = picd.getAddr(ch);
3204    const Int   iRecStride = picd.getStride(ch);
3205    const Int   iWidth  = pcPicD->getWidth (ch) - (m_pcEncTop->getPad(0) >> pcPic->getComponentScaleX(ch));
3206    const Int   iHeight = pcPicD->getHeight(ch) - ((m_pcEncTop->getPad(1) >> (pcPic->isField()?1:0)) >> pcPic->getComponentScaleY(ch));
3207
3208    Int   iSize   = iWidth*iHeight;
3209
3210    UInt64 uiSSDtemp=0;
3211    for(Int y = 0; y < iHeight; y++ )
3212    {
3213      for(Int x = 0; x < iWidth; x++ )
3214      {
3215        Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3216        uiSSDtemp   += iDiff * iDiff;
3217      }
3218      pOrg += iOrgStride;
3219      pRec += iRecStride;
3220    }
3221#if SVC_EXTENSION
3222    const Int maxval = 255 << (pcPic->getSlice(0)->getBitDepth(toChannelType(ch)) - 8);
3223#else
3224    const Int maxval = 255 << (pcPic->getPicSym()->getSPS().getBitDepth(toChannelType(ch)) - 8);
3225#endif
3226    const Double fRefValue = (Double) maxval * maxval * iSize;
3227    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3228    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize);
3229  }
3230
3231
3232  /* calculate the size of the access unit, excluding:
3233   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3234   *  - SEI NAL units
3235   */
3236  UInt numRBSPBytes = 0;
3237  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3238  {
3239    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3240#if VERBOSE_RATE
3241    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
3242#endif
3243    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3244    {
3245      numRBSPBytes += numRBSPBytes_nal;
3246    }
3247  }
3248
3249  UInt uibits = numRBSPBytes * 8;
3250  m_vRVM_RP.push_back( uibits );
3251
3252  //===== add PSNR =====
3253  m_gcAnalyzeAll.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3254  TComSlice*  pcSlice = pcPic->getSlice(0);
3255  if (pcSlice->isIntra())
3256  {
3257    m_gcAnalyzeI.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3258  }
3259  if (pcSlice->isInterP())
3260  {
3261    m_gcAnalyzeP.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3262  }
3263  if (pcSlice->isInterB())
3264  {
3265    m_gcAnalyzeB.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3266  }
3267
3268  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
3269  if (!pcSlice->isReferenced())
3270  {
3271    c += 32;
3272  }
3273
3274#if SVC_EXTENSION
3275#if ADAPTIVE_QP_SELECTION 
3276  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, nQP %d QP %d ) %10d bits",
3277         pcSlice->getPOC(),
3278         pcSlice->getLayerId(),
3279         pcSlice->getTLayer(),
3280         c,
3281         NaluToStr( pcSlice->getNalUnitType() ).data(),
3282         pcSlice->getSliceQpBase(),
3283         pcSlice->getSliceQp(),
3284         uibits );
3285#else
3286  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP %d ) %10d bits",
3287         pcSlice->getPOC()-pcSlice->getLastIDR(),
3288         pcSlice->getLayerId(),
3289         pcSlice->getTLayer(),
3290         c,
3291         NaluToStr( pcSlice->getNalUnitType() ).data(),
3292         pcSlice->getSliceQp(),
3293         uibits );
3294#endif
3295#else
3296#if ADAPTIVE_QP_SELECTION
3297  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3298         pcSlice->getPOC(),
3299         pcSlice->getTLayer(),
3300         c,
3301         pcSlice->getSliceQpBase(),
3302         pcSlice->getSliceQp(),
3303         uibits );
3304#else
3305  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3306         pcSlice->getPOC()-pcSlice->getLastIDR(),
3307         pcSlice->getTLayer(),
3308         c,
3309         pcSlice->getSliceQp(),
3310         uibits );
3311#endif
3312#endif
3313
3314  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
3315  if (printFrameMSE)
3316  {
3317    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3318  }
3319  printf(" [ET %5.0f ]", dEncTime );
3320
3321  for (Int iRefList = 0; iRefList < 2; iRefList++)
3322  {
3323    printf(" [L%d ", iRefList);
3324    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
3325    {
3326#if SVC_EXTENSION
3327      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) )
3328      {
3329        UInt refLayerId = pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId();
3330        UInt refLayerIdc = pcSlice->getReferenceLayerIdc(refLayerId);
3331        assert( g_posScalingFactor[refLayerIdc][0] );
3332        assert( g_posScalingFactor[refLayerIdc][1] );
3333
3334        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] );
3335      }
3336      else
3337      {
3338        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
3339      }
3340
3341      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
3342      {
3343        printf( "c" );
3344      }
3345
3346      printf( " " );
3347#else
3348      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3349#endif
3350    }
3351    printf("]");
3352  }
3353#if CGS_3D_ASYMLUT
3354  pcPic->setFrameBit( (Int)uibits );
3355  if( m_layerId && pcSlice->getPPS()->getCGSFlag() )
3356  {
3357#if R0179_ENC_OPT_3DLUT_SIZE
3358      m_Enc3DAsymLUTPicUpdate.update3DAsymLUTParam( &m_Enc3DAsymLUTPPS );
3359#else
3360    if( m_Enc3DAsymLUTPPS.getPPSBit() > 0 )
3361      m_Enc3DAsymLUTPicUpdate.copy3DAsymLUT( &m_Enc3DAsymLUTPPS );
3362#endif
3363    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
3364  }
3365#endif
3366
3367  cscd.destroy();
3368}
3369
3370Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgFirstField, TComPic* pcPicOrgSecondField,
3371                                           TComPicYuv* pcPicRecFirstField, TComPicYuv* pcPicRecSecondField,
3372                                           const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3373{
3374#if !SVC_EXTENSION
3375  const TComSPS &sps=pcPicOrgFirstField->getPicSym()->getSPS();
3376#endif
3377  Double  dPSNR[MAX_NUM_COMPONENT];
3378  TComPic    *apcPicOrgFields[2]={pcPicOrgFirstField, pcPicOrgSecondField};
3379  TComPicYuv *apcPicRecFields[2]={pcPicRecFirstField, pcPicRecSecondField};
3380
3381  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3382  {
3383    dPSNR[i]=0.0;
3384  }
3385
3386  TComPicYuv cscd[2 /* first/second field */];
3387  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3388  {
3389    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3390    {
3391      TComPicYuv &reconField=*(apcPicRecFields[fieldNum]);
3392      cscd[fieldNum].create(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat(), reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), 0, false);
3393      TVideoIOYuv::ColourSpaceConvert(reconField, cscd[fieldNum], conversion, false);
3394      apcPicRecFields[fieldNum]=cscd+fieldNum;
3395    }
3396  }
3397
3398  //===== calculate PSNR =====
3399  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3400
3401  assert(apcPicRecFields[0]->getChromaFormat()==apcPicRecFields[1]->getChromaFormat());
3402  const UInt numValidComponents=apcPicRecFields[0]->getNumberValidComponents();
3403
3404  for(Int chan=0; chan<numValidComponents; chan++)
3405  {
3406    const ComponentID ch=ComponentID(chan);
3407    assert(apcPicRecFields[0]->getWidth(ch)==apcPicRecFields[1]->getWidth(ch));
3408    assert(apcPicRecFields[0]->getHeight(ch)==apcPicRecFields[1]->getHeight(ch));
3409
3410    UInt64 uiSSDtemp=0;
3411    const Int   iWidth  = apcPicRecFields[0]->getWidth (ch) - (m_pcEncTop->getPad(0) >> apcPicRecFields[0]->getComponentScaleX(ch));
3412    const Int   iHeight = apcPicRecFields[0]->getHeight(ch) - ((m_pcEncTop->getPad(1) >> 1) >> apcPicRecFields[0]->getComponentScaleY(ch));
3413
3414    Int   iSize   = iWidth*iHeight;
3415
3416    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3417    {
3418      TComPic *pcPic=apcPicOrgFields[fieldNum];
3419      TComPicYuv *pcPicD=apcPicRecFields[fieldNum];
3420
3421      const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
3422      Pel*  pRec    = pcPicD->getAddr(ch);
3423      const Int   iStride = pcPicD->getStride(ch);
3424
3425
3426      for(Int y = 0; y < iHeight; y++ )
3427      {
3428        for(Int x = 0; x < iWidth; x++ )
3429        {
3430          Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3431          uiSSDtemp   += iDiff * iDiff;
3432        }
3433        pOrg += iStride;
3434        pRec += iStride;
3435      }
3436    }
3437#if SVC_EXTENSION
3438    const Int maxval = 255 << (pcPicOrgFirstField->getSlice(0)->getBitDepth(toChannelType(ch)) - 8);
3439#else
3440    const Int maxval = 255 << (sps.getBitDepth(toChannelType(ch)) - 8);
3441#endif
3442    const Double fRefValue = (Double) maxval * maxval * iSize*2;
3443    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3444    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize*2);
3445  }
3446
3447  UInt uibits = 0; // the number of bits for the pair is not calculated here - instead the overall total is used elsewhere.
3448
3449  //===== add PSNR =====
3450  m_gcAnalyzeAll_in.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3451
3452  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] );
3453  if (printFrameMSE)
3454  {
3455    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3456  }
3457
3458  for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3459  {
3460    cscd[fieldNum].destroy();
3461  }
3462}
3463
3464/** Function for deciding the nal_unit_type.
3465 * \param pocCurr POC of the current picture
3466 * \param lastIDR  POC of the last IDR picture
3467 * \param isField  true to indicate field coding
3468 * \returns the NAL unit type of the picture
3469 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
3470 */
3471NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
3472{
3473  if (pocCurr == 0)
3474  {
3475    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3476  }
3477
3478  if(m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pocCurr == 1)
3479  {
3480    // to avoid the picture becoming an IRAP
3481    return NAL_UNIT_CODED_SLICE_TRAIL_R;
3482  }
3483
3484#if ALLOW_RECOVERY_POINT_AS_RAP
3485  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3486#else
3487  if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3488#endif
3489  {
3490    if (m_pcCfg->getDecodingRefreshType() == 1)
3491    {
3492      return NAL_UNIT_CODED_SLICE_CRA;
3493    }
3494    else if (m_pcCfg->getDecodingRefreshType() == 2)
3495    {
3496      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3497    }
3498  }
3499
3500#if SVC_POC
3501  if( m_pocCraWithoutReset > 0 && m_associatedIRAPType == NAL_UNIT_CODED_SLICE_CRA )
3502  {
3503    if(pocCurr < m_pocCraWithoutReset)
3504#else
3505  if(m_pocCRA>0)
3506  {
3507    if(pocCurr<m_pocCRA)
3508#endif
3509    {
3510      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3511      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3512      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3513      // controlling the reference pictures used for encoding that leading picture. Such a leading
3514      // picture need not be marked as a TFD picture.
3515      return NAL_UNIT_CODED_SLICE_RASL_R;
3516    }
3517  }
3518  if (lastIDR>0)
3519  {
3520    if (pocCurr < lastIDR)
3521    {
3522      return NAL_UNIT_CODED_SLICE_RADL_R;
3523    }
3524  }
3525  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3526}
3527
3528Double TEncGOP::xCalculateRVM()
3529{
3530  Double dRVM = 0;
3531
3532  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3533  {
3534    // calculate RVM only for lowdelay configurations
3535    std::vector<Double> vRL , vB;
3536    size_t N = m_vRVM_RP.size();
3537    vRL.resize( N );
3538    vB.resize( N );
3539
3540    Int i;
3541    Double dRavg = 0 , dBavg = 0;
3542    vB[RVM_VCEGAM10_M] = 0;
3543    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3544    {
3545      vRL[i] = 0;
3546      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
3547      {
3548        vRL[i] += m_vRVM_RP[j];
3549      }
3550      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
3551      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
3552      dRavg += m_vRVM_RP[i];
3553      dBavg += vB[i];
3554    }
3555
3556    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
3557    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
3558
3559    Double dSigamB = 0;
3560    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3561    {
3562      Double tmp = vB[i] - dBavg;
3563      dSigamB += tmp * tmp;
3564    }
3565    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
3566
3567    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
3568
3569    dRVM = dSigamB / dRavg * f;
3570  }
3571
3572  return( dRVM );
3573}
3574
3575/** Attaches the input bitstream to the stream in the output NAL unit
3576    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
3577 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
3578 *  \param rNalu          target NAL unit
3579 */
3580Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* codedSliceData)
3581{
3582  // Byte-align
3583  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
3584
3585  // Perform bitstream concatenation
3586  if (codedSliceData->getNumberOfWrittenBits() > 0)
3587  {
3588    rNalu.m_Bitstream.addSubstream(codedSliceData);
3589  }
3590
3591  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
3592
3593  codedSliceData->clear();
3594}
3595
3596// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
3597// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
3598Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
3599{
3600  TComReferencePictureSet *rps = pcSlice->getRPS();
3601  if(!rps->getNumberOfLongtermPictures())
3602  {
3603    return;
3604  }
3605
3606  // Arrange long-term reference pictures in the correct order of LSB and MSB,
3607  // and assign values for pocLSBLT and MSB present flag
3608  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
3609  Int longtermPicsMSB[MAX_NUM_REF_PICS];
3610  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
3611  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
3612  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
3613  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
3614  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
3615  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
3616
3617  // Get the long-term reference pictures
3618  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
3619  Int i, ctr = 0;
3620  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
3621  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3622  {
3623    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
3624    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
3625    indices[ctr]      = i;
3626    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
3627  }
3628  Int numLongPics = rps->getNumberOfLongtermPictures();
3629  assert(ctr == numLongPics);
3630
3631  // Arrange pictures in decreasing order of MSB;
3632  for(i = 0; i < numLongPics; i++)
3633  {
3634    for(Int j = 0; j < numLongPics - 1; j++)
3635    {
3636      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
3637      {
3638        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
3639        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
3640        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
3641        std::swap(indices[j]        , indices[j+1]        );
3642      }
3643    }
3644  }
3645
3646  for(i = 0; i < numLongPics; i++)
3647  {
3648    // Check if MSB present flag should be enabled.
3649    // Check if the buffer contains any pictures that have the same LSB.
3650    TComList<TComPic*>::iterator  iterPic = rcListPic.begin();
3651    TComPic*                      pcPic;
3652    while ( iterPic != rcListPic.end() )
3653    {
3654      pcPic = *iterPic;
3655      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
3656                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
3657                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
3658      {
3659        mSBPresentFlag[i] = true;
3660        break;
3661      }
3662      iterPic++;
3663    }
3664  }
3665
3666  // tempArray for usedByCurr flag
3667  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
3668  for(i = 0; i < numLongPics; i++)
3669  {
3670    tempArray[i] = rps->getUsed(indices[i]);
3671  }
3672  // Now write the final values;
3673  ctr = 0;
3674  Int currMSB = 0, currLSB = 0;
3675  // currPicPoc = currMSB + currLSB
3676  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB);
3677  currMSB = pcSlice->getPOC() - currLSB;
3678
3679  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3680  {
3681    rps->setPOC                   (i, longtermPicsPoc[ctr]);
3682    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
3683    rps->setUsed                  (i, tempArray[ctr]);
3684    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
3685    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
3686    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);
3687
3688    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
3689  }
3690  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
3691  {
3692    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
3693    {
3694      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
3695      // don't have to check the MSB present flag values for this constraint.
3696      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
3697    }
3698  }
3699}
3700
3701Void TEncGOP::applyDeblockingFilterMetric( TComPic* pcPic, UInt uiNumSlices )
3702{
3703  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
3704  Pel* Rec    = pcPicYuvRec->getAddr(COMPONENT_Y);
3705  Pel* tempRec = Rec;
3706  Int  stride = pcPicYuvRec->getStride(COMPONENT_Y);
3707  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
3708  UInt maxTBsize = (1<<log2maxTB);
3709  const UInt minBlockArtSize = 8;
3710  const UInt picWidth = pcPicYuvRec->getWidth(COMPONENT_Y);
3711  const UInt picHeight = pcPicYuvRec->getHeight(COMPONENT_Y);
3712  const UInt noCol = (picWidth>>log2maxTB);
3713  const UInt noRows = (picHeight>>log2maxTB);
3714  assert(noCol > 1);
3715  assert(noRows > 1);
3716  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
3717  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
3718  UInt colIdx = 0;
3719  UInt rowIdx = 0;
3720  Pel p0, p1, p2, q0, q1, q2;
3721
3722  Int qp = pcPic->getSlice(0)->getSliceQp();
3723#if SVC_EXTENSION
3724  const Int bitDepthLuma=pcPic->getSlice(0)->getBitDepth(CHANNEL_TYPE_LUMA);
3725#else
3726  const Int bitDepthLuma=pcPic->getSlice(0)->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
3727#endif
3728  Int bitdepthScale = 1 << (bitDepthLuma-8);
3729  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
3730  const Int thr2 = (beta>>2);
3731  const Int thr1 = 2*bitdepthScale;
3732  UInt a = 0;
3733
3734  memset(colSAD, 0, noCol*sizeof(UInt64));
3735  memset(rowSAD, 0, noRows*sizeof(UInt64));
3736
3737  if (maxTBsize > minBlockArtSize)
3738  {
3739    // Analyze vertical artifact edges
3740    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
3741    {
3742      for(Int r = 0; r < picHeight; r++)
3743      {
3744        p2 = Rec[c-3];
3745        p1 = Rec[c-2];
3746        p0 = Rec[c-1];
3747        q0 = Rec[c];
3748        q1 = Rec[c+1];
3749        q2 = Rec[c+2];
3750        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3751        if ( thr1 < a && a < thr2)
3752        {
3753          colSAD[colIdx] += abs(p0 - q0);
3754        }
3755        Rec += stride;
3756      }
3757      colIdx++;
3758      Rec = tempRec;
3759    }
3760
3761    // Analyze horizontal artifact edges
3762    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
3763    {
3764      for(Int c = 0; c < picWidth; c++)
3765      {
3766        p2 = Rec[c + (r-3)*stride];
3767        p1 = Rec[c + (r-2)*stride];
3768        p0 = Rec[c + (r-1)*stride];
3769        q0 = Rec[c + r*stride];
3770        q1 = Rec[c + (r+1)*stride];
3771        q2 = Rec[c + (r+2)*stride];
3772        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3773        if (thr1 < a && a < thr2)
3774        {
3775          rowSAD[rowIdx] += abs(p0 - q0);
3776        }
3777      }
3778      rowIdx++;
3779    }
3780  }
3781
3782  UInt64 colSADsum = 0;
3783  UInt64 rowSADsum = 0;
3784  for(Int c = 0; c < noCol-1; c++)
3785  {
3786    colSADsum += colSAD[c];
3787  }
3788  for(Int r = 0; r < noRows-1; r++)
3789  {
3790    rowSADsum += rowSAD[r];
3791  }
3792
3793  colSADsum <<= 10;
3794  rowSADsum <<= 10;
3795  colSADsum /= (noCol-1);
3796  colSADsum /= picHeight;
3797  rowSADsum /= (noRows-1);
3798  rowSADsum /= picWidth;
3799
3800  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
3801  avgSAD >>= (bitDepthLuma-8);
3802
3803  if ( avgSAD > 2048 )
3804  {
3805    avgSAD >>= 9;
3806    Int offset = Clip3(2,6,(Int)avgSAD);
3807    for (Int i=0; i<uiNumSlices; i++)
3808    {
3809      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
3810      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
3811      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
3812      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
3813    }
3814  }
3815  else
3816  {
3817    for (Int i=0; i<uiNumSlices; i++)
3818    {
3819      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
3820      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
3821      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
3822      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
3823    }
3824  }
3825
3826  free(colSAD);
3827  free(rowSAD);
3828}
3829
3830#if SVC_EXTENSION
3831#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3832Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym)
3833{
3834  Int numCUs = picSym->getFrameWidthInCtus() * picSym->getFrameHeightInCtus();
3835
3836  for (Int i = 0; i < numCUs; i++)
3837  {
3838    picSym->setTileSetIdxMap(i, -1, 0, false);
3839  }
3840
3841  for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
3842  {
3843    const TComTile* topLeftTile     = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i));
3844    TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i));
3845    Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCtus() - topLeftTile->getTileWidthInCtus() + 1;
3846    Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCtus();
3847    Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCtus() - topLeftTile->getTileHeightInCtus() + 1;
3848    Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCtus();
3849    assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU);
3850    for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++)
3851    {
3852      for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++)
3853      {
3854        picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCtus() + k, i, m_pcCfg->getIlcIdc(i), false);
3855      }
3856    }
3857  }
3858 
3859  if (m_pcCfg->getSkippedTileSetPresentFlag())
3860  {
3861    Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage();
3862    for (Int i = 0; i < numCUs; i++)
3863    {
3864      if (picSym->getTileSetIdxMap(i) < 0)
3865      {
3866        picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true);
3867      }
3868    }
3869  }
3870}
3871#endif
3872
3873Void TEncGOP::determinePocResetIdc(Int const pocCurr, TComSlice *const slice)
3874{
3875  // If one picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 1 or 2
3876  // If BL picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 2
3877  // If BL picture is IRAP, and another picture is non-IRAP, then the poc_reset_idc is equal to 1 or 2.
3878  slice->setPocMsbNeeded(false);
3879
3880  if( slice->getSliceIdx() == 0 ) // First slice - compute, copy for other slices
3881  {
3882    Int needReset = false;
3883    Int resetDueToBL = false;
3884    if( slice->getVPS()->getMaxLayers() > 1 )
3885    {
3886      // If IRAP is refreshed in this access unit for base layer
3887      if( (m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 1 || m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2)
3888        && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3889        )
3890      {
3891        // Check if the IRAP refresh interval of any layer does not match that of the base layer
3892        for(Int i = 1; i < slice->getVPS()->getMaxLayers(); i++)
3893        {
3894          Bool refreshIntervalFlag = ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 );
3895          Bool refreshTypeFlag     = ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() );
3896          if( !(refreshIntervalFlag && refreshTypeFlag) )
3897          {
3898            needReset = true;
3899            resetDueToBL = true;
3900            break;
3901          }
3902        }
3903      }
3904    }
3905
3906    if( !needReset )// No need reset due to base layer IRAP
3907    {
3908      // Check if EL IDRs results in POC Reset
3909      for(Int i = 1; i < slice->getVPS()->getMaxLayers() && !needReset; i++)
3910      {
3911        Bool idrFlag = ( (m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() == 2) 
3912          && ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3913          );
3914        for(Int j = 0; j < slice->getVPS()->getMaxLayers(); j++)
3915        {
3916          if( j == i )
3917          {
3918            continue;
3919          }
3920
3921          Bool idrOtherPicFlag = ( (m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshType() == 2) 
3922            && ( pocCurr % m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3923            );
3924
3925          if( idrFlag != idrOtherPicFlag )
3926          {
3927            needReset = true;
3928            break;
3929          }
3930        }
3931      }
3932    }
3933    if( needReset )
3934    {
3935      if( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2 )  // BL IDR refresh, assuming BL picture present
3936      {
3937        if( resetDueToBL )
3938        {
3939          slice->setPocResetIdc( 2 ); // Full reset needed
3940
3941          if( slice->getVPS()->getVpsPocLsbAlignedFlag() && slice->getVPS()->getNumDirectRefLayers(slice->getLayerId()) == 0 )
3942          {
3943            slice->setPocMsbNeeded(true);  // Force msb writing
3944          }
3945        }
3946        else
3947        {
3948          slice->setPocResetIdc( 1 ); // Due to IDR in EL
3949        }
3950      }
3951      else
3952      {
3953        slice->setPocResetIdc( 1 ); // Only MSB reset
3954      }
3955
3956      // Start a new POC reset period
3957      if (m_layerId == 0)   // Assuming BL picture is always present at encoder; for other AU structures, need to change this
3958      {
3959        Int periodId = rand() % 64;
3960        m_lastPocPeriodId = (periodId == m_lastPocPeriodId) ? (periodId + 1) % 64 : periodId ;
3961
3962        for( UInt i = 0; i < MAX_LAYERS; i++ )
3963        {
3964          m_ppcTEncTop[i]->setPocDecrementedInDPBFlag(false);
3965        }
3966      }
3967      else
3968      {
3969        m_lastPocPeriodId = m_ppcTEncTop[0]->getGOPEncoder()->getLastPocPeriodId();
3970      }
3971      slice->setPocResetPeriodId(m_lastPocPeriodId);
3972    }
3973    else
3974    {
3975      slice->setPocResetIdc( 0 );
3976    }
3977  }
3978}
3979
3980Void TEncGOP::updatePocValuesOfPics(Int const pocCurr, TComSlice *const slice)
3981{
3982  UInt affectedLayerList[MAX_NUM_LAYER_IDS];
3983  Int  numAffectedLayers;
3984
3985  affectedLayerList[0] = m_layerId;
3986  numAffectedLayers = 1;
3987
3988  if (m_pcEncTop->getVPS()->getVpsPocLsbAlignedFlag())
3989  {
3990    for (UInt j = 0; j < m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId); j++)
3991    {
3992      affectedLayerList[j + 1] = m_pcEncTop->getVPS()->getPredictedLayerId(m_layerId, j);
3993    }
3994    numAffectedLayers = m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId) + 1;
3995  }
3996
3997  Int pocAdjustValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
3998
3999  // New POC reset period
4000  Int maxPocLsb, pocLsbVal, pocMsbDelta, pocLsbDelta, deltaPocVal;
4001
4002  maxPocLsb   = 1 << slice->getSPS()->getBitsForPOC();
4003
4004  Int adjustedPocValue = pocCurr;
4005
4006  if (m_pcEncTop->getFirstPicInLayerDecodedFlag())
4007  {
4008    pocLsbVal   = (slice->getPocResetIdc() == 3)
4009      ? slice->getPocLsbVal()
4010      : pocAdjustValue % maxPocLsb; 
4011    pocMsbDelta = pocAdjustValue - pocLsbVal;
4012    pocLsbDelta = (slice->getPocResetIdc() == 2 || ( slice->getPocResetIdc() == 3 && slice->getFullPocResetFlag() )) 
4013      ? pocLsbVal 
4014      : 0; 
4015    deltaPocVal = pocMsbDelta  + pocLsbDelta;
4016
4017    Int origDeltaPocVal = deltaPocVal;  // original value needed when updating POC adjustment value
4018
4019    // IDR picture in base layer, non-IDR picture in other layers, poc_lsb_aligned_flag = 1
4020    if( slice->getPocMsbNeeded() )
4021    {
4022      if (slice->getLayerId() == 0)
4023      {
4024        Int highestPoc = INT_MIN;
4025
4026        // Find greatest POC in DPB for layer 0
4027        for (TComList<TComPic*>::iterator iterPic = m_pcEncTop->getListPic()->begin(); iterPic != m_pcEncTop->getListPic()->end(); ++iterPic)
4028        {
4029          TComPic *dpbPic = *iterPic;
4030          if (dpbPic->getReconMark() && dpbPic->getLayerId() == 0 && dpbPic->getPOC() > highestPoc)
4031          {
4032            highestPoc = dpbPic->getPOC();
4033          }
4034        }
4035        deltaPocVal = (highestPoc - (highestPoc & (maxPocLsb - 1))) + 1*maxPocLsb;
4036        m_pcEncTop->setCurrPocMsb(deltaPocVal);
4037      }
4038      else
4039      {
4040        deltaPocVal = m_ppcTEncTop[0]->getCurrPocMsb();  // copy from base layer
4041      }
4042      slice->setPocMsbVal(deltaPocVal);
4043    }
4044
4045    for( UInt layerIdx = 0; layerIdx < numAffectedLayers; layerIdx++ )
4046    {
4047      UInt lIdx = slice->getVPS()->getLayerIdxInVps(affectedLayerList[layerIdx]);
4048
4049      if( !m_ppcTEncTop[lIdx]->getPocDecrementedInDPBFlag() )
4050      {
4051        m_ppcTEncTop[lIdx]->setPocDecrementedInDPBFlag(true);
4052
4053        // Decrement value of associatedIrapPoc of the TEncGop object
4054        m_ppcTEncTop[lIdx]->getGOPEncoder()->m_associatedIRAPPOC -= deltaPocVal;
4055
4056        // Decrememnt the value of m_pocCRA
4057        m_ppcTEncTop[lIdx]->getGOPEncoder()->m_pocCRA -= deltaPocVal;
4058
4059        TComList<TComPic*>::iterator  iterPic = m_ppcTEncTop[lIdx]->getListPic()->begin();
4060        while (iterPic != m_ppcTEncTop[lIdx]->getListPic()->end())
4061        {
4062          TComPic *dpbPic = *iterPic;
4063
4064          if( dpbPic->getReconMark() )
4065          {
4066            for( Int i = dpbPic->getNumAllocatedSlice() - 1; i >= 0; i-- )
4067            {
4068              TComSlice *dpbPicSlice = dpbPic->getSlice( i );
4069              TComReferencePictureSet *dpbPicRps = dpbPicSlice->getRPS();
4070
4071              // Decrement POC of slice
4072              dpbPicSlice->setPOC( dpbPicSlice->getPOC() - deltaPocVal );
4073
4074              // Decrement POC value stored in the RPS of each such slice
4075              for( Int j = dpbPicRps->getNumberOfPictures() - 1; j >= 0; j-- )
4076              {
4077                dpbPicRps->setPOC( j, dpbPicRps->getPOC(j) - deltaPocVal );
4078              }
4079
4080              // Decrement value of refPOC
4081              dpbPicSlice->decrementRefPocValues( deltaPocVal );
4082
4083              // Update value of associatedIrapPoc of each slice
4084              dpbPicSlice->setAssociatedIRAPPOC( dpbPicSlice->getAssociatedIRAPPOC() - deltaPocVal );
4085
4086              if( slice->getPocMsbNeeded() )
4087              {
4088                // this delta value is needed when computing delta POCs in reference picture set initialization
4089                dpbPicSlice->setPocResetDeltaPoc(dpbPicSlice->getPocResetDeltaPoc() + (deltaPocVal - pocLsbVal));
4090              }
4091            }
4092          }
4093          iterPic++;
4094        }
4095      }
4096    }
4097
4098    // Actual POC value before reset
4099    adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4100
4101    // Set MSB value before reset
4102    Int tempLsbVal = adjustedPocValue & (maxPocLsb - 1);
4103    if (!slice->getPocMsbNeeded())  // set poc msb normally if special msb handling is not needed
4104    {
4105      slice->setPocMsbVal(adjustedPocValue - tempLsbVal);
4106    }
4107
4108    // Set LSB value before reset - this is needed in the case of resetIdc = 2
4109    slice->setPicOrderCntLsb( tempLsbVal );
4110
4111    // Cumulative delta
4112    deltaPocVal = origDeltaPocVal;  // restore deltaPoc for correct adjustment value update
4113
4114    m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + deltaPocVal );
4115  }
4116
4117  // New LSB value, after reset
4118  adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4119  Int newLsbVal = adjustedPocValue & (maxPocLsb - 1);
4120
4121  // Set value of POC current picture after RESET
4122  if( slice->getPocResetIdc() == 1 )
4123  {
4124    slice->setPOC( newLsbVal );
4125  }
4126  else if( slice->getPocResetIdc() == 2 )
4127  {
4128    slice->setPOC( 0 );
4129  }
4130  else if( slice->getPocResetIdc() == 3 )
4131  {
4132    Int picOrderCntMsb = slice->getCurrMsb( newLsbVal, 
4133      slice->getFullPocResetFlag() ? 0 : slice->getPocLsbVal(), 
4134      0,
4135      maxPocLsb );
4136    slice->setPOC( picOrderCntMsb + newLsbVal );
4137  }
4138  else
4139  {
4140    assert(0);
4141  }
4142}
4143
4144#if CGS_3D_ASYMLUT
4145Void TEncGOP::xDetermin3DAsymLUT( TComSlice * pSlice, TComPic * pCurPic, UInt refLayerIdc, TEncCfg * pCfg, Bool bSignalPPS )
4146{
4147  Int nCGSFlag = pSlice->getPPS()->getCGSFlag();
4148  m_Enc3DAsymLUTPPS.setPPSBit( 0 );
4149  Double dErrorUpdatedPPS = 0 , dErrorPPS = 0;
4150
4151#if R0179_ENC_OPT_3DLUT_SIZE
4152  Int nTLthres = m_pcCfg->getCGSLutSizeRDO() ? 2:7;
4153  Double dFrameLambda; 
4154#if FULL_NBIT
4155  Int    SHIFT_QP = 12 + 6 * (pSlice->getBitDepthY() - 8);
4156#else
4157  Int    SHIFT_QP = 12; 
4158#endif
4159  Int QP = pSlice->getSliceQp();
4160
4161  // set frame lambda
4162  dFrameLambda = 0.68 * pow (2, (QP  - SHIFT_QP) / 3.0) * (m_pcCfg->getGOPSize() > 1 && pSlice->isInterB()? 2 : 1);
4163
4164  if(m_pcCfg->getCGSLutSizeRDO() == 1 && (!bSignalPPS && (pSlice->getDepth() < nTLthres))) 
4165    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB(), dFrameLambda );
4166  else if (pSlice->getDepth() >= nTLthres)
4167    dErrorUpdatedPPS = MAX_DOUBLE;
4168  else // if (m_pcCfg->getCGSLutSizeRDO() = 0 || bSignalPPS)
4169#endif   
4170    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() );
4171
4172
4173  if( bSignalPPS )
4174  {
4175    m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4176    pSlice->setCGSOverWritePPS( 1 ); // regular PPS update
4177  }
4178  else if( nCGSFlag )
4179  {
4180#if R0179_ENC_OPT_3DLUT_SIZE
4181    if(pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R || pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N) 
4182    {
4183      pSlice->setCGSOverWritePPS( 0 ); 
4184    }
4185    else if (pSlice->getDepth() >= nTLthres) 
4186    {
4187      pSlice->setCGSOverWritePPS( 0 ); 
4188    }
4189    else
4190    {
4191#endif   
4192      dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc );
4193      Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9;
4194
4195#if R0179_ENC_OPT_3DLUT_SIZE
4196      if( m_pcCfg->getCGSLutSizeRDO() )
4197      {
4198        dErrorPPS = dErrorPPS/m_Enc3DAsymLUTPicUpdate.getDistFactor(pSlice->getSliceType(), pSlice->getDepth()); 
4199      }
4200#endif
4201      pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS );
4202#if R0179_ENC_OPT_3DLUT_SIZE
4203    }
4204#endif
4205    if( pSlice->getCGSOverWritePPS() )
4206    {
4207      m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4208    }
4209  }
4210}
4211
4212Void TEncGOP::downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest, BitDepths& bitDepth)
4213{
4214  pcYuvSrc->setBorderExtension(false);
4215  pcYuvSrc->extendPicBorder   (); // extend the border.
4216  pcYuvSrc->setBorderExtension(false);
4217
4218  Int iWidth  = pcYuvSrc->getWidth(COMPONENT_Y);
4219  Int iHeight = pcYuvSrc->getHeight(COMPONENT_Y); 
4220
4221  if(!m_temp)
4222  {
4223    initDs(iWidth, iHeight, m_pcCfg->getIntraPeriod()>1);
4224  }
4225
4226  filterImg(pcYuvSrc->getAddr(COMPONENT_Y),  pcYuvSrc->getStride(COMPONENT_Y),  pcYuvDest->getAddr(COMPONENT_Y),  pcYuvDest->getStride(COMPONENT_Y),  iHeight,    iWidth,    bitDepth, 0);
4227  filterImg(pcYuvSrc->getAddr(COMPONENT_Cb), pcYuvSrc->getStride(COMPONENT_Cb), pcYuvDest->getAddr(COMPONENT_Cb), pcYuvDest->getStride(COMPONENT_Cb), iHeight>>1, iWidth>>1, bitDepth, 1);
4228  filterImg(pcYuvSrc->getAddr(COMPONENT_Cr), pcYuvSrc->getStride(COMPONENT_Cr), pcYuvDest->getAddr(COMPONENT_Cr), pcYuvDest->getStride(COMPONENT_Cr), iHeight>>1, iWidth>>1, bitDepth, 2); 
4229}
4230const Int TEncGOP::m_phase_filter_0_t0[4][13]={
4231  {0,  2,  -3,  -9,   6,  39,  58,  39,   6,  -9,  -3,  2,  0}, 
4232  {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},  //
4233  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4234  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4235};
4236
4237const Int TEncGOP::m_phase_filter_0_t1[4][13]={
4238  {0,  4,  0,  -12, 0,  40,  64,  40, 0, -12,  0,  4,  0},
4239  {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},  //
4240  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4241  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4242};
4243const Int TEncGOP::m_phase_filter_0_t1_chroma[4][13]={
4244  {0,  0,  0,   0,  0,   0,  128, 0,  0,  0,  0,  0,  0},
4245  {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},  //
4246  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4247  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4248};
4249
4250const Int TEncGOP::m_phase_filter_1[8][13]={
4251  {0,   0,  5,  -6,  -10,37,  76,  37,-10,   -6, 5,  0,   0},   
4252  {0,  -1,  5,  -3,  -12,29,  75,  45,  -7,   -8, 5,  0,   0},   
4253  {0,  -1,  4,  -1,  -13,22,  73,  52,  -3,  -10, 4,  1,   0},   
4254  {0,  -1,  4,   1,  -13,14,  70,  59,   2,  -12, 3,  2,  -1}, 
4255  {0,  -1,  3,   2,  -13, 8,  65,  65,   8,  -13, 2,  3,  -1},   
4256  {0,  -1,  2,   3,  -12, 2,  59,  70,  14,  -13, 1,  4,  -1},   
4257  {0,   0,  1,   4,  -10,-3,  52,  73,  22,  -13,-1,  4,  -1},   
4258  {0,   0,  0,   5,   -8,-7,  45,  75,  29,  -12,-3,  5,  -1}   
4259};
4260
4261#if CGS_GCC_NO_VECTORIZATION 
4262#ifdef __GNUC__
4263#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
4264#if GCC_VERSION > 40600
4265__attribute__((optimize("no-tree-vectorize")))
4266#endif
4267#endif
4268#endif
4269Void TEncGOP::filterImg( Pel *src, Int iSrcStride, Pel *dst, Int iDstStride, Int height1, Int width1, BitDepths& bitDepth, Int plane )
4270{
4271  Int length = m_iTap;
4272  Int height2,width2;
4273  Int k,iSum;
4274  Int i0, div_i0, i1;
4275  Int j0, div_j0, j1;
4276  const Int *p_filter;
4277  Pel *p_src, *p_dst;
4278  Pel *p_src_line, *p_dst_line;
4279  Int **p_temp, *p_tmp;
4280  Int shift = bitDepth.recon[CHANNEL_TYPE_LUMA] - bitDepth.recon[CHANNEL_TYPE_CHROMA];
4281  Int shift2 = 2*7+shift;
4282  Int shift_round = (1 << (shift2 - 1));
4283  Int iMax = (1<<(bitDepth.recon[CHANNEL_TYPE_LUMA]-shift))-1;
4284  height2 = (height1 * m_iM) / m_iN;
4285  width2  = (width1  * m_iM) / m_iN;
4286
4287  m_phase_filter = plane? m_phase_filter_chroma : m_phase_filter_luma;
4288
4289  // horizontal filtering
4290  p_src_line = src;
4291  for(j1 = 0; j1 < height1; j1++)
4292  {
4293    i0=-m_iN;
4294    p_tmp = m_temp[j1];
4295   
4296    for(i1 = 0; i1 < width2; i1++)
4297    {
4298      i0      += m_iN;
4299      div_i0   = (i0 / m_iM);
4300      p_src    =  p_src_line + ( div_i0 - (length >> 1));
4301      p_filter = m_phase_filter[i0 - div_i0 * m_iM]; // phase_filter[i0 % M]
4302      iSum     = 0;
4303      for(k = 0; k < length; k++)
4304      {
4305        iSum += (*p_src++) * (*p_filter++);
4306      }
4307      *p_tmp++ = iSum;
4308    }
4309    p_src_line +=  iSrcStride;
4310  }
4311
4312  // pad temp (vertical)
4313  for (k=-(length>>1); k<0; k++)
4314  {
4315    memcpy(m_temp[k], m_temp[0], width2*sizeof(Int));
4316  }
4317  for (k=height1; k<(height1+(length>>1)); k++)
4318  {
4319    memcpy(m_temp[k], m_temp[k-1], (width2)* sizeof(Int));
4320  }
4321
4322  // vertical filtering
4323  j0 = (plane == 0) ? -m_iN : -(m_iN-1);
4324 
4325  p_dst_line = dst;
4326  for(j1 = 0; j1 < height2; j1++)
4327  {
4328    j0      += m_iN;
4329    div_j0   = (j0 / m_iM);
4330    p_dst = p_dst_line;
4331    p_temp   = &m_temp[div_j0 - (length>>1)];
4332    p_filter = m_phase_filter[j0 - div_j0 * m_iM]; // phase_filter[j0 % M]
4333    for(i1 = 0; i1 < width2;i1++)
4334    {
4335      iSum=0;
4336      for(k = 0; k < length; k++)
4337      {
4338        iSum += p_temp[k][i1] * p_filter[k];
4339      }
4340      iSum=((iSum + shift_round) >> shift2);
4341      *p_dst++ = (Short)(iSum > iMax ? iMax : (iSum < 0 ? 0 : iSum));
4342    }
4343    p_dst_line += iDstStride;
4344  }
4345}
4346
4347Void TEncGOP::initDs(Int iWidth, Int iHeight, Int iType)
4348{
4349  m_iTap = 13;
4350  if(g_posScalingFactor[0][0] == (1<<15))
4351  {
4352    m_iM = 4;
4353    m_iN = 8;
4354    m_phase_filter_luma = iType? m_phase_filter_0_t1 : m_phase_filter_0_t0;
4355    m_phase_filter_chroma = m_phase_filter_0_t1_chroma; 
4356  }
4357  else
4358  {
4359    m_iM = 8;
4360    m_iN = 12;
4361    m_phase_filter_luma = m_phase_filter_chroma =  m_phase_filter_1;
4362    m_phase_filter = m_phase_filter_1;
4363  }
4364
4365  get_mem2DintWithPad (&m_temp, iHeight, iWidth*m_iM/m_iN,   m_iTap>>1, 0);
4366}
4367
4368Int TEncGOP::get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX)
4369{
4370  Int i;
4371  Int *curr = NULL;
4372  Int iHeight, iWidth;
4373
4374  iHeight = dim0+2*iPadY;
4375  iWidth = dim1+2*iPadX;
4376  (*array2D) = (Int**)malloc(iHeight*sizeof(Int*));
4377  *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth);
4378
4379  (*array2D)[0] += iPadX;
4380  curr = (*array2D)[0];
4381  for(i = 1 ; i < iHeight; i++)
4382  {
4383    curr += iWidth;
4384    (*array2D)[i] = curr;
4385  }
4386  (*array2D) = &((*array2D)[iPadY]);
4387
4388  return 0;
4389}
4390
4391Void TEncGOP::free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX)
4392{
4393  if (array2D)
4394  {
4395    if (*array2D)
4396    {
4397      xFree(array2D[-iPadY]-iPadX);
4398    }
4399    else 
4400    {
4401      printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
4402    }
4403
4404    free (&array2D[-iPadY]);
4405  } 
4406  else
4407  {
4408    printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
4409  }
4410}
4411#endif
4412
4413Void TEncGOP::xCheckLayerReset(TComSlice *slice)
4414{
4415  Bool layerResetFlag;
4416  Int dolLayerId;
4417
4418  if (slice->isIRAP() && slice->getLayerId() > 0)
4419  {
4420    if (m_prevPicHasEos)
4421    {
4422      layerResetFlag = true;
4423      dolLayerId = slice->getLayerId();
4424    }
4425    else if ((slice->isCRA() && slice->getHandleCraAsBlaFlag()) || (slice->isIDR() && slice->getCrossLayerBLAFlag()) || slice->isBLA())
4426    {
4427      layerResetFlag = true;
4428      dolLayerId = slice->getLayerId();
4429    }
4430    else
4431    {
4432      layerResetFlag = false;
4433    }
4434
4435    if (layerResetFlag)
4436    {
4437      for (Int i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
4438      {
4439        Int iLayerId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
4440        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(iLayerId)]->setLayerInitializedFlag(false);
4441        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(iLayerId)]->setFirstPicInLayerDecodedFlag(false);
4442      }
4443
4444      // Each picture that is in the DPB and has nuh_layer_id equal to dolLayerId is marked as "unused for reference".
4445      for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(dolLayerId)]->getListPic()->begin(); pic != m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(dolLayerId)]->getListPic()->end(); pic++)
4446      {
4447        if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
4448        {
4449          (*pic)->getSlice(0)->setReferenced(false);
4450        }
4451      }
4452
4453      // Each picture that is in DPB and has nuh_layer_id equal to any value of IdPredictedLayer[dolLayerId][i]
4454      // for the values of i in range of 0 to NumPredictedLayers[dolLayerId] - 1, inclusive, is marked as "unused for reference"
4455      for (UInt i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
4456      {
4457        UInt predLId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
4458        for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(predLId)]->getListPic()->begin(); pic != m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(predLId)]->getListPic()->end(); pic++)
4459        {
4460          if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
4461          {
4462            (*pic)->getSlice(0)->setReferenced(false);
4463          }
4464        }
4465      }
4466    }
4467  }
4468}
4469
4470Void TEncGOP::xSetNoRaslOutputFlag(TComSlice *slice)
4471{
4472  if (slice->isIRAP())
4473  {
4474    m_noRaslOutputFlag = slice->getHandleCraAsBlaFlag();  // default value
4475    if (slice->isIDR() || slice->isBLA() || m_bFirst || m_prevPicHasEos)
4476    {
4477      m_noRaslOutputFlag = true;
4478    }
4479    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag())
4480    {
4481      Bool refLayersInitialized = true;
4482      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
4483      {
4484        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
4485        if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(refLayerId)]->getLayerInitializedFlag())
4486        {
4487          refLayersInitialized = false;
4488        }
4489      }
4490      if (refLayersInitialized)
4491      {
4492        m_noRaslOutputFlag = true;
4493      }
4494    }
4495  }
4496}
4497
4498Void TEncGOP::xSetLayerInitializedFlag(TComSlice *slice)
4499{
4500  if (slice->isIRAP() && m_noRaslOutputFlag)
4501  {
4502    if (m_layerId == 0)
4503    {
4504      m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4505    }
4506    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag() && slice->getVPS()->getNumDirectRefLayers(m_layerId) == 0)
4507    {
4508      m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4509    }
4510    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag())
4511    {
4512      Bool refLayersInitialized = true;
4513      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
4514      {
4515        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
4516        if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(refLayerId)]->getLayerInitializedFlag())
4517        {
4518          refLayersInitialized = false;
4519        }
4520      }
4521      if (refLayersInitialized)
4522      {
4523        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4524      }
4525    }
4526  }
4527}
4528#endif //SVC_EXTENSION
4529
4530#if Q0074_COLOUR_REMAPPING_SEI
4531Bool confirmParameter(Bool bflag, const Char* message)
4532{
4533  if (!bflag)
4534    return false;
4535
4536  printf("Error: %s\n",message);
4537  return true;
4538}
4539#endif
4540
4541//! \}
Note: See TracBrowser for help on using the repository browser.