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

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

port rev 4721

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