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

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

port rev 4412

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