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

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

port rev 4381

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