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

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

port rev 4600, remove macro Q0074_COLOUR_REMAPPING_SEI

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