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

Last change on this file since 1406 was 1400, checked in by seregin, 10 years ago

port rev 4553

  • Property svn:eol-style set to native
File size: 165.8 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    if (!m_pcCfg->getEfficientFieldIRAPEnabled())
1929    {
1930      if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1931        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1932        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1933        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1934        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1935        || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
1936      {
1937        m_associatedIRAPType = pcSlice->getNalUnitType();
1938        m_associatedIRAPPOC = pocCurr;
1939      }
1940      pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
1941      pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
1942    }
1943
1944    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) 
1945      || (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)
1946      )
1947    {
1948      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3, m_pcCfg->getEfficientFieldIRAPEnabled());
1949    }
1950
1951#if ALIGNED_BUMPING
1952    pcSlice->checkLeadingPictureRestrictions(rcListPic, true);
1953#endif
1954    pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
1955
1956    if(pcSlice->getTLayer() > 0 
1957      &&  !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     // Check if not a leading picture
1958          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
1959          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
1960          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R )
1961        )
1962    {
1963      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag())
1964      {
1965        if(pcSlice->getTemporalLayerNonReferenceFlag())
1966        {
1967          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1968        }
1969        else
1970        {
1971          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R);
1972        }
1973      }
1974      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
1975      {
1976        Bool isSTSA=true;
1977        for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
1978        {
1979          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
1980          if(lTid==pcSlice->getTLayer())
1981          {
1982            const TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
1983            for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
1984            {
1985              if(nRPS->getUsed(jj))
1986              {
1987                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
1988                Int kk=0;
1989                for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
1990                {
1991                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
1992                  {
1993                    break;
1994                  }
1995                }
1996                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
1997                if(tTid >= pcSlice->getTLayer())
1998                {
1999                  isSTSA=false;
2000                  break;
2001                }
2002              }
2003            }
2004          }
2005        }
2006        if(isSTSA==true)
2007        {
2008          if(pcSlice->getTemporalLayerNonReferenceFlag())
2009          {
2010            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
2011          }
2012          else
2013          {
2014            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
2015          }
2016        }
2017      }
2018    }
2019    arrangeLongtermPicturesInRPS(pcSlice, rcListPic);
2020    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
2021    refPicListModification->setRefPicListModificationFlagL0(0);
2022    refPicListModification->setRefPicListModificationFlagL1(0);
2023    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
2024    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
2025
2026#if SVC_EXTENSION
2027    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
2028    {
2029      if( pocCurr > 0 && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL() )
2030      {
2031        pcSlice->setActiveNumILRRefIdx(0);
2032        pcSlice->setInterLayerPredEnabledFlag(0);
2033      }
2034
2035      if( pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
2036      {
2037        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getActiveNumILRRefIdx());
2038        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getActiveNumILRRefIdx());
2039      }
2040      else
2041      {
2042        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getNumRefIdx(REF_PIC_LIST_0)+pcSlice->getActiveNumILRRefIdx());
2043        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getNumRefIdx(REF_PIC_LIST_1)+pcSlice->getActiveNumILRRefIdx());
2044      }
2045
2046      // check for the reference pictures whether there is at least one either temporal picture or ILRP with sample prediction type
2047      if( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) - pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) - pcSlice->getActiveNumILRRefIdx() == 0 )
2048      {
2049        Bool foundSamplePredPicture = false;               
2050
2051        for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
2052        {
2053          if( pcSlice->getVPS()->isSamplePredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), pcSlice->getInterLayerPredLayerIdc(i) ) )
2054          {
2055            foundSamplePredPicture = true;
2056            break;
2057          }
2058        }
2059
2060        if( !foundSamplePredPicture )
2061        {
2062          pcSlice->setSliceType(I_SLICE);
2063          pcSlice->setInterLayerPredEnabledFlag(0);
2064          pcSlice->setActiveNumILRRefIdx(0);
2065        }
2066      }
2067    }
2068
2069   if( ( pcSlice->getTLayer() == 0 && pcSlice->getLayerId() > 0  )    // only for enhancement layer and with temporal layer 0
2070     && !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     
2071          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
2072          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
2073          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R
2074          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
2075          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
2076          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA
2077          )
2078        )
2079    {
2080        Bool isSTSA=true;
2081        Bool isIntra=false;
2082
2083        for( Int i = 0; i < pcSlice->getLayerId(); i++)
2084        {
2085          TComList<TComPic *> *cListPic = m_ppcTEncTop[pcSlice->getVPS()->getLayerIdxInVps(i)]->getListPic();
2086          TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC());
2087          if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerIdx(), i) )
2088          {
2089            if( lowerLayerPic->getSlice(0)->getSliceType() == I_SLICE)
2090            { 
2091              isIntra = true;
2092            }
2093          }
2094        }
2095
2096        for(Int ii=iGOPid+1; ii < m_pcCfg->getGOPSize() && isSTSA; ii++)
2097        {
2098          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
2099          if(lTid==pcSlice->getTLayer()) 
2100          {
2101            const TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
2102            for(Int jj=0; jj<nRPS->getNumberOfPictures(); jj++)
2103            {
2104              if(nRPS->getUsed(jj)) 
2105              {
2106                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
2107                Int kk=0;
2108                for(kk=0; kk<m_pcCfg->getGOPSize(); kk++)
2109                {
2110                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
2111                  {
2112                    break;
2113                  }
2114                }
2115                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
2116                if(tTid >= pcSlice->getTLayer())
2117                {
2118                  isSTSA = false;
2119                  break;
2120                }
2121              }
2122            }
2123          }
2124        }
2125        if(isSTSA==true && isIntra == false)
2126        {   
2127          if(pcSlice->getTemporalLayerNonReferenceFlag())
2128          {
2129            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
2130          }
2131          else
2132          {
2133            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
2134          }
2135        }
2136    }
2137
2138    if( pcSlice->getSliceType() == B_SLICE )
2139    {
2140      pcSlice->setColFromL0Flag(1-uiColDir);
2141    }
2142
2143    //  Set reference list
2144    if(m_layerId ==  0 || ( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() == 0 ) )
2145    {
2146      pcSlice->setRefPicList( rcListPic );
2147    }
2148
2149    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
2150    {
2151      pcSlice->setILRPic( m_pcEncTop->getIlpList() );
2152      pcSlice->setRefPicListModificationSvc();
2153      pcSlice->setRefPicList( rcListPic, false, m_pcEncTop->getIlpList());
2154
2155      if( pcSlice->getMFMEnabledFlag() )
2156      {
2157        Bool found         = false;
2158        UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
2159        UInt ColRefIdx     = pcSlice->getColRefIdx();
2160
2161        for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
2162        {
2163          RefPicList refList = RefPicList(1 - ColFromL0Flag);
2164          TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
2165
2166          // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
2167          // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
2168          if( refPic->isILR(m_layerId) && pcSlice->getVPS()->isMotionPredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() )           
2169            && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerIdx()]->getListPic() )->checkSameRefInfo() == true ) 
2170          { 
2171            ColRefIdx = colIdx; 
2172            found = true;
2173            break; 
2174          }
2175        }
2176
2177        if( found == false )
2178        {
2179          ColFromL0Flag = 1 - ColFromL0Flag;
2180          for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
2181          {
2182            RefPicList refList = RefPicList(1 - ColFromL0Flag);
2183            TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
2184
2185            // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
2186            // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
2187            if( refPic->isILR(m_layerId) && pcSlice->getVPS()->isMotionPredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() )
2188              && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerIdx()]->getListPic() )->checkSameRefInfo() == true ) 
2189            { 
2190              ColRefIdx = colIdx; 
2191              found = true; 
2192              break; 
2193            } 
2194          }
2195        }
2196
2197        if(found == true)
2198        {
2199          pcSlice->setColFromL0Flag(ColFromL0Flag);
2200          pcSlice->setColRefIdx(ColRefIdx);
2201        }
2202      }
2203    }
2204#else //SVC_EXTENSION
2205    //  Set reference list
2206    pcSlice->setRefPicList ( rcListPic );
2207#endif //#if SVC_EXTENSION
2208
2209    //  Slice info. refinement
2210    if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
2211    {
2212      pcSlice->setSliceType ( P_SLICE );
2213    }
2214    pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
2215
2216    if (pcSlice->getSliceType() == B_SLICE)
2217    {
2218#if !SVC_EXTENSION
2219      pcSlice->setColFromL0Flag(1-uiColDir);
2220#endif
2221      Bool bLowDelay = true;
2222      Int  iCurrPOC  = pcSlice->getPOC();
2223      Int iRefIdx = 0;
2224
2225      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
2226      {
2227        if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
2228        {
2229          bLowDelay = false;
2230        }
2231      }
2232      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
2233      {
2234        if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
2235        {
2236          bLowDelay = false;
2237        }
2238      }
2239
2240      pcSlice->setCheckLDC(bLowDelay);
2241    }
2242    else
2243    {
2244      pcSlice->setCheckLDC(true);
2245    }
2246
2247    uiColDir = 1-uiColDir;
2248
2249    //-------------------------------------------------------------
2250    pcSlice->setRefPOCList();
2251
2252    pcSlice->setList1IdxToList0Idx();
2253
2254    if (m_pcEncTop->getTMVPModeId() == 2)
2255    {
2256      if (iGOPid == 0) // first picture in SOP (i.e. forward B)
2257      {
2258        pcSlice->setEnableTMVPFlag(0);
2259      }
2260      else
2261      {
2262        // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
2263        pcSlice->setEnableTMVPFlag(1);
2264      }
2265    }
2266    else if (m_pcEncTop->getTMVPModeId() == 1)
2267    {
2268#if SVC_EXTENSION
2269      if( pcSlice->getIdrPicFlag() )
2270      {
2271        pcSlice->setEnableTMVPFlag(0);
2272      }
2273      else
2274#endif
2275      pcSlice->setEnableTMVPFlag(1);
2276    }
2277    else
2278    {
2279      pcSlice->setEnableTMVPFlag(0);
2280    }
2281
2282#if SVC_EXTENSION
2283    if( m_layerId > 0 && !pcSlice->isIntra() )
2284    {
2285      Int colFromL0Flag = 1;
2286      Int colRefIdx = 0;
2287
2288      // check whether collocated picture is valid
2289      if( pcSlice->getEnableTMVPFlag() )
2290      {
2291        colFromL0Flag = pcSlice->getColFromL0Flag();
2292        colRefIdx = pcSlice->getColRefIdx();
2293
2294        TComPic* refPic = pcSlice->getRefPic(RefPicList(1-colFromL0Flag), colRefIdx);
2295
2296        assert( refPic );
2297
2298        // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
2299        // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
2300        if( refPic->isILR(m_layerId) && !pcSlice->getVPS()->isMotionPredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() ) )
2301        {
2302          pcSlice->setEnableTMVPFlag(false);
2303          pcSlice->setMFMEnabledFlag(false);
2304          colRefIdx = 0;
2305        }
2306      }
2307
2308      // remove motion only ILRP from the end of the colFromL0Flag reference picture list
2309      RefPicList refList = RefPicList(colFromL0Flag);
2310      Int numRefIdx = pcSlice->getNumRefIdx(refList);
2311
2312      if( numRefIdx > 0 )
2313      {
2314        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > 0; refIdx-- )
2315        {
2316          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
2317
2318          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && pcSlice->getVPS()->isSamplePredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() ) ) )
2319          {
2320            break;
2321          }
2322          else
2323          {
2324            assert( numRefIdx > 1 );
2325            numRefIdx--;             
2326          }
2327        }
2328
2329        pcSlice->setNumRefIdx( refList, numRefIdx );
2330      }
2331
2332      // remove motion only ILRP from the end of the (1-colFromL0Flag) reference picture list up to colRefIdx
2333      refList = RefPicList(1 - colFromL0Flag);
2334      numRefIdx = pcSlice->getNumRefIdx(refList);
2335
2336      if( numRefIdx > 0 )
2337      {
2338        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > colRefIdx; refIdx-- )
2339        {
2340          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
2341
2342          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && pcSlice->getVPS()->isSamplePredictionType( pcSlice->getVPS()->getLayerIdxInVps(m_layerId), refPic->getLayerIdx() ) ) )
2343          {
2344            break;
2345          }
2346          else
2347          {
2348            assert( numRefIdx > 1 );
2349            numRefIdx--;             
2350          }
2351        }
2352
2353        pcSlice->setNumRefIdx( refList, numRefIdx );
2354      }
2355
2356      assert( pcSlice->getNumRefIdx(REF_PIC_LIST_0) > 0 && ( pcSlice->isInterP() || (pcSlice->isInterB() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) > 0) ) );
2357    }
2358#endif
2359
2360    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
2361    // set adaptive search range for non-intra-slices
2362    if (m_pcCfg->getUseASR() && pcSlice->getSliceType()!=I_SLICE)
2363    {
2364      m_pcSliceEncoder->setSearchRange(pcSlice);
2365    }
2366
2367    Bool bGPBcheck=false;
2368    if ( pcSlice->getSliceType() == B_SLICE)
2369    {
2370      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
2371      {
2372        bGPBcheck=true;
2373        Int i;
2374        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
2375        {
2376          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) )
2377          {
2378            bGPBcheck=false;
2379            break;
2380          }
2381        }
2382      }
2383    }
2384    if(bGPBcheck)
2385    {
2386      pcSlice->setMvdL1ZeroFlag(true);
2387    }
2388    else
2389    {
2390      pcSlice->setMvdL1ZeroFlag(false);
2391    }
2392    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
2393
2394
2395    Double lambda            = 0.0;
2396    Int actualHeadBits       = 0;
2397    Int actualTotalBits      = 0;
2398    Int estimatedBits        = 0;
2399    Int tmpBitsBeforeWriting = 0;
2400    if ( m_pcCfg->getUseRateCtrl() ) // TODO: does this work with multiple slices and slice-segments?
2401    {
2402      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
2403      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
2404      {
2405        frameLevel = 0;
2406      }
2407      m_pcRateCtrl->initRCPic( frameLevel );
2408      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
2409
2410      Int sliceQP = m_pcCfg->getInitialQP();
2411#if SVC_EXTENSION
2412      if ( ( pocCurr == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
2413#else
2414      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
2415#endif
2416      {
2417        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
2418        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
2419        Double dQPFactor     = 0.57*dLambda_scale;
2420        Int    SHIFT_QP      = 12;
2421        Int    bitdepth_luma_qp_scale = 0;
2422        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
2423        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
2424      }
2425      else if ( frameLevel == 0 )   // intra case, but use the model
2426      {
2427        m_pcSliceEncoder->calCostSliceI(pcPic); // TODO: This only analyses the first slice segment - what about the others?
2428
2429        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
2430        {
2431          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
2432          bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
2433          if ( bits < 200 )
2434          {
2435            bits = 200;
2436          }
2437          m_pcRateCtrl->getRCPic()->setTargetBits( bits );
2438        }
2439
2440        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
2441        m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();
2442        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
2443        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
2444      }
2445      else    // normal case
2446      {
2447        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
2448        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
2449        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
2450      }
2451
2452#if SVC_EXTENSION
2453      sliceQP = Clip3( -pcSlice->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, sliceQP );
2454#else
2455      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, sliceQP );
2456#endif
2457      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
2458
2459      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
2460    }
2461
2462    UInt uiNumSliceSegments = 1;
2463
2464#if AVC_BASE
2465    if( m_layerId == 0 && m_pcEncTop->getVPS()->getNonHEVCBaseLayerFlag() )
2466    {
2467      pcPic->getPicYuvOrg()->copyToPic( pcPic->getPicYuvRec() );
2468
2469      // Calculate for the base layer to be used in EL as Inter layer reference
2470      if( m_pcEncTop->getInterLayerWeightedPredFlag() )
2471      {
2472        m_pcSliceEncoder->estimateILWpParam( pcSlice );
2473      }
2474
2475      return;
2476    }
2477#endif
2478
2479    // Allocate some coders, now the number of tiles are known.
2480    const Int numSubstreamsColumns = (pcSlice->getPPS()->getNumTileColumnsMinus1() + 1);
2481    const Int numSubstreamRows     = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->getFrameHeightInCtus() : (pcSlice->getPPS()->getNumTileRowsMinus1() + 1);
2482    const Int numSubstreams        = numSubstreamRows * numSubstreamsColumns;
2483    std::vector<TComOutputBitstream> substreamsOut(numSubstreams);
2484
2485    // now compress (trial encode) the various slice segments (slices, and dependent slices)
2486    {
2487      const UInt numberOfCtusInFrame=pcPic->getPicSym()->getNumberOfCtusInFrame();
2488      pcSlice->setSliceCurStartCtuTsAddr( 0 );
2489      pcSlice->setSliceSegmentCurStartCtuTsAddr( 0 );
2490
2491      for(UInt nextCtuTsAddr = 0; nextCtuTsAddr < numberOfCtusInFrame; )
2492      {
2493        m_pcSliceEncoder->precompressSlice( pcPic );
2494        m_pcSliceEncoder->compressSlice   ( pcPic, false, false );
2495
2496        const UInt curSliceSegmentEnd = pcSlice->getSliceSegmentCurEndCtuTsAddr();
2497        if (curSliceSegmentEnd < numberOfCtusInFrame)
2498        {
2499          const Bool bNextSegmentIsDependentSlice=curSliceSegmentEnd<pcSlice->getSliceCurEndCtuTsAddr();
2500          const UInt sliceBits=pcSlice->getSliceBits();
2501          pcPic->allocateNewSlice();
2502          // prepare for next slice
2503          pcPic->setCurrSliceIdx                    ( uiNumSliceSegments );
2504          m_pcSliceEncoder->setSliceIdx             ( uiNumSliceSegments   );
2505          pcSlice = pcPic->getSlice                 ( uiNumSliceSegments   );
2506          assert(pcSlice->getPPS()!=0);
2507          pcSlice->copySliceInfo                    ( pcPic->getSlice(uiNumSliceSegments-1)  );
2508          pcSlice->setSliceIdx                      ( uiNumSliceSegments   );
2509          if (bNextSegmentIsDependentSlice)
2510          {
2511            pcSlice->setSliceBits(sliceBits);
2512          }
2513          else
2514          {
2515            pcSlice->setSliceCurStartCtuTsAddr      ( curSliceSegmentEnd );
2516            pcSlice->setSliceBits(0);
2517          }
2518          pcSlice->setDependentSliceSegmentFlag(bNextSegmentIsDependentSlice);
2519          pcSlice->setSliceSegmentCurStartCtuTsAddr ( curSliceSegmentEnd );
2520          // TODO: optimise cabac_init during compress slice to improve multi-slice operation
2521          // pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
2522          uiNumSliceSegments ++;
2523        }
2524        nextCtuTsAddr = curSliceSegmentEnd;
2525      }
2526    }
2527
2528#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
2529    if (m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled())
2530    {
2531      xBuildTileSetsMap(pcPic->getPicSym());
2532    }
2533#endif
2534
2535    duData.clear();
2536    pcSlice = pcPic->getSlice(0);
2537
2538    // SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
2539    if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoCtuBoundary() )
2540    {
2541      m_pcSAO->getPreDBFStatistics(pcPic);
2542    }
2543
2544    //-- Loop filter
2545    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
2546    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
2547    if ( m_pcCfg->getDeblockingFilterMetric() )
2548    {
2549      applyDeblockingFilterMetric(pcPic, uiNumSliceSegments);
2550    }
2551    m_pcLoopFilter->loopFilterPic( pcPic );
2552
2553    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
2554    // Set entropy coder
2555    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
2556
2557    if ( m_bSeqFirst )
2558    {
2559      // write various parameter sets
2560      actualTotalBits += xWriteParameterSets(accessUnit, pcSlice);
2561
2562      // create prefix SEI messages at the beginning of the sequence
2563      assert(leadingSeiMessages.empty());
2564      xCreateIRAPLeadingSEIMessages(leadingSeiMessages, pcSlice->getSPS(), pcSlice->getPPS());
2565
2566      m_bSeqFirst = false;
2567    }
2568#if SVC_EXTENSION && CGS_3D_ASYMLUT
2569    else if( m_pcCfg->getCGSFlag() && pcSlice->getLayerId() && pcSlice->getCGSOverWritePPS() )
2570    {
2571      OutputNALUnit nalu(NAL_UNIT_PPS, 0, m_layerId);
2572      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2573      m_pcEntropyCoder->encodePPS(pcSlice->getPPS() , &m_Enc3DAsymLUTPPS );
2574      accessUnit.push_back(new NALUnitEBSP(nalu));
2575    }
2576#endif
2577
2578    // reset presence of BP SEI indication
2579    m_bufferingPeriodSEIPresentInAU = false;
2580    // create prefix SEI associated with a picture
2581    xCreatePerPictureSEIMessages(iGOPid, leadingSeiMessages, nestedSeiMessages, pcSlice);
2582
2583    /* use the main bitstream buffer for storing the marshalled picture */
2584    m_pcEntropyCoder->setBitstream(NULL);
2585
2586    pcSlice = pcPic->getSlice(0);
2587
2588
2589#if HIGHER_LAYER_IRAP_SKIP_FLAG
2590    if ( pcSlice->getSPS()->getUseSAO() && !( m_pcEncTop->getSkipPictureAtArcSwitch() && m_pcEncTop->getAdaptiveResolutionChange() > 0 && pcSlice->getLayerId() == 1 && pcSlice->getPOC() == m_pcEncTop->getAdaptiveResolutionChange()) )
2591#else
2592    if (pcSlice->getSPS()->getUseSAO())
2593#endif
2594    {
2595      Bool sliceEnabled[MAX_NUM_COMPONENT];
2596      TComBitCounter tempBitCounter;
2597      tempBitCounter.resetBits();
2598      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(&tempBitCounter);
2599      m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
2600      m_pcSAO->SAOProcess(pcPic, sliceEnabled, pcPic->getSlice(0)->getLambdas(), m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary());
2601      m_pcSAO->PCMLFDisableProcess(pcPic);
2602      m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(NULL);
2603
2604      //assign SAO slice header
2605      for(Int s=0; s< uiNumSliceSegments; s++)
2606      {
2607        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_LUMA, sliceEnabled[COMPONENT_Y]);
2608        assert(sliceEnabled[COMPONENT_Cb] == sliceEnabled[COMPONENT_Cr]);
2609        pcPic->getSlice(s)->setSaoEnabledFlag(CHANNEL_TYPE_CHROMA, sliceEnabled[COMPONENT_Cb]);
2610      }
2611    }
2612
2613    // pcSlice is currently slice 0.
2614    std::size_t binCountsInNalUnits   = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
2615    std::size_t numBytesInVclNalUnits = 0; // For implementation of cabac_zero_word stuffing (section 7.4.3.10)
2616
2617    for( UInt sliceSegmentStartCtuTsAddr = 0, sliceIdxCount=0; sliceSegmentStartCtuTsAddr < pcPic->getPicSym()->getNumberOfCtusInFrame(); sliceIdxCount++, sliceSegmentStartCtuTsAddr=pcSlice->getSliceSegmentCurEndCtuTsAddr() )
2618    {
2619      pcSlice = pcPic->getSlice(sliceIdxCount);
2620      if(sliceIdxCount > 0 && pcSlice->getSliceType()!= I_SLICE)
2621      {
2622        pcSlice->checkColRefIdx(sliceIdxCount, pcPic);
2623      }
2624      pcPic->setCurrSliceIdx(sliceIdxCount);
2625      m_pcSliceEncoder->setSliceIdx(sliceIdxCount);
2626
2627      pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
2628      pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
2629
2630      for ( UInt ui = 0 ; ui < numSubstreams; ui++ )
2631      {
2632        substreamsOut[ui].clear();
2633      }
2634
2635      m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
2636      m_pcEntropyCoder->resetEntropy      ( pcSlice );
2637      /* start slice NALunit */
2638#if SVC_EXTENSION
2639      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId );
2640#else
2641      OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
2642#endif
2643      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2644
2645#if SVC_EXTENSION
2646      if( pcSlice->isIRAP() )
2647      {
2648        //the inference for NoOutputPriorPicsFlag
2649        // KJS: This cannot happen at the encoder
2650        if (!m_bFirst && pcSlice->isIRAP() && m_noRaslOutputFlag)
2651        {
2652          if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
2653          {
2654            pcSlice->setNoOutputPriorPicsFlag(true);
2655          }
2656        }
2657      }
2658#else
2659      pcSlice->setNoRaslOutputFlag(false);
2660      if (pcSlice->isIRAP())
2661      {
2662        if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
2663        {
2664          pcSlice->setNoRaslOutputFlag(true);
2665        }
2666        //the inference for NoOutputPriorPicsFlag
2667        // KJS: This cannot happen at the encoder
2668        if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
2669        {
2670          if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
2671          {
2672            pcSlice->setNoOutputPriorPicsFlag(true);
2673          }
2674        }
2675      }
2676#endif
2677
2678      pcSlice->setEncCABACTableIdx(m_pcSliceEncoder->getEncCABACTableIdx());
2679
2680      tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2681      m_pcEntropyCoder->encodeSliceHeader(pcSlice);
2682      actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2683
2684      pcSlice->setFinalized(true);
2685
2686      pcSlice->clearSubstreamSizes(  );
2687      {
2688        UInt numBinsCoded = 0;
2689        m_pcSliceEncoder->encodeSlice(pcPic, &(substreamsOut[0]), numBinsCoded);
2690        binCountsInNalUnits+=numBinsCoded;
2691      }
2692
2693      {
2694        // Construct the final bitstream by concatenating substreams.
2695        // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
2696        // Complete the slice header info.
2697        m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder );
2698        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2699#if SVC_EXTENSION
2700        tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2701        m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2702        actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2703        m_pcEntropyCoder->encodeSliceHeaderExtn( pcSlice, actualHeadBits );
2704#else
2705        m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2706#endif
2707
2708        // Append substreams...
2709        TComOutputBitstream *pcOut = pcBitstreamRedirect;
2710        const Int numZeroSubstreamsAtStartOfSlice  = pcPic->getSubstreamForCtuAddr(pcSlice->getSliceSegmentCurStartCtuTsAddr(), false, pcSlice);
2711        const Int numSubstreamsToCode  = pcSlice->getNumberOfSubstreamSizes()+1;
2712        for ( UInt ui = 0 ; ui < numSubstreamsToCode; ui++ )
2713        {
2714          pcOut->addSubstream(&(substreamsOut[ui+numZeroSubstreamsAtStartOfSlice]));
2715        }
2716      }
2717
2718      // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
2719      // 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.
2720      Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
2721      xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
2722      accessUnit.push_back(new NALUnitEBSP(nalu));
2723      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2724      numBytesInVclNalUnits += (std::size_t)(accessUnit.back()->m_nalUnitData.str().size());
2725      bNALUAlignedWrittenToList = true;
2726
2727      if (!bNALUAlignedWrittenToList)
2728      {
2729        nalu.m_Bitstream.writeAlignZero();
2730        accessUnit.push_back(new NALUnitEBSP(nalu));
2731      }
2732
2733      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2734          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2735          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() )
2736         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
2737          ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
2738      {
2739          UInt numNalus = 0;
2740        UInt numRBSPBytes = 0;
2741        for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2742        {
2743          numRBSPBytes += UInt((*it)->m_nalUnitData.str().size());
2744          numNalus ++;
2745        }
2746        duData.push_back(DUData());
2747        duData.back().accumBitsDU = ( numRBSPBytes << 3 );
2748        duData.back().accumNalsDU = numNalus;
2749      }
2750    } // end iteration over slices
2751
2752    // cabac_zero_words processing
2753    cabac_zero_word_padding(pcSlice, pcPic, binCountsInNalUnits, numBytesInVclNalUnits, accessUnit.back()->m_nalUnitData, m_pcCfg->getCabacZeroWordPaddingEnabled());
2754
2755    pcPic->compressMotion();
2756
2757    //-- For time output for each slice
2758    Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
2759
2760    std::string digestStr;
2761    if (m_pcCfg->getDecodedPictureHashSEIEnabled())
2762    {
2763      SEIDecodedPictureHash *decodedPictureHashSei = new SEIDecodedPictureHash();
2764#if SVC_EXTENSION
2765      m_seiEncoder.initDecodedPictureHashSEI(decodedPictureHashSei, pcPic, digestStr, pcSlice->getBitDepths());
2766#else
2767      m_seiEncoder.initDecodedPictureHashSEI(decodedPictureHashSei, pcPic, digestStr, pcSlice->getSPS()->getBitDepths());
2768#endif
2769      trailingSeiMessages.push_back(decodedPictureHashSei);
2770    }
2771
2772#if O0164_MULTI_LAYER_HRD
2773    xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getVPS(), pcSlice->getSPS());
2774#else
2775    xWriteTrailingSEIMessages(trailingSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS());
2776#endif
2777
2778    m_pcCfg->setEncodedFlag(iGOPid, true);
2779
2780    xCalculateAddPSNRs( isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, dEncTime, snr_conversion, printFrameMSE );
2781
2782    if (!digestStr.empty())
2783    {
2784      if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2785      {
2786        printf(" [MD5:%s]", digestStr.c_str());
2787      }
2788      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2789      {
2790        printf(" [CRC:%s]", digestStr.c_str());
2791      }
2792      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2793      {
2794        printf(" [Checksum:%s]", digestStr.c_str());
2795      }
2796    }
2797
2798    if ( m_pcCfg->getUseRateCtrl() )
2799    {
2800      Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
2801      Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
2802      if ( avgLambda < 0.0 )
2803      {
2804        avgLambda = lambda;
2805      }
2806
2807      m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
2808      m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
2809
2810      m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
2811      if ( pcSlice->getSliceType() != I_SLICE )
2812      {
2813        m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
2814      }
2815      else    // for intra picture, the estimated bits are used to update the current status in the GOP
2816      {
2817        m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
2818      }
2819    }
2820
2821    xCreatePictureTimingSEI(m_pcCfg->getEfficientFieldIRAPEnabled()?effFieldIRAPMap.GetIRAPGOPid():0, leadingSeiMessages, nestedSeiMessages, duInfoSeiMessages, pcSlice, isField, duData);
2822    if (m_pcCfg->getScalableNestingSEIEnabled())
2823    {
2824      xCreateScalableNestingSEI (leadingSeiMessages, nestedSeiMessages);
2825    }
2826#if O0164_MULTI_LAYER_HRD
2827    xWriteLeadingSEIMessages(leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getVPS(), pcSlice->getSPS(), duData);
2828    xWriteDuSEIMessages(duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getVPS(), pcSlice->getSPS(), duData);
2829#else
2830    xWriteLeadingSEIMessages(leadingSeiMessages, duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);
2831    xWriteDuSEIMessages(duInfoSeiMessages, accessUnit, pcSlice->getTLayer(), pcSlice->getSPS(), duData);
2832#endif
2833
2834#if SVC_EXTENSION
2835    m_prevPicHasEos = false;
2836    if (m_pcCfg->getLayerSwitchOffBegin() < m_pcCfg->getLayerSwitchOffEnd())
2837    {
2838      Int pocNext;
2839      if (iGOPid == m_iGopSize - 1)
2840      {
2841        pocNext = iPOCLast - iNumPicRcvd + m_iGopSize + m_pcCfg->getGOPEntry(0).m_POC;
2842      }
2843      else
2844      {
2845        pocNext = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid + 1).m_POC;
2846      }
2847
2848      if (pocNext > m_pcCfg->getLayerSwitchOffBegin() && pocCurr < m_pcCfg->getLayerSwitchOffEnd())
2849      {
2850        OutputNALUnit nalu(NAL_UNIT_EOS, 0, pcSlice->getLayerId());
2851        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder);
2852        accessUnit.push_back(new NALUnitEBSP(nalu));
2853        m_prevPicHasEos = true;
2854      }
2855    }
2856#endif
2857
2858    pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
2859
2860#if SVC_EXTENSION
2861    pcPicYuvRecOut->setReconstructed(true);
2862    m_pcEncTop->setFirstPicInLayerDecodedFlag(true);
2863#endif
2864
2865    pcPic->setReconMark   ( true );
2866    m_bFirst = false;
2867    m_iNumPicCoded++;
2868    m_totalCoded ++;
2869    /* logging: insert a newline at end of picture period */
2870    printf("\n");
2871    fflush(stdout);
2872
2873    if (m_pcCfg->getEfficientFieldIRAPEnabled())
2874    {
2875      iGOPid=effFieldIRAPMap.restoreGOPid(iGOPid);
2876    }
2877  } // iGOPid-loop
2878
2879  delete pcBitstreamRedirect;
2880
2881#if SVC_EXTENSION
2882  assert ( m_iNumPicCoded <= 1 );
2883#else
2884  assert ( (m_iNumPicCoded == iNumPicRcvd) );
2885#endif
2886}
2887
2888Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths)
2889{
2890  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
2891
2892
2893  //--CFG_KDY
2894  const Int rateMultiplier=(isField?2:1);
2895  m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2896  m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2897  m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2898  m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate()*rateMultiplier );
2899  const ChromaFormat chFmt = m_pcCfg->getChromaFormatIdc();
2900
2901  //-- all
2902  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
2903  m_gcAnalyzeAll.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2904
2905  printf( "\n\nI Slices--------------------------------------------------------\n" );
2906  m_gcAnalyzeI.printOut('i', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2907
2908  printf( "\n\nP Slices--------------------------------------------------------\n" );
2909  m_gcAnalyzeP.printOut('p', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2910
2911  printf( "\n\nB Slices--------------------------------------------------------\n" );
2912  m_gcAnalyzeB.printOut('b', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2913
2914  if (!m_pcCfg->getSummaryOutFilename().empty())
2915  {
2916    m_gcAnalyzeAll.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());
2917  }
2918
2919  if (!m_pcCfg->getSummaryPicFilenameBase().empty())
2920  {
2921    m_gcAnalyzeI.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"I.txt");
2922    m_gcAnalyzeP.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"P.txt");
2923    m_gcAnalyzeB.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryPicFilenameBase()+"B.txt");
2924  }
2925
2926  if(isField)
2927  {
2928    //-- interlaced summary
2929    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
2930    m_gcAnalyzeAll_in.setBits(m_gcAnalyzeAll.getBits());
2931    // prior to the above statement, the interlace analyser does not contain the correct total number of bits.
2932
2933    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
2934    m_gcAnalyzeAll_in.printOut('a', chFmt, printMSEBasedSNR, printSequenceMSE, bitDepths);
2935
2936    if (!m_pcCfg->getSummaryOutFilename().empty())
2937    {
2938      m_gcAnalyzeAll_in.printSummary(chFmt, printSequenceMSE, bitDepths, m_pcCfg->getSummaryOutFilename());
2939    }
2940  }
2941
2942  printf("\nRVM: %.3lf\n" , xCalculateRVM());
2943}
2944
2945Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist )
2946{
2947  Bool bCalcDist = false;
2948  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
2949  m_pcLoopFilter->loopFilterPic( pcPic );
2950
2951  if (!bCalcDist)
2952  {
2953#if SVC_EXTENSION
2954    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getSlice(0)->getBitDepths());
2955#else
2956    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec(), pcPic->getPicSym()->getSPS().getBitDepths());
2957#endif
2958  }
2959}
2960
2961// ====================================================================================================================
2962// Protected member functions
2963// ====================================================================================================================
2964
2965
2966Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, Bool isField )
2967{
2968  assert( iNumPicRcvd > 0 );
2969  //  Exception for the first frames
2970  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
2971  {
2972    m_iGopSize    = 1;
2973  }
2974  else
2975  {
2976    m_iGopSize    = m_pcCfg->getGOPSize();
2977  }
2978  assert (m_iGopSize > 0);
2979
2980  return;
2981}
2982
2983
2984Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
2985                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
2986                         Int                       iNumPicRcvd,
2987                         Int                       iTimeOffset,
2988                         TComPic*&                 rpcPic,
2989                         TComPicYuv*&              rpcPicYuvRecOut,
2990                         Int                       pocCurr,
2991                         Bool                      isField)
2992{
2993  Int i;
2994  //  Rec. output
2995  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
2996
2997  if (isField && pocCurr > 1 && m_iGopSize!=1)
2998  {
2999    iTimeOffset--;
3000  }
3001
3002  for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
3003  {
3004    iterPicYuvRec--;
3005  }
3006
3007  rpcPicYuvRecOut = *(iterPicYuvRec);
3008
3009  //  Current pic.
3010  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
3011  while (iterPic != rcListPic.end())
3012  {
3013    rpcPic = *(iterPic);
3014    rpcPic->setCurrSliceIdx(0);
3015    if (rpcPic->getPOC() == pocCurr)
3016    {
3017      break;
3018    }
3019    iterPic++;
3020  }
3021
3022  assert (rpcPic != NULL);
3023  assert (rpcPic->getPOC() == pocCurr);
3024
3025  return;
3026}
3027
3028UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1, const BitDepths &bitDepths)
3029{
3030  UInt64  uiTotalDiff = 0;
3031
3032  for(Int chan=0; chan<pcPic0 ->getNumberValidComponents(); chan++)
3033  {
3034    const ComponentID ch=ComponentID(chan);
3035    Pel*  pSrc0   = pcPic0 ->getAddr(ch);
3036    Pel*  pSrc1   = pcPic1 ->getAddr(ch);
3037    UInt  uiShift     = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepths.recon[toChannelType(ch)]-8);
3038
3039    const Int   iStride = pcPic0->getStride(ch);
3040    const Int   iWidth  = pcPic0->getWidth(ch);
3041    const Int   iHeight = pcPic0->getHeight(ch);
3042
3043    for(Int y = 0; y < iHeight; y++ )
3044    {
3045      for(Int x = 0; x < iWidth; x++ )
3046      {
3047        Intermediate_Int iTemp = pSrc0[x] - pSrc1[x];
3048        uiTotalDiff += UInt64((iTemp*iTemp) >> uiShift);
3049      }
3050      pSrc0 += iStride;
3051      pSrc1 += iStride;
3052    }
3053  }
3054
3055  return uiTotalDiff;
3056}
3057
3058Void 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 )
3059{
3060  xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime, snr_conversion, printFrameMSE );
3061
3062  //In case of field coding, compute the interlaced PSNR for both fields
3063  if(isField)
3064  {
3065    Bool bothFieldsAreEncoded = false;
3066    Int correspondingFieldPOC = pcPic->getPOC();
3067    Int currentPicGOPPoc = m_pcCfg->getGOPEntry(iGOPid).m_POC;
3068    if(pcPic->getPOC() == 0)
3069    {
3070      // particular case for POC 0 and 1.
3071      // If they are not encoded first and separately from other pictures, we need to change this
3072      // POC 0 is always encoded first then POC 1 is encoded
3073      bothFieldsAreEncoded = false;
3074    }
3075    else if(pcPic->getPOC() == 1)
3076    {
3077      // if we are at POC 1, POC 0 has been encoded for sure
3078      correspondingFieldPOC = 0;
3079      bothFieldsAreEncoded = true;
3080    }
3081    else
3082    {
3083      if(pcPic->getPOC()%2 == 1)
3084      {
3085        correspondingFieldPOC -= 1; // all odd POC are associated with the preceding even POC (e.g poc 1 is associated to poc 0)
3086        currentPicGOPPoc      -= 1;
3087      }
3088      else
3089      {
3090        correspondingFieldPOC += 1; // all even POC are associated with the following odd POC (e.g poc 0 is associated to poc 1)
3091        currentPicGOPPoc      += 1;
3092      }
3093      for(Int i = 0; i < m_iGopSize; i ++)
3094      {
3095        if(m_pcCfg->getGOPEntry(i).m_POC == currentPicGOPPoc)
3096        {
3097          bothFieldsAreEncoded = m_pcCfg->getGOPEntry(i).m_isEncoded;
3098          break;
3099        }
3100      }
3101    }
3102
3103    if(bothFieldsAreEncoded)
3104    {
3105      //get complementary top field
3106      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
3107      while ((*iterPic)->getPOC() != correspondingFieldPOC)
3108      {
3109        iterPic ++;
3110      }
3111      TComPic* correspondingFieldPic = *(iterPic);
3112
3113      if( (pcPic->isTopField() && isFieldTopFieldFirst) || (!pcPic->isTopField() && !isFieldTopFieldFirst))
3114      {
3115        xCalculateInterlacedAddPSNR(pcPic, correspondingFieldPic, pcPic->getPicYuvRec(), correspondingFieldPic->getPicYuvRec(), snr_conversion, printFrameMSE );
3116      }
3117      else
3118      {
3119        xCalculateInterlacedAddPSNR(correspondingFieldPic, pcPic, correspondingFieldPic->getPicYuvRec(), pcPic->getPicYuvRec(), snr_conversion, printFrameMSE );
3120      }
3121    }
3122  }
3123}
3124
3125Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime, const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3126{
3127  Double  dPSNR[MAX_NUM_COMPONENT];
3128
3129  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3130  {
3131    dPSNR[i]=0.0;
3132  }
3133
3134  TComPicYuv cscd;
3135  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3136  {
3137    cscd.create(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat(), pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), 0, false);
3138    TVideoIOYuv::ColourSpaceConvert(*pcPicD, cscd, conversion, false);
3139  }
3140  TComPicYuv &picd=(conversion==IPCOLOURSPACE_UNCHANGED)?*pcPicD : cscd;
3141
3142  //===== calculate PSNR =====
3143  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3144
3145  for(Int chan=0; chan<pcPicD->getNumberValidComponents(); chan++)
3146  {
3147    const ComponentID ch=ComponentID(chan);
3148    const TComPicYuv *pOrgPicYuv =(conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg() : pcPic ->getPicYuvOrg();
3149    const Pel*  pOrg       = pOrgPicYuv->getAddr(ch);
3150    const Int   iOrgStride = pOrgPicYuv->getStride(ch);
3151    Pel*  pRec             = picd.getAddr(ch);
3152    const Int   iRecStride = picd.getStride(ch);
3153    const Int   iWidth  = pcPicD->getWidth (ch) - (m_pcEncTop->getPad(0) >> pcPic->getComponentScaleX(ch));
3154    const Int   iHeight = pcPicD->getHeight(ch) - ((m_pcEncTop->getPad(1) >> (pcPic->isField()?1:0)) >> pcPic->getComponentScaleY(ch));
3155
3156    Int   iSize   = iWidth*iHeight;
3157
3158    UInt64 uiSSDtemp=0;
3159    for(Int y = 0; y < iHeight; y++ )
3160    {
3161      for(Int x = 0; x < iWidth; x++ )
3162      {
3163        Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3164        uiSSDtemp   += iDiff * iDiff;
3165      }
3166      pOrg += iOrgStride;
3167      pRec += iRecStride;
3168    }
3169#if SVC_EXTENSION
3170    const Int maxval = 255 << (pcPic->getSlice(0)->getBitDepth(toChannelType(ch)) - 8);
3171#else
3172    const Int maxval = 255 << (pcPic->getPicSym()->getSPS().getBitDepth(toChannelType(ch)) - 8);
3173#endif
3174    const Double fRefValue = (Double) maxval * maxval * iSize;
3175    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3176    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize);
3177  }
3178
3179
3180  /* calculate the size of the access unit, excluding:
3181   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3182   *  - SEI NAL units
3183   */
3184  UInt numRBSPBytes = 0;
3185  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3186  {
3187    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3188    if (m_pcCfg->getSummaryVerboseness() > 0)
3189    {
3190      printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
3191    }
3192    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3193    {
3194      numRBSPBytes += numRBSPBytes_nal;
3195    }
3196  }
3197
3198  UInt uibits = numRBSPBytes * 8;
3199  m_vRVM_RP.push_back( uibits );
3200
3201  //===== add PSNR =====
3202  m_gcAnalyzeAll.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3203  TComSlice*  pcSlice = pcPic->getSlice(0);
3204  if (pcSlice->isIntra())
3205  {
3206    m_gcAnalyzeI.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3207  }
3208  if (pcSlice->isInterP())
3209  {
3210    m_gcAnalyzeP.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3211  }
3212  if (pcSlice->isInterB())
3213  {
3214    m_gcAnalyzeB.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3215  }
3216
3217  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
3218  if (!pcSlice->isReferenced())
3219  {
3220    c += 32;
3221  }
3222
3223#if SVC_EXTENSION
3224#if ADAPTIVE_QP_SELECTION 
3225  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, nQP %d QP %d ) %10d bits",
3226         pcSlice->getPOC(),
3227         pcSlice->getLayerId(),
3228         pcSlice->getTLayer(),
3229         c,
3230         nalUnitTypeToString( pcSlice->getNalUnitType() ),
3231         pcSlice->getSliceQpBase(),
3232         pcSlice->getSliceQp(),
3233         uibits );
3234#else
3235  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP %d ) %10d bits",
3236         pcSlice->getPOC()-pcSlice->getLastIDR(),
3237         pcSlice->getLayerId(),
3238         pcSlice->getTLayer(),
3239         c,
3240         nalUnitTypeToString( pcSlice->getNalUnitType() ),
3241         pcSlice->getSliceQp(),
3242         uibits );
3243#endif
3244#else
3245#if ADAPTIVE_QP_SELECTION
3246  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3247         pcSlice->getPOC(),
3248         pcSlice->getTLayer(),
3249         c,
3250         pcSlice->getSliceQpBase(),
3251         pcSlice->getSliceQp(),
3252         uibits );
3253#else
3254  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3255         pcSlice->getPOC()-pcSlice->getLastIDR(),
3256         pcSlice->getTLayer(),
3257         c,
3258         pcSlice->getSliceQp(),
3259         uibits );
3260#endif
3261#endif
3262
3263  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dPSNR[COMPONENT_Y], dPSNR[COMPONENT_Cb], dPSNR[COMPONENT_Cr] );
3264  if (printFrameMSE)
3265  {
3266    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3267  }
3268  printf(" [ET %5.0f ]", dEncTime );
3269
3270  // printf(" [WP %d]", pcSlice->getUseWeightedPrediction());
3271
3272  for (Int iRefList = 0; iRefList < 2; iRefList++)
3273  {
3274    printf(" [L%d ", iRefList);
3275    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
3276    {
3277#if SVC_EXTENSION
3278      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) )
3279      {
3280        UInt refLayerId = pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId();
3281        UInt refLayerIdc = pcSlice->getReferenceLayerIdc(refLayerId);
3282        assert( g_posScalingFactor[refLayerIdc][0] );
3283        assert( g_posScalingFactor[refLayerIdc][1] );
3284
3285        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] );
3286      }
3287      else
3288      {
3289        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex));
3290      }
3291
3292      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
3293      {
3294        printf( "c" );
3295      }
3296
3297      printf( " " );
3298#else
3299      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3300#endif
3301    }
3302    printf("]");
3303  }
3304#if CGS_3D_ASYMLUT
3305  pcPic->setFrameBit( (Int)uibits );
3306  if( m_layerId && pcSlice->getPPS()->getCGSFlag() )
3307  {
3308#if R0179_ENC_OPT_3DLUT_SIZE
3309      m_Enc3DAsymLUTPicUpdate.update3DAsymLUTParam( &m_Enc3DAsymLUTPPS );
3310#else
3311    if( m_Enc3DAsymLUTPPS.getPPSBit() > 0 )
3312      m_Enc3DAsymLUTPicUpdate.copy3DAsymLUT( &m_Enc3DAsymLUTPPS );
3313#endif
3314    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
3315  }
3316#endif
3317
3318  cscd.destroy();
3319}
3320
3321Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgFirstField, TComPic* pcPicOrgSecondField,
3322                                           TComPicYuv* pcPicRecFirstField, TComPicYuv* pcPicRecSecondField,
3323                                           const InputColourSpaceConversion conversion, const Bool printFrameMSE )
3324{
3325#if !SVC_EXTENSION
3326  const TComSPS &sps=pcPicOrgFirstField->getPicSym()->getSPS();
3327#endif
3328  Double  dPSNR[MAX_NUM_COMPONENT];
3329  TComPic    *apcPicOrgFields[2]={pcPicOrgFirstField, pcPicOrgSecondField};
3330  TComPicYuv *apcPicRecFields[2]={pcPicRecFirstField, pcPicRecSecondField};
3331
3332  for(Int i=0; i<MAX_NUM_COMPONENT; i++)
3333  {
3334    dPSNR[i]=0.0;
3335  }
3336
3337  TComPicYuv cscd[2 /* first/second field */];
3338  if (conversion!=IPCOLOURSPACE_UNCHANGED)
3339  {
3340    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3341    {
3342      TComPicYuv &reconField=*(apcPicRecFields[fieldNum]);
3343      cscd[fieldNum].create(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat(), reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), 0, false);
3344      TVideoIOYuv::ColourSpaceConvert(reconField, cscd[fieldNum], conversion, false);
3345      apcPicRecFields[fieldNum]=cscd+fieldNum;
3346    }
3347  }
3348
3349  //===== calculate PSNR =====
3350  Double MSEyuvframe[MAX_NUM_COMPONENT] = {0, 0, 0};
3351
3352  assert(apcPicRecFields[0]->getChromaFormat()==apcPicRecFields[1]->getChromaFormat());
3353  const UInt numValidComponents=apcPicRecFields[0]->getNumberValidComponents();
3354
3355  for(Int chan=0; chan<numValidComponents; chan++)
3356  {
3357    const ComponentID ch=ComponentID(chan);
3358    assert(apcPicRecFields[0]->getWidth(ch)==apcPicRecFields[1]->getWidth(ch));
3359    assert(apcPicRecFields[0]->getHeight(ch)==apcPicRecFields[1]->getHeight(ch));
3360
3361    UInt64 uiSSDtemp=0;
3362    const Int   iWidth  = apcPicRecFields[0]->getWidth (ch) - (m_pcEncTop->getPad(0) >> apcPicRecFields[0]->getComponentScaleX(ch));
3363    const Int   iHeight = apcPicRecFields[0]->getHeight(ch) - ((m_pcEncTop->getPad(1) >> 1) >> apcPicRecFields[0]->getComponentScaleY(ch));
3364
3365    Int   iSize   = iWidth*iHeight;
3366
3367    for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3368    {
3369      TComPic *pcPic=apcPicOrgFields[fieldNum];
3370      TComPicYuv *pcPicD=apcPicRecFields[fieldNum];
3371
3372      const Pel*  pOrg    = (conversion!=IPCOLOURSPACE_UNCHANGED) ? pcPic ->getPicYuvTrueOrg()->getAddr(ch) : pcPic ->getPicYuvOrg()->getAddr(ch);
3373      Pel*  pRec    = pcPicD->getAddr(ch);
3374      const Int   iStride = pcPicD->getStride(ch);
3375
3376
3377      for(Int y = 0; y < iHeight; y++ )
3378      {
3379        for(Int x = 0; x < iWidth; x++ )
3380        {
3381          Intermediate_Int iDiff = (Intermediate_Int)( pOrg[x] - pRec[x] );
3382          uiSSDtemp   += iDiff * iDiff;
3383        }
3384        pOrg += iStride;
3385        pRec += iStride;
3386      }
3387    }
3388#if SVC_EXTENSION
3389    const Int maxval = 255 << (pcPicOrgFirstField->getSlice(0)->getBitDepth(toChannelType(ch)) - 8);
3390#else
3391    const Int maxval = 255 << (sps.getBitDepth(toChannelType(ch)) - 8);
3392#endif
3393    const Double fRefValue = (Double) maxval * maxval * iSize*2;
3394    dPSNR[ch]         = ( uiSSDtemp ? 10.0 * log10( fRefValue / (Double)uiSSDtemp ) : 999.99 );
3395    MSEyuvframe[ch]   = (Double)uiSSDtemp/(iSize*2);
3396  }
3397
3398  UInt uibits = 0; // the number of bits for the pair is not calculated here - instead the overall total is used elsewhere.
3399
3400  //===== add PSNR =====
3401  m_gcAnalyzeAll_in.addResult (dPSNR, (Double)uibits, MSEyuvframe);
3402
3403  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] );
3404  if (printFrameMSE)
3405  {
3406    printf(" [Y MSE %6.4lf  U MSE %6.4lf  V MSE %6.4lf]", MSEyuvframe[COMPONENT_Y], MSEyuvframe[COMPONENT_Cb], MSEyuvframe[COMPONENT_Cr] );
3407  }
3408
3409  for(UInt fieldNum=0; fieldNum<2; fieldNum++)
3410  {
3411    cscd[fieldNum].destroy();
3412  }
3413}
3414
3415/** Function for deciding the nal_unit_type.
3416 * \param pocCurr POC of the current picture
3417 * \param lastIDR  POC of the last IDR picture
3418 * \param isField  true to indicate field coding
3419 * \returns the NAL unit type of the picture
3420 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
3421 */
3422NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
3423{
3424  if (pocCurr == 0)
3425  {
3426    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3427  }
3428
3429  if(m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pocCurr == 1)
3430  {
3431    // to avoid the picture becoming an IRAP
3432    return NAL_UNIT_CODED_SLICE_TRAIL_R;
3433  }
3434
3435  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3436  {
3437    if (m_pcCfg->getDecodingRefreshType() == 1)
3438    {
3439      return NAL_UNIT_CODED_SLICE_CRA;
3440    }
3441    else if (m_pcCfg->getDecodingRefreshType() == 2)
3442    {
3443      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3444    }
3445  }
3446
3447#if SVC_POC
3448  if( m_pocCraWithoutReset > 0 && m_associatedIRAPType == NAL_UNIT_CODED_SLICE_CRA )
3449  {
3450    if(pocCurr < m_pocCraWithoutReset)
3451#else
3452  if(m_pocCRA>0)
3453  {
3454    if(pocCurr<m_pocCRA)
3455#endif
3456    {
3457      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3458      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3459      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3460      // controlling the reference pictures used for encoding that leading picture. Such a leading
3461      // picture need not be marked as a TFD picture.
3462      return NAL_UNIT_CODED_SLICE_RASL_R;
3463    }
3464  }
3465  if (lastIDR>0)
3466  {
3467    if (pocCurr < lastIDR)
3468    {
3469      return NAL_UNIT_CODED_SLICE_RADL_R;
3470    }
3471  }
3472  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3473}
3474
3475Double TEncGOP::xCalculateRVM()
3476{
3477  Double dRVM = 0;
3478
3479  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3480  {
3481    // calculate RVM only for lowdelay configurations
3482    std::vector<Double> vRL , vB;
3483    size_t N = m_vRVM_RP.size();
3484    vRL.resize( N );
3485    vB.resize( N );
3486
3487    Int i;
3488    Double dRavg = 0 , dBavg = 0;
3489    vB[RVM_VCEGAM10_M] = 0;
3490    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3491    {
3492      vRL[i] = 0;
3493      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
3494      {
3495        vRL[i] += m_vRVM_RP[j];
3496      }
3497      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
3498      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
3499      dRavg += m_vRVM_RP[i];
3500      dBavg += vB[i];
3501    }
3502
3503    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
3504    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
3505
3506    Double dSigamB = 0;
3507    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3508    {
3509      Double tmp = vB[i] - dBavg;
3510      dSigamB += tmp * tmp;
3511    }
3512    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
3513
3514    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
3515
3516    dRVM = dSigamB / dRavg * f;
3517  }
3518
3519  return( dRVM );
3520}
3521
3522/** Attaches the input bitstream to the stream in the output NAL unit
3523    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
3524 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
3525 *  \param rNalu          target NAL unit
3526 */
3527Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream* codedSliceData)
3528{
3529  // Byte-align
3530  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
3531
3532  // Perform bitstream concatenation
3533  if (codedSliceData->getNumberOfWrittenBits() > 0)
3534  {
3535    rNalu.m_Bitstream.addSubstream(codedSliceData);
3536  }
3537
3538  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
3539
3540  codedSliceData->clear();
3541}
3542
3543// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
3544// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
3545Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
3546{
3547  if(pcSlice->getRPS()->getNumberOfLongtermPictures() == 0)
3548  {
3549    return;
3550  }
3551  // we can only modify the local RPS!
3552  assert (pcSlice->getRPSidx()==-1);
3553  TComReferencePictureSet *rps = pcSlice->getLocalRPS();
3554
3555  // Arrange long-term reference pictures in the correct order of LSB and MSB,
3556  // and assign values for pocLSBLT and MSB present flag
3557  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
3558  Int longtermPicsMSB[MAX_NUM_REF_PICS];
3559  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
3560  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
3561  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
3562  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
3563  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
3564  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
3565
3566  // Get the long-term reference pictures
3567  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
3568  Int i, ctr = 0;
3569  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
3570  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3571  {
3572    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
3573    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
3574    indices[ctr]      = i;
3575    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
3576  }
3577  Int numLongPics = rps->getNumberOfLongtermPictures();
3578  assert(ctr == numLongPics);
3579
3580  // Arrange pictures in decreasing order of MSB;
3581  for(i = 0; i < numLongPics; i++)
3582  {
3583    for(Int j = 0; j < numLongPics - 1; j++)
3584    {
3585      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
3586      {
3587        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
3588        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
3589        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
3590        std::swap(indices[j]        , indices[j+1]        );
3591      }
3592    }
3593  }
3594
3595  for(i = 0; i < numLongPics; i++)
3596  {
3597    // Check if MSB present flag should be enabled.
3598    // Check if the buffer contains any pictures that have the same LSB.
3599    TComList<TComPic*>::iterator  iterPic = rcListPic.begin();
3600    TComPic*                      pcPic;
3601    while ( iterPic != rcListPic.end() )
3602    {
3603      pcPic = *iterPic;
3604      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
3605                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
3606                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
3607      {
3608        mSBPresentFlag[i] = true;
3609        break;
3610      }
3611      iterPic++;
3612    }
3613  }
3614
3615  // tempArray for usedByCurr flag
3616  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
3617  for(i = 0; i < numLongPics; i++)
3618  {
3619    tempArray[i] = rps->getUsed(indices[i]);
3620  }
3621  // Now write the final values;
3622  ctr = 0;
3623  Int currMSB = 0, currLSB = 0;
3624  // currPicPoc = currMSB + currLSB
3625  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB);
3626  currMSB = pcSlice->getPOC() - currLSB;
3627
3628  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
3629  {
3630    rps->setPOC                   (i, longtermPicsPoc[ctr]);
3631    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
3632    rps->setUsed                  (i, tempArray[ctr]);
3633    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
3634    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
3635    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);
3636
3637    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
3638  }
3639  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
3640  {
3641    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
3642    {
3643      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
3644      // don't have to check the MSB present flag values for this constraint.
3645      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
3646    }
3647  }
3648}
3649
3650Void TEncGOP::applyDeblockingFilterMetric( TComPic* pcPic, UInt uiNumSlices )
3651{
3652  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
3653  Pel* Rec    = pcPicYuvRec->getAddr(COMPONENT_Y);
3654  Pel* tempRec = Rec;
3655  Int  stride = pcPicYuvRec->getStride(COMPONENT_Y);
3656  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
3657  UInt maxTBsize = (1<<log2maxTB);
3658  const UInt minBlockArtSize = 8;
3659  const UInt picWidth = pcPicYuvRec->getWidth(COMPONENT_Y);
3660  const UInt picHeight = pcPicYuvRec->getHeight(COMPONENT_Y);
3661  const UInt noCol = (picWidth>>log2maxTB);
3662  const UInt noRows = (picHeight>>log2maxTB);
3663  assert(noCol > 1);
3664  assert(noRows > 1);
3665  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
3666  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
3667  UInt colIdx = 0;
3668  UInt rowIdx = 0;
3669  Pel p0, p1, p2, q0, q1, q2;
3670
3671  Int qp = pcPic->getSlice(0)->getSliceQp();
3672#if SVC_EXTENSION
3673  const Int bitDepthLuma=pcPic->getSlice(0)->getBitDepth(CHANNEL_TYPE_LUMA);
3674#else
3675  const Int bitDepthLuma=pcPic->getSlice(0)->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA);
3676#endif
3677  Int bitdepthScale = 1 << (bitDepthLuma-8);
3678  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
3679  const Int thr2 = (beta>>2);
3680  const Int thr1 = 2*bitdepthScale;
3681  UInt a = 0;
3682
3683  memset(colSAD, 0, noCol*sizeof(UInt64));
3684  memset(rowSAD, 0, noRows*sizeof(UInt64));
3685
3686  if (maxTBsize > minBlockArtSize)
3687  {
3688    // Analyze vertical artifact edges
3689    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
3690    {
3691      for(Int r = 0; r < picHeight; r++)
3692      {
3693        p2 = Rec[c-3];
3694        p1 = Rec[c-2];
3695        p0 = Rec[c-1];
3696        q0 = Rec[c];
3697        q1 = Rec[c+1];
3698        q2 = Rec[c+2];
3699        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3700        if ( thr1 < a && a < thr2)
3701        {
3702          colSAD[colIdx] += abs(p0 - q0);
3703        }
3704        Rec += stride;
3705      }
3706      colIdx++;
3707      Rec = tempRec;
3708    }
3709
3710    // Analyze horizontal artifact edges
3711    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
3712    {
3713      for(Int c = 0; c < picWidth; c++)
3714      {
3715        p2 = Rec[c + (r-3)*stride];
3716        p1 = Rec[c + (r-2)*stride];
3717        p0 = Rec[c + (r-1)*stride];
3718        q0 = Rec[c + r*stride];
3719        q1 = Rec[c + (r+1)*stride];
3720        q2 = Rec[c + (r+2)*stride];
3721        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
3722        if (thr1 < a && a < thr2)
3723        {
3724          rowSAD[rowIdx] += abs(p0 - q0);
3725        }
3726      }
3727      rowIdx++;
3728    }
3729  }
3730
3731  UInt64 colSADsum = 0;
3732  UInt64 rowSADsum = 0;
3733  for(Int c = 0; c < noCol-1; c++)
3734  {
3735    colSADsum += colSAD[c];
3736  }
3737  for(Int r = 0; r < noRows-1; r++)
3738  {
3739    rowSADsum += rowSAD[r];
3740  }
3741
3742  colSADsum <<= 10;
3743  rowSADsum <<= 10;
3744  colSADsum /= (noCol-1);
3745  colSADsum /= picHeight;
3746  rowSADsum /= (noRows-1);
3747  rowSADsum /= picWidth;
3748
3749  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
3750  avgSAD >>= (bitDepthLuma-8);
3751
3752  if ( avgSAD > 2048 )
3753  {
3754    avgSAD >>= 9;
3755    Int offset = Clip3(2,6,(Int)avgSAD);
3756    for (Int i=0; i<uiNumSlices; i++)
3757    {
3758      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
3759      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
3760      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
3761      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
3762    }
3763  }
3764  else
3765  {
3766    for (Int i=0; i<uiNumSlices; i++)
3767    {
3768      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
3769      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
3770      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
3771      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
3772    }
3773  }
3774
3775  free(colSAD);
3776  free(rowSAD);
3777}
3778
3779#if SVC_EXTENSION
3780#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
3781Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym)
3782{
3783  Int numCUs = picSym->getFrameWidthInCtus() * picSym->getFrameHeightInCtus();
3784
3785  for (Int i = 0; i < numCUs; i++)
3786  {
3787    picSym->setTileSetIdxMap(i, -1, 0, false);
3788  }
3789
3790  for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
3791  {
3792    const TComTile* topLeftTile     = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i));
3793    TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i));
3794    Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCtus() - topLeftTile->getTileWidthInCtus() + 1;
3795    Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCtus();
3796    Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCtus() - topLeftTile->getTileHeightInCtus() + 1;
3797    Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCtus();
3798    assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU);
3799    for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++)
3800    {
3801      for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++)
3802      {
3803        picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCtus() + k, i, m_pcCfg->getIlcIdc(i), false);
3804      }
3805    }
3806  }
3807 
3808  if (m_pcCfg->getSkippedTileSetPresentFlag())
3809  {
3810    Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage();
3811    for (Int i = 0; i < numCUs; i++)
3812    {
3813      if (picSym->getTileSetIdxMap(i) < 0)
3814      {
3815        picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true);
3816      }
3817    }
3818  }
3819}
3820#endif
3821
3822Void TEncGOP::determinePocResetIdc(Int const pocCurr, TComSlice *const slice)
3823{
3824  // If one picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 1 or 2
3825  // If BL picture in the AU is IDR, and another picture is not IDR, set the poc_reset_idc to 2
3826  // If BL picture is IRAP, and another picture is non-IRAP, then the poc_reset_idc is equal to 1 or 2.
3827  slice->setPocMsbNeeded(false);
3828
3829  if( slice->getSliceIdx() == 0 ) // First slice - compute, copy for other slices
3830  {
3831    Int needReset = false;
3832    Int resetDueToBL = false;
3833    if( slice->getVPS()->getMaxLayers() > 1 )
3834    {
3835      // If IRAP is refreshed in this access unit for base layer
3836      if( (m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 1 || m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2)
3837        && ( pocCurr % m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3838        )
3839      {
3840        // Check if the IRAP refresh interval of any layer does not match that of the base layer
3841        for(Int i = 1; i < slice->getVPS()->getMaxLayers(); i++)
3842        {
3843          Bool refreshIntervalFlag = ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 );
3844          Bool refreshTypeFlag     = ( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() );
3845          if( !(refreshIntervalFlag && refreshTypeFlag) )
3846          {
3847            needReset = true;
3848            resetDueToBL = true;
3849            break;
3850          }
3851        }
3852      }
3853    }
3854
3855    if( !needReset )// No need reset due to base layer IRAP
3856    {
3857      // Check if EL IDRs results in POC Reset
3858      for(Int i = 1; i < slice->getVPS()->getMaxLayers() && !needReset; i++)
3859      {
3860        Bool idrFlag = ( (m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshType() == 2) 
3861          && ( pocCurr % m_ppcTEncTop[i]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3862          );
3863        for(Int j = 0; j < slice->getVPS()->getMaxLayers(); j++)
3864        {
3865          if( j == i )
3866          {
3867            continue;
3868          }
3869
3870          Bool idrOtherPicFlag = ( (m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshType() == 2) 
3871            && ( pocCurr % m_ppcTEncTop[j]->getGOPEncoder()->getIntraRefreshInterval() == 0 )
3872            );
3873
3874          if( idrFlag != idrOtherPicFlag )
3875          {
3876            needReset = true;
3877            break;
3878          }
3879        }
3880      }
3881    }
3882    if( needReset )
3883    {
3884      if( m_ppcTEncTop[0]->getGOPEncoder()->getIntraRefreshType() == 2 )  // BL IDR refresh, assuming BL picture present
3885      {
3886        if( resetDueToBL )
3887        {
3888          slice->setPocResetIdc( 2 ); // Full reset needed
3889
3890          if( slice->getVPS()->getVpsPocLsbAlignedFlag() && slice->getVPS()->getNumDirectRefLayers(slice->getLayerId()) == 0 )
3891          {
3892            slice->setPocMsbNeeded(true);  // Force msb writing
3893          }
3894        }
3895        else
3896        {
3897          slice->setPocResetIdc( 1 ); // Due to IDR in EL
3898        }
3899      }
3900      else
3901      {
3902        slice->setPocResetIdc( 1 ); // Only MSB reset
3903      }
3904
3905      // Start a new POC reset period
3906      if (m_layerId == 0)   // Assuming BL picture is always present at encoder; for other AU structures, need to change this
3907      {
3908        Int periodId = rand() % 64;
3909        m_lastPocPeriodId = (periodId == m_lastPocPeriodId) ? (periodId + 1) % 64 : periodId ;
3910
3911        for( UInt i = 0; i < MAX_LAYERS; i++ )
3912        {
3913          m_ppcTEncTop[i]->setPocDecrementedInDPBFlag(false);
3914        }
3915      }
3916      else
3917      {
3918        m_lastPocPeriodId = m_ppcTEncTop[0]->getGOPEncoder()->getLastPocPeriodId();
3919      }
3920      slice->setPocResetPeriodId(m_lastPocPeriodId);
3921    }
3922    else
3923    {
3924      slice->setPocResetIdc( 0 );
3925    }
3926  }
3927}
3928
3929Void TEncGOP::updatePocValuesOfPics(Int const pocCurr, TComSlice *const slice)
3930{
3931  UInt affectedLayerList[MAX_NUM_LAYER_IDS];
3932  Int  numAffectedLayers;
3933
3934  affectedLayerList[0] = m_layerId;
3935  numAffectedLayers = 1;
3936
3937  if (m_pcEncTop->getVPS()->getVpsPocLsbAlignedFlag())
3938  {
3939    for (UInt j = 0; j < m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId); j++)
3940    {
3941      affectedLayerList[j + 1] = m_pcEncTop->getVPS()->getPredictedLayerId(m_layerId, j);
3942    }
3943    numAffectedLayers = m_pcEncTop->getVPS()->getNumPredictedLayers(m_layerId) + 1;
3944  }
3945
3946  Int pocAdjustValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
3947
3948  // New POC reset period
3949  Int maxPocLsb, pocLsbVal, pocMsbDelta, pocLsbDelta, deltaPocVal;
3950
3951  maxPocLsb   = 1 << slice->getSPS()->getBitsForPOC();
3952
3953  Int adjustedPocValue = pocCurr;
3954
3955  if (m_pcEncTop->getFirstPicInLayerDecodedFlag())
3956  {
3957    pocLsbVal   = (slice->getPocResetIdc() == 3)
3958      ? slice->getPocLsbVal()
3959      : pocAdjustValue % maxPocLsb; 
3960    pocMsbDelta = pocAdjustValue - pocLsbVal;
3961    pocLsbDelta = (slice->getPocResetIdc() == 2 || ( slice->getPocResetIdc() == 3 && slice->getFullPocResetFlag() )) 
3962      ? pocLsbVal 
3963      : 0; 
3964    deltaPocVal = pocMsbDelta  + pocLsbDelta;
3965
3966    Int origDeltaPocVal = deltaPocVal;  // original value needed when updating POC adjustment value
3967
3968    // IDR picture in base layer, non-IDR picture in other layers, poc_lsb_aligned_flag = 1
3969    if( slice->getPocMsbNeeded() )
3970    {
3971      if (slice->getLayerId() == 0)
3972      {
3973        Int highestPoc = INT_MIN;
3974
3975        // Find greatest POC in DPB for layer 0
3976        for (TComList<TComPic*>::iterator iterPic = m_pcEncTop->getListPic()->begin(); iterPic != m_pcEncTop->getListPic()->end(); ++iterPic)
3977        {
3978          TComPic *dpbPic = *iterPic;
3979          if (dpbPic->getReconMark() && dpbPic->getLayerId() == 0 && dpbPic->getPOC() > highestPoc)
3980          {
3981            highestPoc = dpbPic->getPOC();
3982          }
3983        }
3984        deltaPocVal = (highestPoc - (highestPoc & (maxPocLsb - 1))) + 1*maxPocLsb;
3985        m_pcEncTop->setCurrPocMsb(deltaPocVal);
3986      }
3987      else
3988      {
3989        deltaPocVal = m_ppcTEncTop[0]->getCurrPocMsb();  // copy from base layer
3990      }
3991      slice->setPocMsbVal(deltaPocVal);
3992    }
3993
3994    for( UInt layerIdx = 0; layerIdx < numAffectedLayers; layerIdx++ )
3995    {
3996      UInt lIdx = slice->getVPS()->getLayerIdxInVps(affectedLayerList[layerIdx]);
3997
3998      if( !m_ppcTEncTop[lIdx]->getPocDecrementedInDPBFlag() )
3999      {
4000        m_ppcTEncTop[lIdx]->setPocDecrementedInDPBFlag(true);
4001
4002        // Decrement value of associatedIrapPoc of the TEncGop object
4003        m_ppcTEncTop[lIdx]->getGOPEncoder()->m_associatedIRAPPOC -= deltaPocVal;
4004
4005        // Decrememnt the value of m_pocCRA
4006        m_ppcTEncTop[lIdx]->getGOPEncoder()->m_pocCRA -= deltaPocVal;
4007
4008        TComList<TComPic*>::iterator  iterPic = m_ppcTEncTop[lIdx]->getListPic()->begin();
4009        while (iterPic != m_ppcTEncTop[lIdx]->getListPic()->end())
4010        {
4011          TComPic *dpbPic = *iterPic;
4012
4013          if( dpbPic->getReconMark() )
4014          {
4015            for( Int i = dpbPic->getNumAllocatedSlice() - 1; i >= 0; i-- )
4016            {
4017              TComSlice *dpbPicSlice = dpbPic->getSlice( i );
4018              TComReferencePictureSet *dpbPicRps = dpbPicSlice->getLocalRPS();
4019
4020              // Decrement POC of slice
4021              dpbPicSlice->setPOC( dpbPicSlice->getPOC() - deltaPocVal );
4022
4023              // Decrement POC value stored in the RPS of each such slice
4024              for( Int j = dpbPicRps->getNumberOfPictures() - 1; j >= 0; j-- )
4025              {
4026                dpbPicRps->setPOC( j, dpbPicRps->getPOC(j) - deltaPocVal );
4027              }
4028             
4029              dpbPicSlice->setRPS(dpbPicRps);
4030
4031              // Decrement value of refPOC
4032              dpbPicSlice->decrementRefPocValues( deltaPocVal );
4033
4034              // Update value of associatedIrapPoc of each slice
4035              dpbPicSlice->setAssociatedIRAPPOC( dpbPicSlice->getAssociatedIRAPPOC() - deltaPocVal );
4036
4037              if( slice->getPocMsbNeeded() )
4038              {
4039                // this delta value is needed when computing delta POCs in reference picture set initialization
4040                dpbPicSlice->setPocResetDeltaPoc(dpbPicSlice->getPocResetDeltaPoc() + (deltaPocVal - pocLsbVal));
4041              }
4042            }
4043          }
4044          iterPic++;
4045        }
4046      }
4047    }
4048
4049    // Actual POC value before reset
4050    adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4051
4052    // Set MSB value before reset
4053    Int tempLsbVal = adjustedPocValue & (maxPocLsb - 1);
4054    if (!slice->getPocMsbNeeded())  // set poc msb normally if special msb handling is not needed
4055    {
4056      slice->setPocMsbVal(adjustedPocValue - tempLsbVal);
4057    }
4058
4059    // Set LSB value before reset - this is needed in the case of resetIdc = 2
4060    slice->setPicOrderCntLsb( tempLsbVal );
4061
4062    // Cumulative delta
4063    deltaPocVal = origDeltaPocVal;  // restore deltaPoc for correct adjustment value update
4064
4065    m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + deltaPocVal );
4066  }
4067
4068  // New LSB value, after reset
4069  adjustedPocValue = pocCurr - m_pcEncTop->getPocAdjustmentValue();
4070  Int newLsbVal = adjustedPocValue & (maxPocLsb - 1);
4071
4072  // Set value of POC current picture after RESET
4073  if( slice->getPocResetIdc() == 1 )
4074  {
4075    slice->setPOC( newLsbVal );
4076  }
4077  else if( slice->getPocResetIdc() == 2 )
4078  {
4079    slice->setPOC( 0 );
4080  }
4081  else if( slice->getPocResetIdc() == 3 )
4082  {
4083    Int picOrderCntMsb = slice->getCurrMsb( newLsbVal, 
4084      slice->getFullPocResetFlag() ? 0 : slice->getPocLsbVal(), 
4085      0,
4086      maxPocLsb );
4087    slice->setPOC( picOrderCntMsb + newLsbVal );
4088  }
4089  else
4090  {
4091    assert(0);
4092  }
4093}
4094
4095#if CGS_3D_ASYMLUT
4096Void TEncGOP::xDetermin3DAsymLUT( TComSlice * pSlice, TComPic * pCurPic, UInt refLayerIdc, TEncCfg * pCfg, Bool bSignalPPS )
4097{
4098  Int nCGSFlag = pSlice->getPPS()->getCGSFlag();
4099  m_Enc3DAsymLUTPPS.setPPSBit( 0 );
4100  Double dErrorUpdatedPPS = 0 , dErrorPPS = 0;
4101
4102#if R0179_ENC_OPT_3DLUT_SIZE
4103  Int nTLthres = m_pcCfg->getCGSLutSizeRDO() ? 2:7;
4104  Double dFrameLambda; 
4105#if FULL_NBIT
4106  Int    SHIFT_QP = 12 + 6 * (pSlice->getBitDepthY() - 8);
4107#else
4108  Int    SHIFT_QP = 12; 
4109#endif
4110  Int QP = pSlice->getSliceQp();
4111
4112  // set frame lambda
4113  dFrameLambda = 0.68 * pow (2, (QP  - SHIFT_QP) / 3.0) * (m_pcCfg->getGOPSize() > 1 && pSlice->isInterB()? 2 : 1);
4114
4115  if(m_pcCfg->getCGSLutSizeRDO() == 1 && (!bSignalPPS && (pSlice->getDepth() < nTLthres))) 
4116    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB(), dFrameLambda );
4117  else if (pSlice->getDepth() >= nTLthres)
4118    dErrorUpdatedPPS = MAX_DOUBLE;
4119  else // if (m_pcCfg->getCGSLutSizeRDO() = 0 || bSignalPPS)
4120#endif   
4121    dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() );
4122
4123
4124  if( bSignalPPS )
4125  {
4126    m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4127    pSlice->setCGSOverWritePPS( 1 ); // regular PPS update
4128  }
4129  else if( nCGSFlag )
4130  {
4131#if R0179_ENC_OPT_3DLUT_SIZE
4132    if(pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R || pSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N) 
4133    {
4134      pSlice->setCGSOverWritePPS( 0 ); 
4135    }
4136    else if (pSlice->getDepth() >= nTLthres) 
4137    {
4138      pSlice->setCGSOverWritePPS( 0 ); 
4139    }
4140    else
4141    {
4142#endif   
4143      dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc );
4144      Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9;
4145
4146#if R0179_ENC_OPT_3DLUT_SIZE
4147      if( m_pcCfg->getCGSLutSizeRDO() )
4148      {
4149        dErrorPPS = dErrorPPS/m_Enc3DAsymLUTPicUpdate.getDistFactor(pSlice->getSliceType(), pSlice->getDepth()); 
4150      }
4151#endif
4152      pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS );
4153#if R0179_ENC_OPT_3DLUT_SIZE
4154    }
4155#endif
4156    if( pSlice->getCGSOverWritePPS() )
4157    {
4158      m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4159    }
4160  }
4161}
4162
4163Void TEncGOP::downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest, BitDepths& bitDepth)
4164{
4165  pcYuvSrc->setBorderExtension(false);
4166  pcYuvSrc->extendPicBorder   (); // extend the border.
4167  pcYuvSrc->setBorderExtension(false);
4168
4169  Int iWidth  = pcYuvSrc->getWidth(COMPONENT_Y);
4170  Int iHeight = pcYuvSrc->getHeight(COMPONENT_Y); 
4171
4172  if(!m_temp)
4173  {
4174    initDs(iWidth, iHeight, m_pcCfg->getIntraPeriod()>1);
4175  }
4176
4177  filterImg(pcYuvSrc->getAddr(COMPONENT_Y),  pcYuvSrc->getStride(COMPONENT_Y),  pcYuvDest->getAddr(COMPONENT_Y),  pcYuvDest->getStride(COMPONENT_Y),  iHeight,    iWidth,    bitDepth, 0);
4178  filterImg(pcYuvSrc->getAddr(COMPONENT_Cb), pcYuvSrc->getStride(COMPONENT_Cb), pcYuvDest->getAddr(COMPONENT_Cb), pcYuvDest->getStride(COMPONENT_Cb), iHeight>>1, iWidth>>1, bitDepth, 1);
4179  filterImg(pcYuvSrc->getAddr(COMPONENT_Cr), pcYuvSrc->getStride(COMPONENT_Cr), pcYuvDest->getAddr(COMPONENT_Cr), pcYuvDest->getStride(COMPONENT_Cr), iHeight>>1, iWidth>>1, bitDepth, 2); 
4180}
4181const Int TEncGOP::m_phase_filter_0_t0[4][13]={
4182  {0,  2,  -3,  -9,   6,  39,  58,  39,   6,  -9,  -3,  2,  0}, 
4183  {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},  //
4184  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4185  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4186};
4187
4188const Int TEncGOP::m_phase_filter_0_t1[4][13]={
4189  {0,  4,  0,  -12, 0,  40,  64,  40, 0, -12,  0,  4,  0},
4190  {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},  //
4191  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4192  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4193};
4194const Int TEncGOP::m_phase_filter_0_t1_chroma[4][13]={
4195  {0,  0,  0,   0,  0,   0,  128, 0,  0,  0,  0,  0,  0},
4196  {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},  //
4197  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4198  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4199};
4200
4201const Int TEncGOP::m_phase_filter_1[8][13]={
4202  {0,   0,  5,  -6,  -10,37,  76,  37,-10,   -6, 5,  0,   0},   
4203  {0,  -1,  5,  -3,  -12,29,  75,  45,  -7,   -8, 5,  0,   0},   
4204  {0,  -1,  4,  -1,  -13,22,  73,  52,  -3,  -10, 4,  1,   0},   
4205  {0,  -1,  4,   1,  -13,14,  70,  59,   2,  -12, 3,  2,  -1}, 
4206  {0,  -1,  3,   2,  -13, 8,  65,  65,   8,  -13, 2,  3,  -1},   
4207  {0,  -1,  2,   3,  -12, 2,  59,  70,  14,  -13, 1,  4,  -1},   
4208  {0,   0,  1,   4,  -10,-3,  52,  73,  22,  -13,-1,  4,  -1},   
4209  {0,   0,  0,   5,   -8,-7,  45,  75,  29,  -12,-3,  5,  -1}   
4210};
4211
4212#if CGS_GCC_NO_VECTORIZATION 
4213#ifdef __GNUC__
4214#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
4215#if GCC_VERSION > 40600
4216__attribute__((optimize("no-tree-vectorize")))
4217#endif
4218#endif
4219#endif
4220Void TEncGOP::filterImg( Pel *src, Int iSrcStride, Pel *dst, Int iDstStride, Int height1, Int width1, BitDepths& bitDepth, Int plane )
4221{
4222  Int length = m_iTap;
4223  Int height2,width2;
4224  Int k,iSum;
4225  Int i0, div_i0, i1;
4226  Int j0, div_j0, j1;
4227  const Int *p_filter;
4228  Pel *p_src, *p_dst;
4229  Pel *p_src_line, *p_dst_line;
4230  Int **p_temp, *p_tmp;
4231  Int shift = bitDepth.recon[CHANNEL_TYPE_LUMA] - bitDepth.recon[CHANNEL_TYPE_CHROMA];
4232  Int shift2 = 2*7+shift;
4233  Int shift_round = (1 << (shift2 - 1));
4234  Int iMax = (1<<(bitDepth.recon[CHANNEL_TYPE_LUMA]-shift))-1;
4235  height2 = (height1 * m_iM) / m_iN;
4236  width2  = (width1  * m_iM) / m_iN;
4237
4238  m_phase_filter = plane? m_phase_filter_chroma : m_phase_filter_luma;
4239
4240  // horizontal filtering
4241  p_src_line = src;
4242  for(j1 = 0; j1 < height1; j1++)
4243  {
4244    i0=-m_iN;
4245    p_tmp = m_temp[j1];
4246   
4247    for(i1 = 0; i1 < width2; i1++)
4248    {
4249      i0      += m_iN;
4250      div_i0   = (i0 / m_iM);
4251      p_src    =  p_src_line + ( div_i0 - (length >> 1));
4252      p_filter = m_phase_filter[i0 - div_i0 * m_iM]; // phase_filter[i0 % M]
4253      iSum     = 0;
4254      for(k = 0; k < length; k++)
4255      {
4256        iSum += (*p_src++) * (*p_filter++);
4257      }
4258      *p_tmp++ = iSum;
4259    }
4260    p_src_line +=  iSrcStride;
4261  }
4262
4263  // pad temp (vertical)
4264  for (k=-(length>>1); k<0; k++)
4265  {
4266    memcpy(m_temp[k], m_temp[0], width2*sizeof(Int));
4267  }
4268  for (k=height1; k<(height1+(length>>1)); k++)
4269  {
4270    memcpy(m_temp[k], m_temp[k-1], (width2)* sizeof(Int));
4271  }
4272
4273  // vertical filtering
4274  j0 = (plane == 0) ? -m_iN : -(m_iN-1);
4275 
4276  p_dst_line = dst;
4277  for(j1 = 0; j1 < height2; j1++)
4278  {
4279    j0      += m_iN;
4280    div_j0   = (j0 / m_iM);
4281    p_dst = p_dst_line;
4282    p_temp   = &m_temp[div_j0 - (length>>1)];
4283    p_filter = m_phase_filter[j0 - div_j0 * m_iM]; // phase_filter[j0 % M]
4284    for(i1 = 0; i1 < width2;i1++)
4285    {
4286      iSum=0;
4287      for(k = 0; k < length; k++)
4288      {
4289        iSum += p_temp[k][i1] * p_filter[k];
4290      }
4291      iSum=((iSum + shift_round) >> shift2);
4292      *p_dst++ = (Short)(iSum > iMax ? iMax : (iSum < 0 ? 0 : iSum));
4293    }
4294    p_dst_line += iDstStride;
4295  }
4296}
4297
4298Void TEncGOP::initDs(Int iWidth, Int iHeight, Int iType)
4299{
4300  m_iTap = 13;
4301  if(g_posScalingFactor[0][0] == (1<<15))
4302  {
4303    m_iM = 4;
4304    m_iN = 8;
4305    m_phase_filter_luma = iType? m_phase_filter_0_t1 : m_phase_filter_0_t0;
4306    m_phase_filter_chroma = m_phase_filter_0_t1_chroma; 
4307  }
4308  else
4309  {
4310    m_iM = 8;
4311    m_iN = 12;
4312    m_phase_filter_luma = m_phase_filter_chroma =  m_phase_filter_1;
4313    m_phase_filter = m_phase_filter_1;
4314  }
4315
4316  get_mem2DintWithPad (&m_temp, iHeight, iWidth*m_iM/m_iN,   m_iTap>>1, 0);
4317}
4318
4319Int TEncGOP::get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX)
4320{
4321  Int i;
4322  Int *curr = NULL;
4323  Int iHeight, iWidth;
4324
4325  iHeight = dim0+2*iPadY;
4326  iWidth = dim1+2*iPadX;
4327  (*array2D) = (Int**)malloc(iHeight*sizeof(Int*));
4328  *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth);
4329
4330  (*array2D)[0] += iPadX;
4331  curr = (*array2D)[0];
4332  for(i = 1 ; i < iHeight; i++)
4333  {
4334    curr += iWidth;
4335    (*array2D)[i] = curr;
4336  }
4337  (*array2D) = &((*array2D)[iPadY]);
4338
4339  return 0;
4340}
4341
4342Void TEncGOP::free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX)
4343{
4344  if (array2D)
4345  {
4346    if (*array2D)
4347    {
4348      xFree(array2D[-iPadY]-iPadX);
4349    }
4350    else 
4351    {
4352      printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
4353    }
4354
4355    free (&array2D[-iPadY]);
4356  } 
4357  else
4358  {
4359    printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
4360  }
4361}
4362#endif
4363
4364Void TEncGOP::xCheckLayerReset(TComSlice *slice)
4365{
4366  Bool layerResetFlag;
4367  Int dolLayerId;
4368
4369  if (slice->isIRAP() && slice->getLayerId() > 0)
4370  {
4371    if (m_prevPicHasEos)
4372    {
4373      layerResetFlag = true;
4374      dolLayerId = slice->getLayerId();
4375    }
4376    else if ((slice->isCRA() && slice->getHandleCraAsBlaFlag()) || (slice->isIDR() && slice->getCrossLayerBLAFlag()) || slice->isBLA())
4377    {
4378      layerResetFlag = true;
4379      dolLayerId = slice->getLayerId();
4380    }
4381    else
4382    {
4383      layerResetFlag = false;
4384    }
4385
4386    if (layerResetFlag)
4387    {
4388      for (Int i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
4389      {
4390        Int iLayerId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
4391        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(iLayerId)]->setLayerInitializedFlag(false);
4392        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(iLayerId)]->setFirstPicInLayerDecodedFlag(false);
4393      }
4394
4395      // Each picture that is in the DPB and has nuh_layer_id equal to dolLayerId is marked as "unused for reference".
4396      for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(dolLayerId)]->getListPic()->begin(); pic != m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(dolLayerId)]->getListPic()->end(); pic++)
4397      {
4398        if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
4399        {
4400          (*pic)->getSlice(0)->setReferenced(false);
4401        }
4402      }
4403
4404      // Each picture that is in DPB and has nuh_layer_id equal to any value of IdPredictedLayer[dolLayerId][i]
4405      // for the values of i in range of 0 to NumPredictedLayers[dolLayerId] - 1, inclusive, is marked as "unused for reference"
4406      for (UInt i = 0; i < slice->getVPS()->getNumPredictedLayers(dolLayerId); i++)
4407      {
4408        UInt predLId = slice->getVPS()->getPredictedLayerId(dolLayerId, i);
4409        for (TComList<TComPic*>::iterator pic = m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(predLId)]->getListPic()->begin(); pic != m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(predLId)]->getListPic()->end(); pic++)
4410        {
4411          if ((*pic)->getSlice(0)->getPOC() != slice->getPOC())
4412          {
4413            (*pic)->getSlice(0)->setReferenced(false);
4414          }
4415        }
4416      }
4417    }
4418  }
4419}
4420
4421Void TEncGOP::xSetNoRaslOutputFlag(TComSlice *slice)
4422{
4423  if (slice->isIRAP())
4424  {
4425    m_noRaslOutputFlag = slice->getHandleCraAsBlaFlag();  // default value
4426    if (slice->isIDR() || slice->isBLA() || m_bFirst || m_prevPicHasEos)
4427    {
4428      m_noRaslOutputFlag = true;
4429    }
4430    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag())
4431    {
4432      Bool refLayersInitialized = true;
4433      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
4434      {
4435        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
4436        if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(refLayerId)]->getLayerInitializedFlag())
4437        {
4438          refLayersInitialized = false;
4439        }
4440      }
4441      if (refLayersInitialized)
4442      {
4443        m_noRaslOutputFlag = true;
4444      }
4445    }
4446  }
4447}
4448
4449Void TEncGOP::xSetLayerInitializedFlag(TComSlice *slice)
4450{
4451  if (slice->isIRAP() && m_noRaslOutputFlag)
4452  {
4453    if (m_layerId == 0)
4454    {
4455      m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4456    }
4457    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag() && slice->getVPS()->getNumDirectRefLayers(m_layerId) == 0)
4458    {
4459      m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4460    }
4461    else if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->getLayerInitializedFlag())
4462    {
4463      Bool refLayersInitialized = true;
4464      for (UInt j = 0; j < slice->getVPS()->getNumDirectRefLayers(m_layerId); j++)
4465      {
4466        UInt refLayerId = slice->getVPS()->getRefLayerId(m_layerId, j);
4467        if (!m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(refLayerId)]->getLayerInitializedFlag())
4468        {
4469          refLayersInitialized = false;
4470        }
4471      }
4472      if (refLayersInitialized)
4473      {
4474        m_ppcTEncTop[slice->getVPS()->getLayerIdxInVps(m_layerId)]->setLayerInitializedFlag(true);
4475      }
4476    }
4477  }
4478}
4479#endif //SVC_EXTENSION
4480
4481#if Q0074_COLOUR_REMAPPING_SEI
4482Bool confirmParameter(Bool bflag, const Char* message)
4483{
4484  if (!bflag)
4485    return false;
4486
4487  printf("Error: %s\n",message);
4488  return true;
4489}
4490#endif
4491
4492//! \}
Note: See TracBrowser for help on using the repository browser.