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

Last change on this file since 1363 was 1353, checked in by seregin, 10 years ago

port rev 4431

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