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

Last change on this file since 794 was 780, checked in by nokia, 11 years ago

software implementation for JCTVC-Q0247

  • Property svn:eol-style set to native
File size: 178.5 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2014, 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
52using namespace std;
53//! \ingroup TLibEncoder
54//! \{
55
56// ====================================================================================================================
57// Constructor / destructor / initialization / destroy
58// ====================================================================================================================
59Int getLSB(Int poc, Int maxLSB)
60{
61  if (poc >= 0)
62  {
63    return poc % maxLSB;
64  }
65  else
66  {
67    return (maxLSB - ((-poc) % maxLSB)) % maxLSB;
68  }
69}
70
71TEncGOP::TEncGOP()
72{
73  m_iLastIDR            = 0;
74  m_iGopSize            = 0;
75  m_iNumPicCoded        = 0; //Niko
76  m_bFirst              = true;
77#if ALLOW_RECOVERY_POINT_AS_RAP
78  m_iLastRecoveryPicPOC = 0;
79#endif
80 
81  m_pcCfg               = NULL;
82  m_pcSliceEncoder      = NULL;
83  m_pcListPic           = NULL;
84 
85  m_pcEntropyCoder      = NULL;
86  m_pcCavlcCoder        = NULL;
87  m_pcSbacCoder         = NULL;
88  m_pcBinCABAC          = NULL;
89 
90  m_bSeqFirst           = true;
91 
92  m_bRefreshPending     = 0;
93  m_pocCRA            = 0;
94  m_numLongTermRefPicSPS = 0;
95  ::memset(m_ltRefPicPocLsbSps, 0, sizeof(m_ltRefPicPocLsbSps));
96  ::memset(m_ltRefPicUsedByCurrPicFlag, 0, sizeof(m_ltRefPicUsedByCurrPicFlag));
97  m_cpbRemovalDelay   = 0;
98  m_lastBPSEI         = 0;
99  xResetNonNestedSEIPresentFlags();
100  xResetNestedSEIPresentFlags();
101#if FIX1172
102  m_associatedIRAPType = NAL_UNIT_CODED_SLICE_IDR_N_LP;
103  m_associatedIRAPPOC  = 0;
104#endif
105#if SVC_EXTENSION
106  m_pcPredSearch        = NULL;
107#if Q0048_CGS_3D_ASYMLUT
108  m_temp = NULL;
109  m_pColorMappedPic = NULL;
110#endif
111#endif //SVC_EXTENSION
112  return;
113}
114
115TEncGOP::~TEncGOP()
116{
117#if Q0048_CGS_3D_ASYMLUT
118  if(m_pColorMappedPic)
119  {
120    m_pColorMappedPic->destroy();
121    delete m_pColorMappedPic;
122    m_pColorMappedPic = NULL;               
123  }
124  if(m_temp)
125  {
126    free_mem2DintWithPad(m_temp, m_iTap>>1, 0);
127    m_temp = NULL;
128  }
129#endif
130}
131
132/** Create list to contain pointers to LCU start addresses of slice.
133 */
134#if SVC_EXTENSION
135Void  TEncGOP::create( UInt layerId )
136{
137  m_bLongtermTestPictureHasBeenCoded = 0;
138  m_bLongtermTestPictureHasBeenCoded2 = 0;
139  m_layerId = layerId;
140}
141#else
142Void  TEncGOP::create()
143{
144  m_bLongtermTestPictureHasBeenCoded = 0;
145  m_bLongtermTestPictureHasBeenCoded2 = 0;
146}
147#endif
148
149Void  TEncGOP::destroy()
150{
151}
152
153Void TEncGOP::init ( TEncTop* pcTEncTop )
154{
155  m_pcEncTop     = pcTEncTop;
156  m_pcCfg                = pcTEncTop;
157  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
158  m_pcListPic            = pcTEncTop->getListPic(); 
159 
160  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
161  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
162  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
163  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
164  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
165  m_pcBitCounter         = pcTEncTop->getBitCounter();
166 
167  //--Adaptive Loop filter
168  m_pcSAO                = pcTEncTop->getSAO();
169  m_pcRateCtrl           = pcTEncTop->getRateCtrl();
170  m_lastBPSEI          = 0;
171  m_totalCoded         = 0;
172
173#if SVC_EXTENSION
174  m_ppcTEncTop           = pcTEncTop->getLayerEnc();
175  m_pcPredSearch         = pcTEncTop->getPredSearch();                       ///< encoder search class
176#if Q0048_CGS_3D_ASYMLUT
177  if( pcTEncTop->getLayerId() )
178  {
179    m_Enc3DAsymLUTPicUpdate.create( m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthYLayer[pcTEncTop->getLayerId()-1] , g_bitDepthCLayer[pcTEncTop->getLayerId()-1] , g_bitDepthYLayer[pcTEncTop->getLayerId()] , g_bitDepthCLayer[pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ );
180    m_Enc3DAsymLUTPPS.create(   m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthYLayer[pcTEncTop->getLayerId()-1] , g_bitDepthCLayer[pcTEncTop->getLayerId()-1] , g_bitDepthYLayer[pcTEncTop->getLayerId()] , g_bitDepthCLayer[pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ );
181    if(!m_pColorMappedPic)
182    {
183      m_pColorMappedPic = new TComPicYuv;
184      m_pColorMappedPic->create( m_ppcTEncTop[0]->getSourceWidth(), m_ppcTEncTop[0]->getSourceHeight(), m_ppcTEncTop[0]->getChromaFormatIDC(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
185    }
186  }
187#endif
188#endif //SVC_EXTENSION
189}
190
191SEIActiveParameterSets* TEncGOP::xCreateSEIActiveParameterSets (TComSPS *sps)
192{
193  SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets(); 
194  seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId(); 
195  seiActiveParameterSets->m_selfContainedCvsFlag = false;
196  seiActiveParameterSets->m_noParameterSetUpdateFlag = false;
197  seiActiveParameterSets->numSpsIdsMinus1 = 0;
198  seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); 
199  seiActiveParameterSets->activeSeqParameterSetId[0] = sps->getSPSId();
200  return seiActiveParameterSets;
201}
202
203SEIFramePacking* TEncGOP::xCreateSEIFramePacking()
204{
205  SEIFramePacking *seiFramePacking = new SEIFramePacking();
206  seiFramePacking->m_arrangementId = m_pcCfg->getFramePackingArrangementSEIId();
207  seiFramePacking->m_arrangementCancelFlag = 0;
208  seiFramePacking->m_arrangementType = m_pcCfg->getFramePackingArrangementSEIType();
209  assert((seiFramePacking->m_arrangementType > 2) && (seiFramePacking->m_arrangementType < 6) );
210  seiFramePacking->m_quincunxSamplingFlag = m_pcCfg->getFramePackingArrangementSEIQuincunx();
211  seiFramePacking->m_contentInterpretationType = m_pcCfg->getFramePackingArrangementSEIInterpretation();
212  seiFramePacking->m_spatialFlippingFlag = 0;
213  seiFramePacking->m_frame0FlippedFlag = 0;
214  seiFramePacking->m_fieldViewsFlag = (seiFramePacking->m_arrangementType == 2);
215  seiFramePacking->m_currentFrameIsFrame0Flag = ((seiFramePacking->m_arrangementType == 5) && m_iNumPicCoded&1);
216  seiFramePacking->m_frame0SelfContainedFlag = 0;
217  seiFramePacking->m_frame1SelfContainedFlag = 0;
218  seiFramePacking->m_frame0GridPositionX = 0;
219  seiFramePacking->m_frame0GridPositionY = 0;
220  seiFramePacking->m_frame1GridPositionX = 0;
221  seiFramePacking->m_frame1GridPositionY = 0;
222  seiFramePacking->m_arrangementReservedByte = 0;
223  seiFramePacking->m_arrangementPersistenceFlag = true;
224  seiFramePacking->m_upsampledAspectRatio = 0;
225  return seiFramePacking;
226}
227
228SEIDisplayOrientation* TEncGOP::xCreateSEIDisplayOrientation()
229{
230  SEIDisplayOrientation *seiDisplayOrientation = new SEIDisplayOrientation();
231  seiDisplayOrientation->cancelFlag = false;
232  seiDisplayOrientation->horFlip = false;
233  seiDisplayOrientation->verFlip = false;
234  seiDisplayOrientation->anticlockwiseRotation = m_pcCfg->getDisplayOrientationSEIAngle();
235  return seiDisplayOrientation;
236}
237
238SEIToneMappingInfo*  TEncGOP::xCreateSEIToneMappingInfo()
239{
240  SEIToneMappingInfo *seiToneMappingInfo = new SEIToneMappingInfo();
241  seiToneMappingInfo->m_toneMapId = m_pcCfg->getTMISEIToneMapId();
242  seiToneMappingInfo->m_toneMapCancelFlag = m_pcCfg->getTMISEIToneMapCancelFlag();
243  seiToneMappingInfo->m_toneMapPersistenceFlag = m_pcCfg->getTMISEIToneMapPersistenceFlag();
244
245  seiToneMappingInfo->m_codedDataBitDepth = m_pcCfg->getTMISEICodedDataBitDepth();
246  assert(seiToneMappingInfo->m_codedDataBitDepth >= 8 && seiToneMappingInfo->m_codedDataBitDepth <= 14);
247  seiToneMappingInfo->m_targetBitDepth = m_pcCfg->getTMISEITargetBitDepth();
248  assert( seiToneMappingInfo->m_targetBitDepth >= 1 && seiToneMappingInfo->m_targetBitDepth <= 17 );
249  seiToneMappingInfo->m_modelId = m_pcCfg->getTMISEIModelID();
250  assert(seiToneMappingInfo->m_modelId >=0 &&seiToneMappingInfo->m_modelId<=4);
251
252  switch( seiToneMappingInfo->m_modelId)
253  {
254  case 0:
255    {
256      seiToneMappingInfo->m_minValue = m_pcCfg->getTMISEIMinValue();
257      seiToneMappingInfo->m_maxValue = m_pcCfg->getTMISEIMaxValue();
258      break;
259    }
260  case 1:
261    {
262      seiToneMappingInfo->m_sigmoidMidpoint = m_pcCfg->getTMISEISigmoidMidpoint();
263      seiToneMappingInfo->m_sigmoidWidth = m_pcCfg->getTMISEISigmoidWidth();
264      break;
265    }
266  case 2:
267    {
268      UInt num = 1u<<(seiToneMappingInfo->m_targetBitDepth);
269      seiToneMappingInfo->m_startOfCodedInterval.resize(num);
270      Int* ptmp = m_pcCfg->getTMISEIStartOfCodedInterva();
271      if(ptmp)
272      {
273        for(int i=0; i<num;i++)
274        {
275          seiToneMappingInfo->m_startOfCodedInterval[i] = ptmp[i];
276        }
277      }
278      break;
279    }
280  case 3:
281    {
282      seiToneMappingInfo->m_numPivots = m_pcCfg->getTMISEINumPivots();
283      seiToneMappingInfo->m_codedPivotValue.resize(seiToneMappingInfo->m_numPivots);
284      seiToneMappingInfo->m_targetPivotValue.resize(seiToneMappingInfo->m_numPivots);
285      Int* ptmpcoded = m_pcCfg->getTMISEICodedPivotValue();
286      Int* ptmptarget = m_pcCfg->getTMISEITargetPivotValue();
287      if(ptmpcoded&&ptmptarget)
288      {
289        for(int i=0; i<(seiToneMappingInfo->m_numPivots);i++)
290        {
291          seiToneMappingInfo->m_codedPivotValue[i]=ptmpcoded[i];
292          seiToneMappingInfo->m_targetPivotValue[i]=ptmptarget[i];
293         }
294       }
295       break;
296     }
297  case 4:
298     {
299       seiToneMappingInfo->m_cameraIsoSpeedIdc = m_pcCfg->getTMISEICameraIsoSpeedIdc();
300       seiToneMappingInfo->m_cameraIsoSpeedValue = m_pcCfg->getTMISEICameraIsoSpeedValue();
301       assert( seiToneMappingInfo->m_cameraIsoSpeedValue !=0 );
302       seiToneMappingInfo->m_exposureIndexIdc = m_pcCfg->getTMISEIExposurIndexIdc();
303       seiToneMappingInfo->m_exposureIndexValue = m_pcCfg->getTMISEIExposurIndexValue();
304       assert( seiToneMappingInfo->m_exposureIndexValue !=0 );
305       seiToneMappingInfo->m_exposureCompensationValueSignFlag = m_pcCfg->getTMISEIExposureCompensationValueSignFlag();
306       seiToneMappingInfo->m_exposureCompensationValueNumerator = m_pcCfg->getTMISEIExposureCompensationValueNumerator();
307       seiToneMappingInfo->m_exposureCompensationValueDenomIdc = m_pcCfg->getTMISEIExposureCompensationValueDenomIdc();
308       seiToneMappingInfo->m_refScreenLuminanceWhite = m_pcCfg->getTMISEIRefScreenLuminanceWhite();
309       seiToneMappingInfo->m_extendedRangeWhiteLevel = m_pcCfg->getTMISEIExtendedRangeWhiteLevel();
310       assert( seiToneMappingInfo->m_extendedRangeWhiteLevel >= 100 );
311       seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue = m_pcCfg->getTMISEINominalBlackLevelLumaCodeValue();
312       seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue = m_pcCfg->getTMISEINominalWhiteLevelLumaCodeValue();
313       assert( seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue > seiToneMappingInfo->m_nominalBlackLevelLumaCodeValue );
314       seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue = m_pcCfg->getTMISEIExtendedWhiteLevelLumaCodeValue();
315       assert( seiToneMappingInfo->m_extendedWhiteLevelLumaCodeValue >= seiToneMappingInfo->m_nominalWhiteLevelLumaCodeValue );
316       break;
317    }
318  default:
319    {
320      assert(!"Undefined SEIToneMapModelId");
321      break;
322    }
323  }
324  return seiToneMappingInfo;
325}
326
327#if P0050_KNEE_FUNCTION_SEI
328SEIKneeFunctionInfo* TEncGOP::xCreateSEIKneeFunctionInfo()
329{
330  SEIKneeFunctionInfo *seiKneeFunctionInfo = new SEIKneeFunctionInfo();
331  seiKneeFunctionInfo->m_kneeId = m_pcCfg->getKneeSEIId();
332  seiKneeFunctionInfo->m_kneeCancelFlag = m_pcCfg->getKneeSEICancelFlag();
333  if ( !seiKneeFunctionInfo->m_kneeCancelFlag )
334  {
335    seiKneeFunctionInfo->m_kneePersistenceFlag = m_pcCfg->getKneeSEIPersistenceFlag();
336    seiKneeFunctionInfo->m_kneeMappingFlag = m_pcCfg->getKneeSEIMappingFlag();
337    seiKneeFunctionInfo->m_kneeInputDrange = m_pcCfg->getKneeSEIInputDrange();
338    seiKneeFunctionInfo->m_kneeInputDispLuminance = m_pcCfg->getKneeSEIInputDispLuminance();
339    seiKneeFunctionInfo->m_kneeOutputDrange = m_pcCfg->getKneeSEIOutputDrange();
340    seiKneeFunctionInfo->m_kneeOutputDispLuminance = m_pcCfg->getKneeSEIOutputDispLuminance();
341
342    seiKneeFunctionInfo->m_kneeNumKneePointsMinus1 = m_pcCfg->getKneeSEINumKneePointsMinus1();
343    Int* piInputKneePoint  = m_pcCfg->getKneeSEIInputKneePoint();
344    Int* piOutputKneePoint = m_pcCfg->getKneeSEIOutputKneePoint();
345    if(piInputKneePoint&&piOutputKneePoint)
346    {
347      seiKneeFunctionInfo->m_kneeInputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
348      seiKneeFunctionInfo->m_kneeOutputKneePoint.resize(seiKneeFunctionInfo->m_kneeNumKneePointsMinus1+1);
349      for(Int i=0; i<=seiKneeFunctionInfo->m_kneeNumKneePointsMinus1; i++)
350      {
351        seiKneeFunctionInfo->m_kneeInputKneePoint[i] = piInputKneePoint[i];
352        seiKneeFunctionInfo->m_kneeOutputKneePoint[i] = piOutputKneePoint[i];
353       }
354    }
355  }
356  return seiKneeFunctionInfo;
357}
358#endif
359
360#if Q0074_SEI_COLOR_MAPPING
361SEIColorMappingInfo*  TEncGOP::xCreateSEIColorMappingInfo( Char* file )
362{
363  SEIColorMappingInfo *seiColorMappingInfo = new SEIColorMappingInfo();
364
365  FILE* fic = fopen( file, "r" );
366
367  Int iVal, retval;
368
369  retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMapId );
370  retval = fscanf( fic, "%d", &iVal );
371  seiColorMappingInfo->m_colorMapCancelFlag = iVal;
372  if( !seiColorMappingInfo->m_colorMapCancelFlag )
373  {
374    retval = fscanf( fic, "%d", &iVal );
375    seiColorMappingInfo->m_colorMapPersistenceFlag = iVal;
376    retval = fscanf( fic, "%d", &iVal );
377    seiColorMappingInfo->m_colorMap_video_signal_type_present_flag = iVal;
378    if( seiColorMappingInfo->m_colorMap_video_signal_type_present_flag )
379    {
380      retval = fscanf( fic, "%d", &iVal );
381      seiColorMappingInfo->m_colorMap_video_full_range_flag = iVal;
382      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMap_primaries );
383      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMap_transfer_characteristics );
384      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMap_matrix_coeffs );
385    }
386  }
387
388  retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colour_map_coded_data_bit_depth );
389  retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colour_map_target_bit_depth );
390  retval = fscanf( fic, "%d", &iVal );
391  seiColorMappingInfo->m_colorMapModelId = iVal;
392
393  assert( seiColorMappingInfo->m_colorMapModelId == 0 );
394 
395  for( Int i=0 ; i<3 ; i++ )
396  {
397    retval = fscanf( fic, "%d", &seiColorMappingInfo->m_num_input_pivots[i] );
398    seiColorMappingInfo->m_coded_input_pivot_value[i]   = new Int[ seiColorMappingInfo->m_num_input_pivots[i] ];
399    seiColorMappingInfo->m_target_input_pivot_value[i]  = new Int[ seiColorMappingInfo->m_num_input_pivots[i] ];
400    for( Int j=0 ; j<seiColorMappingInfo->m_num_input_pivots[i] ; j++ )
401    {
402      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_coded_input_pivot_value[i][j] );
403      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_target_input_pivot_value[i][j] );
404    }
405  }
406
407  retval = fscanf( fic, "%d", &iVal );
408  seiColorMappingInfo->m_matrix_flag = iVal;
409  if( seiColorMappingInfo->m_matrix_flag )
410  {
411    retval = fscanf( fic, "%d", &seiColorMappingInfo->m_log2_matrix_denom );
412    for( Int i=0 ; i<3 ; i++ )
413    {
414      for( Int j=0 ; j<3 ; j++ )
415      {
416        retval = fscanf( fic, "%d", &seiColorMappingInfo->m_matrix_coef[i][j] );
417      }
418    }
419  }
420
421  for( Int i=0 ; i<3 ; i++ )
422  {
423    retval = fscanf( fic, "%d", &seiColorMappingInfo->m_num_output_pivots[i] );
424    seiColorMappingInfo->m_coded_output_pivot_value[i]   = new Int[ seiColorMappingInfo->m_num_output_pivots[i] ];
425    seiColorMappingInfo->m_target_output_pivot_value[i]  = new Int[ seiColorMappingInfo->m_num_output_pivots[i] ];
426    for( Int j=0 ; j<seiColorMappingInfo->m_num_output_pivots[i] ; j++ )
427    {
428      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_coded_output_pivot_value[i][j] );
429      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_target_output_pivot_value[i][j] );
430    }
431  }
432
433  fclose( fic );
434
435  if( retval != 1 )
436  {
437    printf("Error: can't read color mapping information\n");
438  }
439
440  return seiColorMappingInfo;
441}
442#endif
443
444Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps)
445{
446  OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
447
448  if(m_pcCfg->getActiveParameterSetsSEIEnabled())
449  {
450    SEIActiveParameterSets *sei = xCreateSEIActiveParameterSets (sps);
451
452    //nalu = NALUnit(NAL_UNIT_SEI);
453    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
454#if O0164_MULTI_LAYER_HRD
455    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
456#else
457    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
458#endif
459    writeRBSPTrailingBits(nalu.m_Bitstream);
460    accessUnit.push_back(new NALUnitEBSP(nalu));
461    delete sei;
462    m_activeParameterSetSEIPresentInAU = true;
463  }
464
465  if(m_pcCfg->getFramePackingArrangementSEIEnabled())
466  {
467    SEIFramePacking *sei = xCreateSEIFramePacking ();
468
469    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
470    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
471#if O0164_MULTI_LAYER_HRD
472    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps);
473#else
474    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
475#endif
476    writeRBSPTrailingBits(nalu.m_Bitstream);
477    accessUnit.push_back(new NALUnitEBSP(nalu));
478    delete sei;
479  }
480  if (m_pcCfg->getDisplayOrientationSEIAngle())
481  {
482    SEIDisplayOrientation *sei = xCreateSEIDisplayOrientation();
483
484    nalu = NALUnit(NAL_UNIT_PREFIX_SEI); 
485    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
486#if O0164_MULTI_LAYER_HRD
487    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
488#else
489    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
490#endif
491    writeRBSPTrailingBits(nalu.m_Bitstream);
492    accessUnit.push_back(new NALUnitEBSP(nalu));
493    delete sei;
494  }
495  if(m_pcCfg->getToneMappingInfoSEIEnabled())
496  {
497    SEIToneMappingInfo *sei = xCreateSEIToneMappingInfo ();
498     
499    nalu = NALUnit(NAL_UNIT_PREFIX_SEI); 
500    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
501#if O0164_MULTI_LAYER_HRD
502    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
503#else
504    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
505#endif
506    writeRBSPTrailingBits(nalu.m_Bitstream);
507    accessUnit.push_back(new NALUnitEBSP(nalu));
508    delete sei;
509  }
510#if P0050_KNEE_FUNCTION_SEI
511  if(m_pcCfg->getKneeSEIEnabled())
512  {
513    SEIKneeFunctionInfo *sei = xCreateSEIKneeFunctionInfo();
514
515    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
516    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
517#if O0164_MULTI_LAYER_HRD
518    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps);
519#else
520    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps);
521#endif
522    writeRBSPTrailingBits(nalu.m_Bitstream);
523    accessUnit.push_back(new NALUnitEBSP(nalu));
524    delete sei;
525  }
526#endif
527#if Q0074_SEI_COLOR_MAPPING
528  if(m_pcCfg->getColorMappingInfoSEIFile())
529  {
530    SEIColorMappingInfo *sei = xCreateSEIColorMappingInfo( m_pcCfg->getColorMappingInfoSEIFile() );
531     
532#if SVC_EXTENSION
533    nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, m_layerId);  // temporalId = 0 ?
534#else
535    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
536#endif
537    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
538#if O0164_MULTI_LAYER_HRD
539    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
540#else
541    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
542#endif
543    writeRBSPTrailingBits(nalu.m_Bitstream);
544    accessUnit.push_back(new NALUnitEBSP(nalu));
545    delete sei;
546  }
547#endif
548
549#if SVC_EXTENSION
550#if LAYERS_NOT_PRESENT_SEI
551  if(m_pcCfg->getLayersNotPresentSEIEnabled())
552  {
553    SEILayersNotPresent *sei = xCreateSEILayersNotPresent ();
554    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
555#if O0164_MULTI_LAYER_HRD
556    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
557#else
558    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
559#endif
560    writeRBSPTrailingBits(nalu.m_Bitstream);
561    accessUnit.push_back(new NALUnitEBSP(nalu));
562    delete sei;
563  }
564#endif
565
566#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
567  if(m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled())
568  {
569    SEIInterLayerConstrainedTileSets *sei = xCreateSEIInterLayerConstrainedTileSets ();
570
571    nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, m_pcCfg->getNumLayer()-1); // For highest layer
572    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
573#if O0164_MULTI_LAYER_HRD
574    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
575#else
576    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
577#endif
578    writeRBSPTrailingBits(nalu.m_Bitstream);
579    accessUnit.push_back(new NALUnitEBSP(nalu));
580    delete sei;
581  }
582#endif
583#endif //SVC_EXTENSION
584}
585
586// ====================================================================================================================
587// Public member functions
588// ====================================================================================================================
589#if SVC_EXTENSION
590Void TEncGOP::compressGOP( Int iPicIdInGOP, Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, Bool isField, Bool isTff)
591#else
592Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, Bool isField, Bool isTff)
593#endif
594{
595  TComPic*        pcPic;
596  TComPicYuv*     pcPicYuvRecOut;
597  TComSlice*      pcSlice;
598  TComOutputBitstream  *pcBitstreamRedirect;
599  pcBitstreamRedirect = new TComOutputBitstream;
600  AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
601  UInt                  uiOneBitstreamPerSliceLength = 0;
602  TEncSbac* pcSbacCoders = NULL;
603  TComOutputBitstream* pcSubstreamsOut = NULL;
604
605  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut, isField );
606
607  m_iNumPicCoded = 0;
608  SEIPictureTiming pictureTimingSEI;
609  Bool writeSOP = m_pcCfg->getSOPDescriptionSEIEnabled();
610  // Initialize Scalable Nesting SEI with single layer values
611  SEIScalableNesting scalableNestingSEI;
612  scalableNestingSEI.m_bitStreamSubsetFlag           = 1;      // If the nested SEI messages are picture buffereing SEI mesages, picure timing SEI messages or sub-picture timing SEI messages, bitstream_subset_flag shall be equal to 1
613  scalableNestingSEI.m_nestingOpFlag                 = 0;
614  scalableNestingSEI.m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
615  scalableNestingSEI.m_allLayersFlag                 = 0;
616  scalableNestingSEI.m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
617  scalableNestingSEI.m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
618  scalableNestingSEI.m_nestingLayerId[0]             = 0;
619  scalableNestingSEI.m_callerOwnsSEIs                = true;
620  Int picSptDpbOutputDuDelay = 0;
621  UInt *accumBitsDU = NULL;
622  UInt *accumNalsDU = NULL;
623  SEIDecodingUnitInfo decodingUnitInfoSEI;
624#if EFFICIENT_FIELD_IRAP
625  Int IRAPGOPid = -1;
626  Bool IRAPtoReorder = false;
627  Bool swapIRAPForward = false;
628  if(isField)
629  {
630    Int pocCurr;
631#if SVC_EXTENSION
632    for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
633#else
634    for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
635#endif   
636    {
637      // determine actual POC
638      if(iPOCLast == 0) //case first frame or first top field
639      {
640        pocCurr=0;
641      }
642      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
643      {
644        pocCurr = 1;
645      }
646      else
647      {
648        pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
649      }
650
651      // check if POC corresponds to IRAP
652      NalUnitType tmpUnitType = getNalUnitType(pocCurr, m_iLastIDR, isField);
653      if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP
654      {
655        if(pocCurr%2 == 0 && iGOPid < m_iGopSize-1 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid+1).m_POC-1)
656        { // if top field and following picture in enc order is associated bottom field
657          IRAPGOPid = iGOPid;
658          IRAPtoReorder = true;
659          swapIRAPForward = true; 
660          break;
661        }
662        if(pocCurr%2 != 0 && iGOPid > 0 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid-1).m_POC+1)
663        {
664          // if picture is an IRAP remember to process it first
665          IRAPGOPid = iGOPid;
666          IRAPtoReorder = true;
667          swapIRAPForward = false; 
668          break;
669        }
670      }
671    }
672  }
673#endif
674#if SVC_EXTENSION
675  for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
676#else
677  for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
678#endif
679  {
680#if EFFICIENT_FIELD_IRAP
681    if(IRAPtoReorder)
682    {
683      if(swapIRAPForward)
684      {
685        if(iGOPid == IRAPGOPid)
686        {
687          iGOPid = IRAPGOPid +1;
688        }
689        else if(iGOPid == IRAPGOPid +1)
690        {
691          iGOPid = IRAPGOPid;
692        }
693      }
694      else
695      {
696        if(iGOPid == IRAPGOPid -1)
697        {
698          iGOPid = IRAPGOPid;
699        }
700        else if(iGOPid == IRAPGOPid)
701        {
702          iGOPid = IRAPGOPid -1;
703        }
704      }
705    }
706#endif
707    UInt uiColDir = 1;
708    //-- For time output for each slice
709    long iBeforeTime = clock();
710
711    //select uiColDir
712    Int iCloseLeft=1, iCloseRight=-1;
713    for(Int i = 0; i<m_pcCfg->getGOPEntry(iGOPid).m_numRefPics; i++) 
714    {
715      Int iRef = m_pcCfg->getGOPEntry(iGOPid).m_referencePics[i];
716      if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
717      {
718        iCloseRight=iRef;
719      }
720      else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
721      {
722        iCloseLeft=iRef;
723      }
724    }
725    if(iCloseRight>-1)
726    {
727      iCloseRight=iCloseRight+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
728    }
729    if(iCloseLeft<1) 
730    {
731      iCloseLeft=iCloseLeft+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
732      while(iCloseLeft<0)
733      {
734        iCloseLeft+=m_iGopSize;
735      }
736    }
737    Int iLeftQP=0, iRightQP=0;
738    for(Int i=0; i<m_iGopSize; i++)
739    {
740      if(m_pcCfg->getGOPEntry(i).m_POC==(iCloseLeft%m_iGopSize)+1)
741      {
742        iLeftQP= m_pcCfg->getGOPEntry(i).m_QPOffset;
743      }
744      if (m_pcCfg->getGOPEntry(i).m_POC==(iCloseRight%m_iGopSize)+1)
745      {
746        iRightQP=m_pcCfg->getGOPEntry(i).m_QPOffset;
747      }
748    }
749    if(iCloseRight>-1&&iRightQP<iLeftQP)
750    {
751      uiColDir=0;
752    }
753
754    /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
755    Int iTimeOffset;
756    Int pocCurr;
757   
758    if(iPOCLast == 0) //case first frame or first top field
759    {
760      pocCurr=0;
761      iTimeOffset = 1;
762    }
763    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
764    {
765      pocCurr = 1;
766      iTimeOffset = 1;
767    }
768    else
769    {
770      pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
771      iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
772    }
773
774    if(pocCurr>=m_pcCfg->getFramesToBeEncoded())
775    {
776#if EFFICIENT_FIELD_IRAP
777      if(IRAPtoReorder)
778      {
779        if(swapIRAPForward)
780        {
781          if(iGOPid == IRAPGOPid)
782          {
783            iGOPid = IRAPGOPid +1;
784            IRAPtoReorder = false;
785          }
786          else if(iGOPid == IRAPGOPid +1)
787          {
788            iGOPid --;
789          }
790        }
791        else
792        {
793          if(iGOPid == IRAPGOPid)
794          {
795            iGOPid = IRAPGOPid -1;
796          }
797          else if(iGOPid == IRAPGOPid -1)
798          {
799            iGOPid = IRAPGOPid;
800            IRAPtoReorder = false;
801          }
802        }
803      }
804#endif
805      continue;
806    }
807
808#if M0040_ADAPTIVE_RESOLUTION_CHANGE
809    if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && ((m_layerId == 1 && pocCurr < m_pcEncTop->getAdaptiveResolutionChange()) ||
810                                                          (m_layerId == 0 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange())) )
811    {
812      continue;
813    }
814#endif
815
816    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 )
817    {
818      m_iLastIDR = pocCurr;
819    }       
820    // start a new access unit: create an entry in the list of output access units
821    accessUnitsInGOP.push_back(AccessUnit());
822    AccessUnit& accessUnit = accessUnitsInGOP.back();
823    xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, pocCurr, isField);
824
825    //  Slice data initialization
826    pcPic->clearSliceBuffer();
827    assert(pcPic->getNumAllocatedSlice() == 1);
828    m_pcSliceEncoder->setSliceIdx(0);
829    pcPic->setCurrSliceIdx(0);
830#if SVC_EXTENSION
831    pcPic->setLayerId( m_layerId );
832    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), m_pcEncTop->getVPS(), isField );
833#else
834    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, pocCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS(), isField );
835#endif
836
837    //Set Frame/Field coding
838    pcSlice->getPic()->setField(isField);
839
840#if SVC_EXTENSION
841#if POC_RESET_FLAG
842    if( !pcSlice->getPocResetFlag() ) // For picture that are not reset, we should adjust the value of POC calculated from the configuration files.
843    {
844      // Subtract POC adjustment value until now.
845      pcSlice->setPOC( pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue() );
846    }
847    else
848    {
849      // Check if this is the first slice in the picture
850      // In the encoder, the POC values are copied along with copySliceInfo, so we only need
851      // to do this for the first slice.
852      Int pocAdjustValue = pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue();
853      if( pcSlice->getSliceIdx() == 0 )
854      {
855        TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
856
857        // Iterate through all picture in DPB
858        while( iterPic != rcListPic.end() )
859        {             
860          TComPic *dpbPic = *iterPic;
861          if( dpbPic->getPOC() == pocCurr )
862          {
863            if( dpbPic->getReconMark() )
864            {
865              assert( !( dpbPic->getSlice(0)->isReferenced() ) && !( dpbPic->getOutputMark() ) );
866            }
867          }
868          // Check if the picture pointed to by iterPic is either used for reference or
869          // needed for output, are in the same layer, and not the current picture.
870          if( /* ( ( dpbPic->getSlice(0)->isReferenced() ) || ( dpbPic->getOutputMark() ) )
871              && */ ( dpbPic->getLayerId() == pcSlice->getLayerId() )
872              && ( dpbPic->getReconMark() ) 
873            )
874          {
875            for(Int i = dpbPic->getNumAllocatedSlice()-1; i >= 0; i--)
876            {
877              TComSlice *slice = dpbPic->getSlice(i);
878              TComReferencePictureSet *rps = slice->getRPS();
879              slice->setPOC( dpbPic->getSlice(i)->getPOC() - pocAdjustValue );
880
881              // Also adjust the POC value stored in the RPS of each such slice
882              for(Int j = rps->getNumberOfPictures(); j >= 0; j--)
883              {
884                rps->setPOC( j, rps->getPOC(j) - pocAdjustValue );
885              }
886              // Also adjust the value of refPOC
887              for(Int k = 0; k < 2; k++)  // For List 0 and List 1
888              {
889                RefPicList list = (k == 1) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
890                for(Int j = 0; j < slice->getNumRefIdx(list); j++)
891                {
892                  slice->setRefPOC( slice->getRefPOC(list, j) - pocAdjustValue, list, j);
893                }
894              }
895            }
896          }
897          iterPic++;
898        }
899        m_pcEncTop->setPocAdjustmentValue( m_pcEncTop->getPocAdjustmentValue() + pocAdjustValue );
900      }
901      pcSlice->setPocValueBeforeReset( pcSlice->getPOC() - m_pcEncTop->getPocAdjustmentValue() + pocAdjustValue );
902      pcSlice->setPOC( 0 );
903    }
904#endif
905#if O0149_CROSS_LAYER_BLA_FLAG
906    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) )
907    {
908      pcSlice->setCrossLayerBLAFlag(m_pcEncTop->getCrossLayerBLAFlag());
909    }
910    else
911    {
912      pcSlice->setCrossLayerBLAFlag(false);
913    }
914#endif
915#if NO_CLRAS_OUTPUT_FLAG
916    if (m_layerId == 0 &&
917        (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
918      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
919      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
920      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
921      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
922      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA))
923    {
924      if (m_bFirst)
925      {
926        m_pcEncTop->setNoClrasOutputFlag(true);
927      }
928      else if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
929            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
930            || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP)
931      {
932        m_pcEncTop->setNoClrasOutputFlag(true);
933      }
934#if O0149_CROSS_LAYER_BLA_FLAG
935      else if ((pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP) &&
936               pcSlice->getCrossLayerBLAFlag())
937      {
938        m_pcEncTop->setNoClrasOutputFlag(true);
939      }
940#endif
941      else
942      {
943        m_pcEncTop->setNoClrasOutputFlag(false);
944      }
945      if (m_pcEncTop->getNoClrasOutputFlag())
946      {
947        for (UInt i = 0; i < m_pcCfg->getNumLayer(); i++)
948        {
949          m_ppcTEncTop[i]->setLayerInitializedFlag(false);
950          m_ppcTEncTop[i]->setFirstPicInLayerDecodedFlag(false);
951        }
952      }
953    }
954#endif
955#if M0040_ADAPTIVE_RESOLUTION_CHANGE
956    if (m_pcEncTop->getAdaptiveResolutionChange() > 0 && m_layerId == 1 && pocCurr > m_pcEncTop->getAdaptiveResolutionChange())
957    {
958      pcSlice->setActiveNumILRRefIdx(0);
959      pcSlice->setInterLayerPredEnabledFlag(false);
960      pcSlice->setMFMEnabledFlag(false);
961    }
962#endif
963#endif //SVC_EXTENSION
964
965    pcSlice->setLastIDR(m_iLastIDR);
966    pcSlice->setSliceIdx(0);
967    //set default slice level flag to the same as SPS level flag
968    pcSlice->setLFCrossSliceBoundaryFlag(  pcSlice->getPPS()->getLoopFilterAcrossSlicesEnabledFlag()  );
969    pcSlice->setScalingList ( m_pcEncTop->getScalingList()  );
970    if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF)
971    {
972      m_pcEncTop->getTrQuant()->setFlatScalingList();
973      m_pcEncTop->getTrQuant()->setUseScalingList(false);
974      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
975      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
976    }
977    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT)
978    {
979#if SCALINGLIST_INFERRING
980      // inferring of the scaling list can be moved to the config file
981      UInt refLayerId = 0;
982      if( m_layerId > 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
983      {
984        m_pcEncTop->getSPS()->setInferScalingListFlag( true );
985        m_pcEncTop->getSPS()->setScalingListRefLayerId( refLayerId );
986        m_pcEncTop->getSPS()->setScalingListPresentFlag( false );
987        m_pcEncTop->getPPS()->setInferScalingListFlag( false );
988        m_pcEncTop->getPPS()->setScalingListPresentFlag( false );
989
990        // infer the scaling list from the reference layer
991        pcSlice->setScalingList ( m_ppcTEncTop[refLayerId]->getScalingList() );
992      }
993      else
994      {
995#endif
996      pcSlice->setDefaultScalingList ();
997      m_pcEncTop->getSPS()->setScalingListPresentFlag(false);
998      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
999
1000#if SCALINGLIST_INFERRING
1001      }
1002#endif
1003
1004      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
1005      m_pcEncTop->getTrQuant()->setUseScalingList(true);
1006    }
1007    else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ)
1008    {
1009#if SCALINGLIST_INFERRING
1010      // inferring of the scaling list can be moved to the config file
1011      UInt refLayerId = 0;
1012      if( m_layerId > 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() && m_pcEncTop->getVPS()->getRecursiveRefLayerFlag( m_layerId, refLayerId ) )
1013      {
1014        m_pcEncTop->getSPS()->setInferScalingListFlag( true );
1015        m_pcEncTop->getSPS()->setScalingListRefLayerId( refLayerId );
1016        m_pcEncTop->getSPS()->setScalingListPresentFlag( false );
1017        m_pcEncTop->getPPS()->setInferScalingListFlag( false );
1018        m_pcEncTop->getPPS()->setScalingListPresentFlag( false );
1019
1020        // infer the scaling list from the reference layer
1021        pcSlice->setScalingList ( m_ppcTEncTop[refLayerId]->getScalingList() );
1022      }
1023      else
1024      {
1025#endif
1026
1027      if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile()))
1028      {
1029        pcSlice->setDefaultScalingList ();
1030      }
1031      pcSlice->getScalingList()->checkDcOfMatrix();
1032      m_pcEncTop->getSPS()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList());
1033      m_pcEncTop->getPPS()->setScalingListPresentFlag(false);
1034
1035#if SCALINGLIST_INFERRING
1036    }
1037#endif
1038
1039      m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
1040      m_pcEncTop->getTrQuant()->setUseScalingList(true);
1041    }
1042    else
1043    {
1044      printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId());
1045      assert(0);
1046    }
1047
1048    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='P')
1049    {
1050      pcSlice->setSliceType(P_SLICE);
1051    }
1052    if(pcSlice->getSliceType()==B_SLICE&&m_pcCfg->getGOPEntry(iGOPid).m_sliceType=='I')
1053    {
1054      pcSlice->setSliceType(I_SLICE);
1055    }
1056
1057    // Set the nal unit type
1058    pcSlice->setNalUnitType(getNalUnitType(pocCurr, m_iLastIDR, isField));
1059#if SVC_EXTENSION
1060    if (m_layerId > 0)
1061    {
1062      Int interLayerPredLayerIdcTmp[MAX_VPS_LAYER_ID_PLUS1];
1063      Int activeNumILRRefIdxTmp = 0;
1064
1065      for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
1066      {
1067        UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
1068        UInt refLayerId = pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc);
1069#if VPS_EXTN_DIRECT_REF_LAYERS
1070        TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId]->getRefLayerEnc(refLayerIdc)->getListPic();
1071#else
1072        TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId-1]->getListPic();
1073#endif
1074        pcSlice->setBaseColPic( *cListPic, refLayerIdc );
1075
1076        // Apply temporal layer restriction to inter-layer prediction
1077#if O0225_MAX_TID_FOR_REF_LAYERS
1078        Int maxTidIlRefPicsPlus1 = m_pcEncTop->getVPS()->getMaxTidIlRefPicsPlus1(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getLayerId(),m_layerId);
1079#else
1080        Int maxTidIlRefPicsPlus1 = m_pcEncTop->getVPS()->getMaxTidIlRefPicsPlus1(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getLayerId());
1081#endif
1082        if( ((Int)(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getTLayer())<=maxTidIlRefPicsPlus1-1) || (maxTidIlRefPicsPlus1==0 && pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getRapPicFlag()) )
1083        {
1084          interLayerPredLayerIdcTmp[activeNumILRRefIdxTmp++] = refLayerIdc; // add picture to the list of valid inter-layer pictures
1085        }
1086        else
1087        {
1088          continue; // ILP is not valid due to temporal layer restriction
1089        }
1090
1091#if O0098_SCALED_REF_LAYER_ID
1092        const Window &scalEL = m_pcEncTop->getScaledRefLayerWindowForLayer(refLayerId);
1093#else
1094        const Window &scalEL = m_pcEncTop->getScaledRefLayerWindow(refLayerIdc);
1095#endif
1096
1097        Int widthBL   = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getWidth();
1098        Int heightBL  = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getHeight();
1099#if Q0200_CONFORMANCE_BL_SIZE
1100        Int chromaFormatIdc = pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getChromaFormatIdc();
1101        const Window &confBL = pcSlice->getBaseColPic(refLayerIdc)->getConformanceWindow();
1102        widthBL  -= ( confBL.getWindowLeftOffset() + confBL.getWindowRightOffset() ) * TComSPS::getWinUnitX( chromaFormatIdc );
1103        heightBL -= ( confBL.getWindowTopOffset() + confBL.getWindowBottomOffset() ) * TComSPS::getWinUnitY( chromaFormatIdc );
1104#endif
1105        Int widthEL   = pcPic->getPicYuvRec()->getWidth()  - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset();
1106        Int heightEL  = pcPic->getPicYuvRec()->getHeight() - scalEL.getWindowTopOffset()  - scalEL.getWindowBottomOffset();
1107
1108        g_mvScalingFactor[refLayerIdc][0] = widthEL  == widthBL  ? 4096 : Clip3(-4096, 4095, ((widthEL  << 8) + (widthBL  >> 1)) / widthBL);
1109        g_mvScalingFactor[refLayerIdc][1] = heightEL == heightBL ? 4096 : Clip3(-4096, 4095, ((heightEL << 8) + (heightBL >> 1)) / heightBL);
1110
1111        g_posScalingFactor[refLayerIdc][0] = ((widthBL  << 16) + (widthEL  >> 1)) / widthEL;
1112        g_posScalingFactor[refLayerIdc][1] = ((heightBL << 16) + (heightEL >> 1)) / heightEL;
1113
1114#if Q0048_CGS_3D_ASYMLUT
1115        TComPicYuv* pBaseColRec = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
1116        if( pcSlice->getPPS()->getCGSFlag() )
1117        {
1118          if(g_posScalingFactor[refLayerIdc][0] < (1<<16) || g_posScalingFactor[refLayerIdc][1] < (1<<16)) //if(pcPic->isSpatialEnhLayer(refLayerIdc))
1119          {
1120            //downsampling;
1121            downScalePic(pcPic->getPicYuvOrg(), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1122            //pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg()->dump("ds.yuv", true, true);
1123            m_Enc3DAsymLUTPPS.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1124            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
1125          }
1126          else
1127          {
1128            m_Enc3DAsymLUTPPS.setDsOrigPic(pcPic->getPicYuvOrg());
1129            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcPic->getPicYuvOrg());
1130          }
1131
1132          Bool bSignalPPS = m_bSeqFirst;
1133          bSignalPPS |= m_pcCfg->getGOPSize() > 1 ? pocCurr % m_pcCfg->getIntraPeriod() == 0 : pocCurr % m_pcCfg->getFrameRate() == 0;
1134          xDetermin3DAsymLUT( pcSlice , pcPic , refLayerIdc , m_pcCfg , bSignalPPS );
1135          m_Enc3DAsymLUTPPS.colorMapping( pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(),  m_pColorMappedPic );
1136          pBaseColRec = m_pColorMappedPic;
1137        }
1138#endif
1139#if SVC_EXTENSION
1140        if( pcPic->isSpatialEnhLayer(refLayerIdc) )
1141        {
1142          // check for the sample prediction picture type
1143          if( m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag(refLayerId) )
1144          {
1145#if P0312_VERT_PHASE_ADJ
1146            //when PhasePositionEnableFlag is equal to 1, set vertPhasePositionFlag to 0 if BL is top field and 1 if bottom
1147            if( scalEL.getVertPhasePositionEnableFlag() )
1148            {
1149              pcSlice->setVertPhasePositionFlag( pcSlice->getPOC()%2, refLayerIdc );
1150            }
1151#endif
1152#if O0215_PHASE_ALIGNMENT
1153#if O0194_JOINT_US_BITSHIFT
1154#if Q0048_CGS_3D_ASYMLUT
1155            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), pcSlice->getVPS()->getPhaseAlignFlag() );
1156#else
1157            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), pcSlice->getVPS()->getPhaseAlignFlag() );
1158#endif
1159#else
1160#if Q0048_CGS_3D_ASYMLUT
1161            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
1162#else
1163            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
1164#endif
1165#endif
1166#else
1167#if O0194_JOINT_US_BITSHIFT
1168#if Q0048_CGS_3D_ASYMLUT
1169            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
1170#else
1171            m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
1172#endif
1173#else
1174#if Q0048_CGS_3D_ASYMLUT
1175            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
1176#else
1177            m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
1178#endif
1179#endif
1180#endif
1181          }
1182        }
1183        else
1184        {
1185#if Q0048_CGS_3D_ASYMLUT
1186          pcPic->setFullPelBaseRec( refLayerIdc, pBaseColRec );
1187#else
1188          pcPic->setFullPelBaseRec( refLayerIdc, pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec() );
1189#endif
1190        }
1191        pcSlice->setFullPelBaseRec ( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc) );
1192#endif //SVC_EXTENSION
1193      }
1194
1195      // Update the list of active inter-layer pictures
1196      for ( Int i = 0; i < activeNumILRRefIdxTmp; i++)
1197      {
1198        pcSlice->setInterLayerPredLayerIdc( interLayerPredLayerIdcTmp[i], i );
1199      }
1200
1201#if !O0225_TID_BASED_IL_RPS_DERIV || Q0060_MAX_TID_REF_EQUAL_TO_ZERO
1202      pcSlice->setActiveNumILRRefIdx( activeNumILRRefIdxTmp );
1203#endif
1204      if ( pcSlice->getActiveNumILRRefIdx() == 0 )
1205      {
1206        // No valid inter-layer pictures -> disable inter-layer prediction
1207        pcSlice->setInterLayerPredEnabledFlag(false);
1208      }
1209
1210      if( pocCurr % m_pcCfg->getIntraPeriod() == 0 )
1211      {
1212        if(pcSlice->getVPS()->getCrossLayerIrapAlignFlag())
1213        {
1214          TComList<TComPic*> *cListPic = m_ppcTEncTop[m_layerId]->getRefLayerEnc(0)->getListPic();
1215          TComPic* picLayer0 = pcSlice->getRefPic(*cListPic, pcSlice->getPOC() );
1216          if(picLayer0)
1217          {
1218            pcSlice->setNalUnitType(picLayer0->getSlice(0)->getNalUnitType());
1219          }
1220          else
1221          {
1222            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA);
1223          }
1224        }
1225        else
1226        {
1227          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_CRA);
1228        }
1229      }
1230
1231      if( pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
1232      {
1233        pcSlice->setSliceType(I_SLICE);
1234      }
1235      else if( !m_pcEncTop->getElRapSliceTypeB() )
1236      {
1237        if( (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP) &&
1238          (pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA) &&
1239          pcSlice->getSliceType() == B_SLICE )
1240        {
1241          pcSlice->setSliceType(P_SLICE);
1242        }
1243      }     
1244    }
1245#endif //#if SVC_EXTENSION
1246    if(pcSlice->getTemporalLayerNonReferenceFlag())
1247    {
1248      if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_TRAIL_R &&
1249          !(m_iGopSize == 1 && pcSlice->getSliceType() == I_SLICE))
1250        // Add this condition to avoid POC issues with encoder_intra_main.cfg configuration (see #1127 in bug tracker)
1251      {
1252        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TRAIL_N);
1253    }
1254      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RADL_R)
1255      {
1256        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RADL_N);
1257      }
1258      if(pcSlice->getNalUnitType()==NAL_UNIT_CODED_SLICE_RASL_R)
1259      {
1260        pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_RASL_N);
1261      }
1262    }
1263
1264#if EFFICIENT_FIELD_IRAP
1265#if FIX1172
1266    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1267      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1268      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1269      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1270      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1271      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
1272    {
1273      m_associatedIRAPType = pcSlice->getNalUnitType();
1274      m_associatedIRAPPOC = pocCurr;
1275    }
1276    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
1277    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
1278#endif
1279#endif
1280    // Do decoding refresh marking if any
1281#if NO_CLRAS_OUTPUT_FLAG
1282    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcEncTop->getNoClrasOutputFlag());
1283#else
1284    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
1285#endif
1286    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
1287    pcSlice->getRPS()->setNumberOfLongtermPictures(0);
1288#if EFFICIENT_FIELD_IRAP
1289#else
1290#if FIX1172
1291    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
1292      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
1293      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
1294      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
1295      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
1296      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
1297    {
1298      m_associatedIRAPType = pcSlice->getNalUnitType();
1299      m_associatedIRAPPOC = pocCurr;
1300    }
1301    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
1302    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
1303#endif
1304#endif
1305
1306#if ALLOW_RECOVERY_POINT_AS_RAP
1307    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) 
1308#if EFFICIENT_FIELD_IRAP
1309      || (isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)
1310#endif
1311      )
1312    {
1313      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3);
1314    }
1315#else
1316    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0) || (pcSlice->isIRAP()))
1317    {
1318      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP());
1319    }
1320#endif
1321#if ALIGNED_BUMPING
1322    pcSlice->checkLeadingPictureRestrictions(rcListPic);
1323#endif
1324    pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
1325
1326    if(pcSlice->getTLayer() > 0 
1327      &&  !( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_N     // Check if not a leading picture
1328          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL_R
1329          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_N
1330          || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RASL_R )
1331        )
1332    {
1333      if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic) || pcSlice->getSPS()->getTemporalIdNestingFlag())
1334      {
1335#if SVC_EXTENSION
1336        // Alignment of TSA pictures across AU
1337        if( pcSlice->getLayerId() > 0 )
1338        {
1339          Bool oneRefLayerTSA = false, oneRefLayerNotTSA = false;
1340          for( Int i = 0; i < pcSlice->getLayerId(); i++)
1341          {
1342            TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic();
1343            TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC());
1344            if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) )
1345            {
1346              if( ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_N ) ||
1347                  ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_TSA_R ) 
1348                )
1349              {
1350                if(pcSlice->getTemporalLayerNonReferenceFlag() )
1351                {
1352                  pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1353                }
1354                else
1355                {
1356                  pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R );
1357                }
1358                oneRefLayerTSA = true;
1359              }
1360              else
1361              {
1362                oneRefLayerNotTSA = true;
1363              }
1364            }
1365          }
1366          assert( !( oneRefLayerNotTSA && oneRefLayerTSA ) ); // Only one variable should be true - failure of this assert means
1367                                                                // that two independent reference layers that are not dependent on
1368                                                                // each other, but are reference for current layer have inconsistency
1369          if( oneRefLayerNotTSA /*&& !oneRefLayerTSA*/ )          // No reference layer is TSA - set current as TRAIL
1370          {
1371            if(pcSlice->getTemporalLayerNonReferenceFlag() )
1372            {
1373              pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_N );
1374            }
1375            else
1376            {
1377              pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_R );
1378            }
1379          }
1380          else  // This means there is no reference layer picture for current picture in this AU
1381          {
1382            if(pcSlice->getTemporalLayerNonReferenceFlag() )
1383            {
1384              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1385            }
1386            else
1387            {
1388              pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R );
1389            }
1390          }
1391        }
1392#else  //SVC_EXTENSION
1393        if(pcSlice->getTemporalLayerNonReferenceFlag())
1394        {
1395          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_N);
1396        }
1397        else
1398        {
1399          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TSA_R);
1400        }
1401#endif //SVC_EXTENSION
1402      }
1403      else if(pcSlice->isStepwiseTemporalLayerSwitchingPointCandidate(rcListPic))
1404      {
1405        Bool isSTSA=true;
1406        for(Int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++)
1407        {
1408          Int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId;
1409          if(lTid==pcSlice->getTLayer()) 
1410          {
1411            TComReferencePictureSet* nRPS = pcSlice->getSPS()->getRPSList()->getReferencePictureSet(ii);
1412            for(Int jj=0;jj<nRPS->getNumberOfPictures();jj++)
1413            {
1414              if(nRPS->getUsed(jj)) 
1415              {
1416                Int tPoc=m_pcCfg->getGOPEntry(ii).m_POC+nRPS->getDeltaPOC(jj);
1417                Int kk=0;
1418                for(kk=0;kk<m_pcCfg->getGOPSize();kk++)
1419                {
1420                  if(m_pcCfg->getGOPEntry(kk).m_POC==tPoc)
1421                    break;
1422                }
1423                Int tTid=m_pcCfg->getGOPEntry(kk).m_temporalId;
1424                if(tTid >= pcSlice->getTLayer())
1425                {
1426                  isSTSA=false;
1427                  break;
1428                }
1429              }
1430            }
1431          }
1432        }
1433        if(isSTSA==true)
1434        {   
1435#if SVC_EXTENSION
1436          // Alignment of STSA pictures across AU
1437          if( pcSlice->getLayerId() > 0 )
1438          {
1439            Bool oneRefLayerSTSA = false, oneRefLayerNotSTSA = false;
1440            for( Int i = 0; i < pcSlice->getLayerId(); i++)
1441            {
1442              TComList<TComPic *> *cListPic = m_ppcTEncTop[i]->getListPic();
1443              TComPic *lowerLayerPic = pcSlice->getRefPic(*cListPic, pcSlice->getPOC());
1444              if( lowerLayerPic && pcSlice->getVPS()->getDirectDependencyFlag(pcSlice->getLayerId(), i) )
1445              {
1446                if( ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA_N ) ||
1447                    ( lowerLayerPic->getSlice(0)->getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA_R ) 
1448                  )
1449                {
1450                  if(pcSlice->getTemporalLayerNonReferenceFlag() )
1451                  {
1452                    pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1453                  }
1454                  else
1455                  {
1456                    pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R );
1457                  }
1458                  oneRefLayerSTSA = true;
1459                }
1460                else
1461                {
1462                  oneRefLayerNotSTSA = true;
1463                }
1464              }
1465            }
1466            assert( !( oneRefLayerNotSTSA && oneRefLayerSTSA ) ); // Only one variable should be true - failure of this assert means
1467                                                                  // that two independent reference layers that are not dependent on
1468                                                                  // each other, but are reference for current layer have inconsistency
1469            if( oneRefLayerNotSTSA /*&& !oneRefLayerSTSA*/ )          // No reference layer is STSA - set current as TRAIL
1470            {
1471              if(pcSlice->getTemporalLayerNonReferenceFlag() )
1472              {
1473                pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_N );
1474              }
1475              else
1476              {
1477                pcSlice->setNalUnitType( NAL_UNIT_CODED_SLICE_TRAIL_R );
1478              }
1479            }
1480            else  // This means there is no reference layer picture for current picture in this AU
1481            {
1482              if(pcSlice->getTemporalLayerNonReferenceFlag() )
1483              {
1484                pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1485              }
1486              else
1487              {
1488                pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R );
1489              }
1490            }
1491          }
1492#else  //SVC_EXTENSION
1493          if(pcSlice->getTemporalLayerNonReferenceFlag())
1494          {
1495            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_N);
1496          }
1497          else
1498          {
1499            pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_STSA_R);
1500          }
1501#endif //SVC_EXTENSION
1502        }
1503      }
1504    }
1505    arrangeLongtermPicturesInRPS(pcSlice, rcListPic);
1506    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
1507    refPicListModification->setRefPicListModificationFlagL0(0);
1508    refPicListModification->setRefPicListModificationFlagL1(0);
1509    pcSlice->setNumRefIdx(REF_PIC_LIST_0,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
1510    pcSlice->setNumRefIdx(REF_PIC_LIST_1,min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive,pcSlice->getRPS()->getNumberOfPictures()));
1511
1512#if SVC_EXTENSION
1513    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
1514    {
1515#if POC_RESET_FLAG
1516      if ( pocCurr > 0          && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL())
1517#else
1518      if (pcSlice->getPOC()>0  && pcSlice->isRADL() && pcPic->getSlice(0)->getBaseColPic(pcPic->getSlice(0)->getInterLayerPredLayerIdc(0))->getSlice(0)->isRASL())
1519#endif
1520      {
1521        pcSlice->setActiveNumILRRefIdx(0);
1522        pcSlice->setInterLayerPredEnabledFlag(0);
1523      }
1524      if( pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
1525      {
1526        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getActiveNumILRRefIdx());
1527        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getActiveNumILRRefIdx());
1528      }
1529      else
1530      {
1531        pcSlice->setNumRefIdx(REF_PIC_LIST_0, pcSlice->getNumRefIdx(REF_PIC_LIST_0)+pcSlice->getActiveNumILRRefIdx());
1532        pcSlice->setNumRefIdx(REF_PIC_LIST_1, pcSlice->getNumRefIdx(REF_PIC_LIST_1)+pcSlice->getActiveNumILRRefIdx());
1533      }
1534
1535      // check for the reference pictures whether there is at least one either temporal picture or ILRP with sample prediction type
1536      if( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) - pcSlice->getActiveNumILRRefIdx() == 0 && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) - pcSlice->getActiveNumILRRefIdx() == 0 )
1537      {
1538        Bool foundSamplePredPicture = false;               
1539
1540        for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
1541        {
1542          if( m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( pcSlice->getVPS()->getRefLayerId( m_layerId, pcSlice->getInterLayerPredLayerIdc(i) ) ) )
1543          {
1544            foundSamplePredPicture = true;
1545            break;
1546          }
1547        }
1548
1549        if( !foundSamplePredPicture )
1550        {
1551          pcSlice->setSliceType(I_SLICE);
1552          pcSlice->setInterLayerPredEnabledFlag(0);
1553          pcSlice->setActiveNumILRRefIdx(0);
1554        }
1555      }
1556    }
1557#endif //SVC_EXTENSION
1558
1559#if ADAPTIVE_QP_SELECTION
1560    pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
1561#endif     
1562
1563#if SVC_EXTENSION
1564    if( pcSlice->getSliceType() == B_SLICE )
1565    {
1566      pcSlice->setColFromL0Flag(1-uiColDir);
1567    }
1568
1569    //  Set reference list
1570    if(m_layerId ==  0 || ( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() == 0 ) )
1571    {
1572      pcSlice->setRefPicList( rcListPic);
1573    }
1574
1575    if( m_layerId > 0 && pcSlice->getActiveNumILRRefIdx() )
1576    {
1577      pcSlice->setILRPic( m_pcEncTop->getIlpList() );
1578#if REF_IDX_MFM
1579      if( pcSlice->getMFMEnabledFlag() )
1580      {
1581        pcSlice->setRefPOCListILP(m_pcEncTop->getIlpList(), pcSlice->getBaseColPic());
1582      }
1583#else
1584      //  Set reference list
1585      pcSlice->setRefPicList ( rcListPic );
1586#endif
1587      pcSlice->setRefPicListModificationSvc();
1588      pcSlice->setRefPicList( rcListPic, false, m_pcEncTop->getIlpList());
1589
1590#if REF_IDX_MFM
1591      if( pcSlice->getMFMEnabledFlag() )
1592      {
1593        Bool found         = false;
1594        UInt ColFromL0Flag = pcSlice->getColFromL0Flag();
1595        UInt ColRefIdx     = pcSlice->getColRefIdx();
1596
1597        for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
1598        {
1599          RefPicList refList = RefPicList(1 - ColFromL0Flag);
1600          TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
1601
1602          // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
1603          // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
1604          if( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag( refPic->getLayerId() )
1605#if MFM_ENCCONSTRAINT
1606            && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerId()]->getListPic() )->checkSameRefInfo() == true 
1607#endif
1608            ) 
1609          { 
1610            ColRefIdx = colIdx; 
1611            found = true;
1612            break; 
1613          }
1614        }
1615
1616        if( found == false )
1617        {
1618          ColFromL0Flag = 1 - ColFromL0Flag;
1619          for(Int colIdx = 0; colIdx < pcSlice->getNumRefIdx( RefPicList(1 - ColFromL0Flag) ); colIdx++) 
1620          {
1621            RefPicList refList = RefPicList(1 - ColFromL0Flag);
1622            TComPic* refPic = pcSlice->getRefPic(refList, colIdx);
1623
1624            // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
1625            // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
1626            if( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag( refPic->getLayerId() )
1627#if MFM_ENCCONSTRAINT
1628              && pcSlice->getBaseColPic( *m_ppcTEncTop[refPic->getLayerId()]->getListPic() )->checkSameRefInfo() == true 
1629#endif
1630              ) 
1631            { 
1632              ColRefIdx = colIdx; 
1633              found = true; 
1634              break; 
1635            } 
1636          }
1637        }
1638
1639        if(found == true)
1640        {
1641          pcSlice->setColFromL0Flag(ColFromL0Flag);
1642          pcSlice->setColRefIdx(ColRefIdx);
1643        }
1644      }
1645#endif
1646    }
1647#else //SVC_EXTENSION
1648    //  Set reference list
1649    pcSlice->setRefPicList ( rcListPic );
1650#endif //#if SVC_EXTENSION
1651
1652    //  Slice info. refinement
1653    if ( (pcSlice->getSliceType() == B_SLICE) && (pcSlice->getNumRefIdx(REF_PIC_LIST_1) == 0) )
1654    {
1655      pcSlice->setSliceType ( P_SLICE );
1656    }
1657
1658    if (pcSlice->getSliceType() == B_SLICE)
1659    {
1660#if !SVC_EXTENSION
1661      pcSlice->setColFromL0Flag(1-uiColDir);
1662#endif
1663      Bool bLowDelay = true;
1664      Int  iCurrPOC  = pcSlice->getPOC();
1665      Int iRefIdx = 0;
1666
1667      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
1668      {
1669        if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
1670        {
1671          bLowDelay = false;
1672        }
1673      }
1674      for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
1675      {
1676        if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
1677        {
1678          bLowDelay = false;
1679        }
1680      }
1681
1682      pcSlice->setCheckLDC(bLowDelay); 
1683    }
1684    else
1685    {
1686      pcSlice->setCheckLDC(true); 
1687    }
1688
1689    uiColDir = 1-uiColDir;
1690
1691    //-------------------------------------------------------------
1692    pcSlice->setRefPOCList();
1693
1694    pcSlice->setList1IdxToList0Idx();
1695
1696    if (m_pcEncTop->getTMVPModeId() == 2)
1697    {
1698      if (iGOPid == 0) // first picture in SOP (i.e. forward B)
1699      {
1700        pcSlice->setEnableTMVPFlag(0);
1701      }
1702      else
1703      {
1704        // Note: pcSlice->getColFromL0Flag() is assumed to be always 0 and getcolRefIdx() is always 0.
1705        pcSlice->setEnableTMVPFlag(1);
1706      }
1707      pcSlice->getSPS()->setTMVPFlagsPresent(1);
1708    }
1709    else if (m_pcEncTop->getTMVPModeId() == 1)
1710    {
1711      pcSlice->getSPS()->setTMVPFlagsPresent(1);
1712#if SVC_EXTENSION
1713      if( pcSlice->getIdrPicFlag() )
1714      {
1715        pcSlice->setEnableTMVPFlag(0);
1716      }
1717      else
1718#endif
1719      pcSlice->setEnableTMVPFlag(1);
1720    }
1721    else
1722    {
1723      pcSlice->getSPS()->setTMVPFlagsPresent(0);
1724      pcSlice->setEnableTMVPFlag(0);
1725    }
1726
1727#if SVC_EXTENSION
1728    if( m_layerId > 0 && !pcSlice->isIntra() )
1729    {
1730      Int colFromL0Flag = 1;
1731      Int colRefIdx = 0;
1732
1733      // check whether collocated picture is valid
1734      if( pcSlice->getEnableTMVPFlag() )
1735      {
1736        colFromL0Flag = pcSlice->getColFromL0Flag();
1737        colRefIdx = pcSlice->getColRefIdx();
1738
1739        TComPic* refPic = pcSlice->getRefPic(RefPicList(1-colFromL0Flag), colRefIdx);
1740
1741        assert( refPic );
1742
1743        // It is a requirement of bitstream conformance when the collocated picture, used for temporal motion vector prediction, is an inter-layer reference picture,
1744        // VpsInterLayerMotionPredictionEnabled[ LayerIdxInVps[ currLayerId ] ][ LayerIdxInVps[ rLId ] ] shall be equal to 1, where rLId is set equal to nuh_layer_id of the inter-layer picture.
1745        if( refPic->isILR(m_layerId) && !m_ppcTEncTop[m_layerId]->getMotionPredEnabledFlag(refPic->getLayerId()) )
1746        {
1747          pcSlice->setEnableTMVPFlag(false);
1748          pcSlice->setMFMEnabledFlag(false);
1749          colRefIdx = 0;
1750        }
1751      }
1752
1753      // remove motion only ILRP from the end of the colFromL0Flag reference picture list
1754      RefPicList refList = RefPicList(colFromL0Flag);
1755      Int numRefIdx = pcSlice->getNumRefIdx(refList);
1756
1757      if( numRefIdx > 0 )
1758      {
1759        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > 0; refIdx-- )
1760        {
1761          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
1762
1763          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( refPic->getLayerId() ) ) )
1764          {
1765            break;
1766          }
1767          else
1768          {
1769            assert( numRefIdx > 1 );
1770            numRefIdx--;             
1771          }
1772        }
1773
1774        pcSlice->setNumRefIdx( refList, numRefIdx );
1775      }
1776
1777      // remove motion only ILRP from the end of the (1-colFromL0Flag) reference picture list up to colRefIdx
1778      refList = RefPicList(1 - colFromL0Flag);
1779      numRefIdx = pcSlice->getNumRefIdx(refList);
1780
1781      if( numRefIdx > 0 )
1782      {
1783        for( Int refIdx = pcSlice->getNumRefIdx(refList) - 1; refIdx > colRefIdx; refIdx-- )
1784        {
1785          TComPic* refPic = pcSlice->getRefPic(refList, refIdx);
1786
1787          if( !refPic->isILR(m_layerId) || ( refPic->isILR(m_layerId) && m_ppcTEncTop[m_layerId]->getSamplePredEnabledFlag( refPic->getLayerId() ) ) )
1788          {
1789            break;
1790          }
1791          else
1792          {
1793            assert( numRefIdx > 1 );
1794            numRefIdx--;             
1795          }
1796        }
1797
1798        pcSlice->setNumRefIdx( refList, numRefIdx );
1799      }
1800
1801      assert( pcSlice->getNumRefIdx(REF_PIC_LIST_0) > 0 && ( pcSlice->isInterP() || (pcSlice->isInterB() && pcSlice->getNumRefIdx(REF_PIC_LIST_1) > 0) ) );
1802    }
1803#endif
1804
1805    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
1806    //  Slice compression
1807    if (m_pcCfg->getUseASR())
1808    {
1809      m_pcSliceEncoder->setSearchRange(pcSlice);
1810    }
1811
1812    Bool bGPBcheck=false;
1813    if ( pcSlice->getSliceType() == B_SLICE)
1814    {
1815      if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
1816      {
1817        bGPBcheck=true;
1818        Int i;
1819        for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
1820        {
1821          if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
1822          {
1823            bGPBcheck=false;
1824            break;
1825          }
1826        }
1827      }
1828    }
1829    if(bGPBcheck)
1830    {
1831      pcSlice->setMvdL1ZeroFlag(true);
1832    }
1833    else
1834    {
1835      pcSlice->setMvdL1ZeroFlag(false);
1836    }
1837    pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
1838
1839    Double lambda            = 0.0;
1840    Int actualHeadBits       = 0;
1841    Int actualTotalBits      = 0;
1842    Int estimatedBits        = 0;
1843    Int tmpBitsBeforeWriting = 0;
1844    if ( m_pcCfg->getUseRateCtrl() )
1845    {
1846      Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
1847      if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
1848      {
1849        frameLevel = 0;
1850      }
1851      m_pcRateCtrl->initRCPic( frameLevel );
1852      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
1853
1854      Int sliceQP = m_pcCfg->getInitialQP();
1855#if POC_RESET_FLAG
1856      if ( ( pocCurr == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
1857#else
1858      if ( ( pcSlice->getPOC() == 0 && m_pcCfg->getInitialQP() > 0 ) || ( frameLevel == 0 && m_pcCfg->getForceIntraQP() ) ) // QP is specified
1859#endif
1860      {
1861        Int    NumberBFrames = ( m_pcCfg->getGOPSize() - 1 );
1862        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)NumberBFrames );
1863        Double dQPFactor     = 0.57*dLambda_scale;
1864        Int    SHIFT_QP      = 12;
1865        Int    bitdepth_luma_qp_scale = 0;
1866        Double qp_temp = (Double) sliceQP + bitdepth_luma_qp_scale - SHIFT_QP;
1867        lambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
1868      }
1869      else if ( frameLevel == 0 )   // intra case, but use the model
1870      {
1871        m_pcSliceEncoder->calCostSliceI(pcPic);
1872        if ( m_pcCfg->getIntraPeriod() != 1 )   // do not refine allocated bits for all intra case
1873        {
1874          Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
1875          bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
1876          if ( bits < 200 )
1877          {
1878            bits = 200;
1879          }
1880          m_pcRateCtrl->getRCPic()->setTargetBits( bits );
1881        }
1882
1883        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1884        m_pcRateCtrl->getRCPic()->getLCUInitTargetBits();
1885        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
1886        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1887      }
1888      else    // normal case
1889      {
1890        list<TEncRCPic*> listPreviousPicture = m_pcRateCtrl->getPicList();
1891        lambda  = m_pcRateCtrl->getRCPic()->estimatePicLambda( listPreviousPicture, pcSlice->getSliceType());
1892        sliceQP = m_pcRateCtrl->getRCPic()->estimatePicQP( lambda, listPreviousPicture );
1893      }
1894
1895#if REPN_FORMAT_IN_VPS
1896      sliceQP = Clip3( -pcSlice->getQpBDOffsetY(), MAX_QP, sliceQP );
1897#else
1898      sliceQP = Clip3( -pcSlice->getSPS()->getQpBDOffsetY(), MAX_QP, sliceQP );
1899#endif
1900      m_pcRateCtrl->getRCPic()->setPicEstQP( sliceQP );
1901
1902      m_pcSliceEncoder->resetQP( pcPic, sliceQP, lambda );
1903    }
1904
1905    UInt uiNumSlices = 1;
1906
1907    UInt uiInternalAddress = pcPic->getNumPartInCU()-4;
1908    UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1;
1909    UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1910    UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1911#if REPN_FORMAT_IN_VPS
1912    UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
1913    UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
1914#else
1915    UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
1916    UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
1917#endif
1918    while(uiPosX>=uiWidth||uiPosY>=uiHeight) 
1919    {
1920      uiInternalAddress--;
1921      uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
1922      uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
1923    }
1924    uiInternalAddress++;
1925    if(uiInternalAddress==pcPic->getNumPartInCU()) 
1926    {
1927      uiInternalAddress = 0;
1928      uiExternalAddress++;
1929    }
1930    UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress;
1931
1932    UInt uiCummulativeTileWidth;
1933    UInt uiCummulativeTileHeight;
1934    Int  p, j;
1935    UInt uiEncCUAddr;
1936
1937    //set NumColumnsMinus1 and NumRowsMinus1
1938    pcPic->getPicSym()->setNumColumnsMinus1( pcSlice->getPPS()->getNumColumnsMinus1() );
1939    pcPic->getPicSym()->setNumRowsMinus1( pcSlice->getPPS()->getNumRowsMinus1() );
1940
1941    //create the TComTileArray
1942    pcPic->getPicSym()->xCreateTComTileArray();
1943
1944    if( pcSlice->getPPS()->getUniformSpacingFlag() == 1 )
1945    {
1946      //set the width for each tile
1947      for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
1948      {
1949        for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1()+1; p++)
1950        {
1951          pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->
1952            setTileWidth( (p+1)*pcPic->getPicSym()->getFrameWidthInCU()/(pcPic->getPicSym()->getNumColumnsMinus1()+1) 
1953            - (p*pcPic->getPicSym()->getFrameWidthInCU())/(pcPic->getPicSym()->getNumColumnsMinus1()+1) );
1954        }
1955      }
1956
1957      //set the height for each tile
1958      for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
1959      {
1960        for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1()+1; p++)
1961        {
1962          pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->
1963            setTileHeight( (p+1)*pcPic->getPicSym()->getFrameHeightInCU()/(pcPic->getPicSym()->getNumRowsMinus1()+1) 
1964            - (p*pcPic->getPicSym()->getFrameHeightInCU())/(pcPic->getPicSym()->getNumRowsMinus1()+1) );   
1965        }
1966      }
1967    }
1968    else
1969    {
1970      //set the width for each tile
1971      for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
1972      {
1973        uiCummulativeTileWidth = 0;
1974        for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1(); p++)
1975        {
1976          pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->setTileWidth( pcSlice->getPPS()->getColumnWidth(p) );
1977          uiCummulativeTileWidth += pcSlice->getPPS()->getColumnWidth(p);
1978        }
1979        pcPic->getPicSym()->getTComTile(j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p)->setTileWidth( pcPic->getPicSym()->getFrameWidthInCU()-uiCummulativeTileWidth );
1980      }
1981
1982      //set the height for each tile
1983      for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
1984      {
1985        uiCummulativeTileHeight = 0;
1986        for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1(); p++)
1987        {
1988          pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->setTileHeight( pcSlice->getPPS()->getRowHeight(p) );
1989          uiCummulativeTileHeight += pcSlice->getPPS()->getRowHeight(p);
1990        }
1991        pcPic->getPicSym()->getTComTile(p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j)->setTileHeight( pcPic->getPicSym()->getFrameHeightInCU()-uiCummulativeTileHeight );
1992      }
1993    }
1994    //intialize each tile of the current picture
1995    pcPic->getPicSym()->xInitTiles();
1996
1997#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
1998    if (m_pcCfg->getInterLayerConstrainedTileSetsSEIEnabled())
1999    {
2000      xBuildTileSetsMap(pcPic->getPicSym());
2001    }
2002#endif
2003
2004    // Allocate some coders, now we know how many tiles there are.
2005    Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
2006
2007    //generate the Coding Order Map and Inverse Coding Order Map
2008    for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
2009    {
2010      pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr);
2011      pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p);
2012    }
2013    pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());   
2014    pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
2015
2016    // Allocate some coders, now we know how many tiles there are.
2017    m_pcEncTop->createWPPCoders(iNumSubstreams);
2018    pcSbacCoders = m_pcEncTop->getSbacCoders();
2019    pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];
2020
2021    UInt startCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
2022    UInt startCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
2023    pcSlice->setSliceCurStartCUAddr( startCUAddrSlice ); // Setting "start CU addr" for current slice
2024    m_storedStartCUAddrForEncodingSlice.clear();
2025
2026    UInt startCUAddrSliceSegmentIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
2027    UInt startCUAddrSliceSegment    = 0; // used to keep track of current Dependent slice's starting CU addr.
2028    pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment ); // Setting "start CU addr" for current Dependent slice
2029
2030    m_storedStartCUAddrForEncodingSliceSegment.clear();
2031    UInt nextCUAddr = 0;
2032    m_storedStartCUAddrForEncodingSlice.push_back (nextCUAddr);
2033    startCUAddrSliceIdx++;
2034    m_storedStartCUAddrForEncodingSliceSegment.push_back(nextCUAddr);
2035    startCUAddrSliceSegmentIdx++;
2036#if AVC_BASE
2037    if( m_layerId == 0 && m_pcEncTop->getVPS()->getAvcBaseLayerFlag() )
2038    {
2039      pcPic->getPicYuvOrg()->copyToPic( pcPic->getPicYuvRec() );
2040#if O0194_WEIGHTED_PREDICTION_CGS
2041      // Calculate for the base layer to be used in EL as Inter layer reference
2042      if( m_pcEncTop->getInterLayerWeightedPredFlag() )
2043      {
2044        m_pcSliceEncoder->estimateILWpParam( pcSlice );
2045      }
2046#endif
2047#if AVC_SYNTAX
2048      pcPic->readBLSyntax( m_ppcTEncTop[0]->getBLSyntaxFile(), SYNTAX_BYTES );
2049#endif
2050      return;
2051    }
2052#endif
2053
2054    while(nextCUAddr<uiRealEndAddress) // determine slice boundaries
2055    {
2056      pcSlice->setNextSlice       ( false );
2057      pcSlice->setNextSliceSegment( false );
2058      assert(pcPic->getNumAllocatedSlice() == startCUAddrSliceIdx);
2059      m_pcSliceEncoder->precompressSlice( pcPic );
2060      m_pcSliceEncoder->compressSlice   ( pcPic );
2061
2062      Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextSliceSegment());
2063      if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU))
2064      {
2065        startCUAddrSlice = pcSlice->getSliceCurEndCUAddr();
2066        // Reconstruction slice
2067        m_storedStartCUAddrForEncodingSlice.push_back(startCUAddrSlice);
2068        startCUAddrSliceIdx++;
2069        // Dependent slice
2070        if (startCUAddrSliceSegmentIdx>0 && m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx-1] != startCUAddrSlice)
2071        {
2072          m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSlice);
2073          startCUAddrSliceSegmentIdx++;
2074        }
2075
2076        if (startCUAddrSlice < uiRealEndAddress)
2077        {
2078          pcPic->allocateNewSlice();         
2079          pcPic->setCurrSliceIdx                  ( startCUAddrSliceIdx-1 );
2080          m_pcSliceEncoder->setSliceIdx           ( startCUAddrSliceIdx-1 );
2081          pcSlice = pcPic->getSlice               ( startCUAddrSliceIdx-1 );
2082          pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
2083          pcSlice->setSliceIdx                    ( startCUAddrSliceIdx-1 );
2084          pcSlice->setSliceCurStartCUAddr         ( startCUAddrSlice      );
2085          pcSlice->setSliceSegmentCurStartCUAddr  ( startCUAddrSlice      );
2086          pcSlice->setSliceBits(0);
2087#if SVC_EXTENSION
2088          // copy reference list modification info from the first slice, assuming that this information is the same across all slices in the picture
2089          memcpy( pcSlice->getRefPicListModification(), pcPic->getSlice(0)->getRefPicListModification(), sizeof(TComRefPicListModification) );
2090#endif
2091          uiNumSlices ++;
2092        }
2093      }
2094      else if (pcSlice->isNextSliceSegment() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU))
2095      {
2096        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
2097        m_storedStartCUAddrForEncodingSliceSegment.push_back(startCUAddrSliceSegment);
2098        startCUAddrSliceSegmentIdx++;
2099        pcSlice->setSliceSegmentCurStartCUAddr( startCUAddrSliceSegment );
2100      }
2101      else
2102      {
2103        startCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
2104        startCUAddrSliceSegment                                                     = pcSlice->getSliceSegmentCurEndCUAddr();
2105      }       
2106
2107      nextCUAddr = (startCUAddrSlice > startCUAddrSliceSegment) ? startCUAddrSlice : startCUAddrSliceSegment;
2108    }
2109    m_storedStartCUAddrForEncodingSlice.push_back( pcSlice->getSliceCurEndCUAddr());
2110    startCUAddrSliceIdx++;
2111    m_storedStartCUAddrForEncodingSliceSegment.push_back(pcSlice->getSliceCurEndCUAddr());
2112    startCUAddrSliceSegmentIdx++;
2113
2114    pcSlice = pcPic->getSlice(0);
2115
2116    // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
2117    if( pcSlice->getSPS()->getUseSAO() && m_pcCfg->getSaoLcuBoundary() )
2118    {
2119      m_pcSAO->getPreDBFStatistics(pcPic);
2120    }
2121    //-- Loop filter
2122    Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
2123    m_pcLoopFilter->setCfg(bLFCrossTileBoundary);
2124    if ( m_pcCfg->getDeblockingFilterMetric() )
2125    {
2126      dblMetric(pcPic, uiNumSlices);
2127    }
2128    m_pcLoopFilter->loopFilterPic( pcPic );
2129
2130    /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
2131    // Set entropy coder
2132    m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2133
2134    /* write various header sets. */
2135    if ( m_bSeqFirst )
2136    {
2137#if SVC_EXTENSION
2138      OutputNALUnit nalu( NAL_UNIT_VPS, 0, 0 ); // The value of nuh_layer_id of VPS NAL unit shall be equal to 0.
2139#if AVC_BASE
2140      if( ( m_layerId == 1 && m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) || ( m_layerId == 0 && !m_pcEncTop->getVPS()->getAvcBaseLayerFlag() ) )
2141#else
2142      if( m_layerId == 0 )
2143#endif
2144      {
2145#else
2146      OutputNALUnit nalu(NAL_UNIT_VPS);
2147#endif
2148#if VPS_VUI_OFFSET
2149      // The following code also calculates the VPS VUI offset
2150#endif
2151#if !P0125_REVERT_VPS_EXTN_OFFSET_TO_RESERVED
2152#if VPS_EXTN_OFFSET_CALC
2153      OutputNALUnit tempNalu(NAL_UNIT_VPS, 0, 0        ); // The value of nuh_layer_id of VPS NAL unit shall be equal to 0.
2154      m_pcEntropyCoder->setBitstream(&tempNalu.m_Bitstream);
2155      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());  // Use to calculate the VPS extension offset
2156#endif
2157#endif
2158      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2159      m_pcEntropyCoder->encodeVPS(m_pcEncTop->getVPS());
2160      writeRBSPTrailingBits(nalu.m_Bitstream);
2161      accessUnit.push_back(new NALUnitEBSP(nalu));
2162      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2163#if SVC_EXTENSION
2164      }
2165#endif
2166
2167#if SVC_EXTENSION
2168      nalu = NALUnit(NAL_UNIT_SPS, 0, m_layerId);
2169#else
2170      nalu = NALUnit(NAL_UNIT_SPS);
2171#endif
2172#if Q0078_ADD_LAYER_SETS
2173      if (m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0)
2174      {
2175        nalu.m_layerId = 0; // For independent base layer rewriting
2176      }
2177#endif
2178      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2179      if (m_bSeqFirst)
2180      {
2181        pcSlice->getSPS()->setNumLongTermRefPicSPS(m_numLongTermRefPicSPS);
2182        for (Int k = 0; k < m_numLongTermRefPicSPS; k++)
2183        {
2184          pcSlice->getSPS()->setLtRefPicPocLsbSps(k, m_ltRefPicPocLsbSps[k]);
2185          pcSlice->getSPS()->setUsedByCurrPicLtSPSFlag(k, m_ltRefPicUsedByCurrPicFlag[k]);
2186        }
2187      }
2188      if( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
2189      {
2190        UInt maxCU = m_pcCfg->getSliceArgument() >> ( pcSlice->getSPS()->getMaxCUDepth() << 1);
2191        UInt numDU = ( m_pcCfg->getSliceMode() == 1 ) ? ( pcPic->getNumCUsInFrame() / maxCU ) : ( 0 );
2192        if( pcPic->getNumCUsInFrame() % maxCU != 0 || numDU == 0 )
2193        {
2194          numDU ++;
2195        }
2196        pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->setNumDU( numDU );
2197        pcSlice->getSPS()->setHrdParameters( m_pcCfg->getFrameRate(), numDU, m_pcCfg->getTargetBitrate(), ( m_pcCfg->getIntraPeriod() > 0 ) );
2198      }
2199      if( m_pcCfg->getBufferingPeriodSEIEnabled() || m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() )
2200      {
2201        pcSlice->getSPS()->getVuiParameters()->setHrdParametersPresentFlag( true );
2202      }
2203#if O0092_0094_DEPENDENCY_CONSTRAINT
2204      assert( pcSlice->getSPS()->getLayerId() == 0 || pcSlice->getSPS()->getLayerId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pcSlice->getSPS()->getLayerId()) );
2205#endif
2206      m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
2207      writeRBSPTrailingBits(nalu.m_Bitstream);
2208      accessUnit.push_back(new NALUnitEBSP(nalu));
2209      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2210
2211#if SVC_EXTENSION
2212      nalu = NALUnit(NAL_UNIT_PPS, 0, m_layerId);
2213#else
2214      nalu = NALUnit(NAL_UNIT_PPS);
2215#endif
2216#if Q0078_ADD_LAYER_SETS
2217      if (m_pcEncTop->getVPS()->getNumDirectRefLayers(m_layerId) == 0 && m_pcEncTop->getVPS()->getNumAddLayerSets() > 0)
2218      {
2219        nalu.m_layerId = 0; // For independent base layer rewriting
2220      }
2221#endif
2222      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2223#if O0092_0094_DEPENDENCY_CONSTRAINT
2224      assert( pcSlice->getPPS()->getPPSId() == 0 || pcSlice->getPPS()->getPPSId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pcSlice->getPPS()->getPPSId()) );
2225#endif
2226      m_pcEntropyCoder->encodePPS(pcSlice->getPPS()
2227#if Q0048_CGS_3D_ASYMLUT
2228        , & m_Enc3DAsymLUTPPS
2229#endif
2230        );
2231      writeRBSPTrailingBits(nalu.m_Bitstream);
2232      accessUnit.push_back(new NALUnitEBSP(nalu));
2233      actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2234
2235      xCreateLeadingSEIMessages(accessUnit, pcSlice->getSPS());
2236
2237#if O0164_MULTI_LAYER_HRD
2238      if (pcSlice->getLayerId() == 0 && m_pcEncTop->getVPS()->getVpsVuiBspHrdPresentFlag())
2239      {
2240        nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, 1);
2241        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2242        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2243        SEIScalableNesting *scalableBspNestingSei = xCreateBspNestingSEI(pcSlice);
2244        m_seiWriter.writeSEImessage(nalu.m_Bitstream, *scalableBspNestingSei, m_pcEncTop->getVPS(), pcSlice->getSPS());
2245        writeRBSPTrailingBits(nalu.m_Bitstream);
2246
2247        UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2248        UInt offsetPosition = m_activeParameterSetSEIPresentInAU
2249          + m_bufferingPeriodSEIPresentInAU
2250          + m_pictureTimingSEIPresentInAU
2251          + m_nestedPictureTimingSEIPresentInAU;  // Insert SEI after APS, BP and PT SEI
2252        AccessUnit::iterator it;
2253        for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2254        {
2255          it++;
2256        }
2257        accessUnit.insert(it, new NALUnitEBSP(nalu));
2258      }
2259#endif
2260
2261      m_bSeqFirst = false;
2262    }
2263#if Q0048_CGS_3D_ASYMLUT
2264    else if( m_pcCfg->getCGSFlag() && pcSlice->getLayerId() && pcSlice->getCGSOverWritePPS() )
2265    {
2266#if SVC_EXTENSION
2267      OutputNALUnit nalu(NAL_UNIT_PPS, 0, m_layerId);
2268#endif
2269
2270      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2271      m_pcEntropyCoder->encodePPS(pcSlice->getPPS() , &m_Enc3DAsymLUTPPS );
2272      writeRBSPTrailingBits(nalu.m_Bitstream);
2273      accessUnit.push_back(new NALUnitEBSP(nalu));
2274    }
2275#endif
2276
2277    if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
2278    {
2279      Int SOPcurrPOC = pocCurr;
2280
2281      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2282      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2283      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2284
2285      SEISOPDescription SOPDescriptionSEI;
2286      SOPDescriptionSEI.m_sopSeqParameterSetId = pcSlice->getSPS()->getSPSId();
2287
2288      UInt i = 0;
2289      UInt prevEntryId = iGOPid;
2290      for (j = iGOPid; j < m_iGopSize; j++)
2291      {
2292        Int deltaPOC = m_pcCfg->getGOPEntry(j).m_POC - m_pcCfg->getGOPEntry(prevEntryId).m_POC;
2293        if ((SOPcurrPOC + deltaPOC) < m_pcCfg->getFramesToBeEncoded())
2294        {
2295          SOPcurrPOC += deltaPOC;
2296          SOPDescriptionSEI.m_sopDescVclNaluType[i] = getNalUnitType(SOPcurrPOC, m_iLastIDR, isField);
2297          SOPDescriptionSEI.m_sopDescTemporalId[i] = m_pcCfg->getGOPEntry(j).m_temporalId;
2298          SOPDescriptionSEI.m_sopDescStRpsIdx[i] = m_pcEncTop->getReferencePictureSetIdxForSOP(pcSlice, SOPcurrPOC, j);
2299          SOPDescriptionSEI.m_sopDescPocDelta[i] = deltaPOC;
2300
2301          prevEntryId = j;
2302          i++;
2303        }
2304      }
2305
2306      SOPDescriptionSEI.m_numPicsInSopMinus1 = i - 1;
2307
2308#if O0164_MULTI_LAYER_HRD
2309      m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
2310#else
2311      m_seiWriter.writeSEImessage( nalu.m_Bitstream, SOPDescriptionSEI, pcSlice->getSPS());
2312#endif
2313      writeRBSPTrailingBits(nalu.m_Bitstream);
2314      accessUnit.push_back(new NALUnitEBSP(nalu));
2315
2316      writeSOP = false;
2317    }
2318#if Q0189_TMVP_CONSTRAINTS
2319   if( m_pcEncTop->getTMVPConstraintsSEIEnabled() == 1 &&
2320      (m_pcEncTop->getTMVPModeId() == 1 || m_pcEncTop->getTMVPModeId() == 2) &&
2321      pcSlice->getLayerId() >0 && 
2322      (pcSlice->getNalUnitType() ==  NAL_UNIT_CODED_SLICE_IDR_W_RADL || pcSlice->getNalUnitType() ==  NAL_UNIT_CODED_SLICE_IDR_N_LP))
2323   {
2324      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2325      SEITMVPConstrains seiTMVPConstrains;
2326      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2327      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2328      seiTMVPConstrains.no_intra_layer_col_pic_flag = 1;
2329      seiTMVPConstrains.prev_pics_not_used_flag = 1;
2330#if   O0164_MULTI_LAYER_HRD
2331      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiTMVPConstrains, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2332#else
2333      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiTMVPConstrains, pcSlice->getSPS() );
2334#endif
2335      writeRBSPTrailingBits(nalu.m_Bitstream);
2336      accessUnit.push_back(new NALUnitEBSP(nalu));
2337   }
2338#endif
2339#if Q0247_FRAME_FIELD_INFO
2340    if(  pcSlice->getLayerId()> 0 &&
2341     ( (m_pcCfg->getProgressiveSourceFlag() && m_pcCfg->getInterlacedSourceFlag()) || m_pcCfg->getFrameFieldInfoPresentFlag()))
2342    {
2343      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2344      SEIFrameFieldInfo seiFFInfo;
2345      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2346      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2347      seiFFInfo.m_ffinfo_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
2348#if   O0164_MULTI_LAYER_HRD
2349      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiFFInfo, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2350#else
2351      m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiFFInfo, pcSlice->getSPS() );
2352#endif
2353      writeRBSPTrailingBits(nalu.m_Bitstream);
2354      accessUnit.push_back(new NALUnitEBSP(nalu));
2355    }
2356#endif
2357
2358    if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2359        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2360        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
2361       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
2362    {
2363      if( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() )
2364      {
2365        UInt numDU = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNumDU();
2366        pictureTimingSEI.m_numDecodingUnitsMinus1     = ( numDU - 1 );
2367        pictureTimingSEI.m_duCommonCpbRemovalDelayFlag = false;
2368
2369        if( pictureTimingSEI.m_numNalusInDuMinus1 == NULL )
2370        {
2371          pictureTimingSEI.m_numNalusInDuMinus1       = new UInt[ numDU ];
2372        }
2373        if( pictureTimingSEI.m_duCpbRemovalDelayMinus1  == NULL )
2374        {
2375          pictureTimingSEI.m_duCpbRemovalDelayMinus1  = new UInt[ numDU ];
2376        }
2377        if( accumBitsDU == NULL )
2378        {
2379          accumBitsDU                                  = new UInt[ numDU ];
2380        }
2381        if( accumNalsDU == NULL )
2382        {
2383          accumNalsDU                                  = new UInt[ numDU ];
2384        }
2385      }
2386      pictureTimingSEI.m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<double>(pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
2387#if POC_RESET_FLAG
2388      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pocCurr - m_totalCoded;
2389#else
2390      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded;
2391#endif
2392#if EFFICIENT_FIELD_IRAP
2393      if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
2394      {
2395        // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
2396        pictureTimingSEI.m_picDpbOutputDelay ++;
2397      }
2398#endif
2399      Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
2400      pictureTimingSEI.m_picDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
2401      if( m_pcCfg->getDecodingUnitInfoSEIEnabled() )
2402      {
2403        picSptDpbOutputDuDelay = factor * pictureTimingSEI.m_picDpbOutputDelay;
2404      }
2405    }
2406
2407    if( ( m_pcCfg->getBufferingPeriodSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) &&
2408        ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) && 
2409        ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
2410       || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
2411    {
2412      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2413      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2414      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2415
2416      SEIBufferingPeriod sei_buffering_period;
2417     
2418      UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
2419      sei_buffering_period.m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
2420      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
2421      sei_buffering_period.m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
2422      sei_buffering_period.m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
2423
2424      Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
2425
2426      UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
2427      uiInitialCpbRemovalDelay -= uiTmp;
2428      uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
2429      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
2430      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
2431      sei_buffering_period.m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
2432      sei_buffering_period.m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
2433
2434      sei_buffering_period.m_rapCpbParamsPresentFlag              = 0;
2435      //for the concatenation, it can be set to one during splicing.
2436      sei_buffering_period.m_concatenationFlag = 0;
2437      //since the temporal layer HRD is not ready, we assumed it is fixed
2438      sei_buffering_period.m_auCpbRemovalDelayDelta = 1;
2439      sei_buffering_period.m_cpbDelayOffset = 0;
2440      sei_buffering_period.m_dpbDelayOffset = 0;
2441
2442#if O0164_MULTI_LAYER_HRD
2443      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, m_pcEncTop->getVPS(), pcSlice->getSPS());
2444#else
2445      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_buffering_period, pcSlice->getSPS());
2446#endif
2447      writeRBSPTrailingBits(nalu.m_Bitstream);
2448      {
2449      UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2450      UInt offsetPosition = m_activeParameterSetSEIPresentInAU;   // Insert BP SEI after APS SEI
2451      AccessUnit::iterator it;
2452      for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2453      {
2454        it++;
2455      }
2456      accessUnit.insert(it, new NALUnitEBSP(nalu));
2457      m_bufferingPeriodSEIPresentInAU = true;
2458      }
2459
2460      if (m_pcCfg->getScalableNestingSEIEnabled())
2461      {
2462        OutputNALUnit naluTmp(NAL_UNIT_PREFIX_SEI);
2463        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2464        m_pcEntropyCoder->setBitstream(&naluTmp.m_Bitstream);
2465        scalableNestingSEI.m_nestedSEIs.clear();
2466        scalableNestingSEI.m_nestedSEIs.push_back(&sei_buffering_period);
2467#if O0164_MULTI_LAYER_HRD
2468        m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
2469#else
2470        m_seiWriter.writeSEImessage( naluTmp.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
2471#endif
2472        writeRBSPTrailingBits(naluTmp.m_Bitstream);
2473        UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
2474        UInt offsetPosition = m_activeParameterSetSEIPresentInAU + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU;   // Insert BP SEI after non-nested APS, BP and PT SEIs
2475        AccessUnit::iterator it;
2476        for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
2477        {
2478          it++;
2479        }
2480        accessUnit.insert(it, new NALUnitEBSP(naluTmp));
2481        m_nestedBufferingPeriodSEIPresentInAU = true;
2482      }
2483
2484      m_lastBPSEI = m_totalCoded;
2485      m_cpbRemovalDelay = 0;
2486    }
2487    m_cpbRemovalDelay ++;
2488    if( ( m_pcEncTop->getRecoveryPointSEIEnabled() ) && ( pcSlice->getSliceType() == I_SLICE ) )
2489    {
2490      if( m_pcEncTop->getGradualDecodingRefreshInfoEnabled() && !pcSlice->getRapPicFlag() )
2491      {
2492        // Gradual decoding refresh SEI
2493        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2494        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2495        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2496
2497        SEIGradualDecodingRefreshInfo seiGradualDecodingRefreshInfo;
2498        seiGradualDecodingRefreshInfo.m_gdrForegroundFlag = true; // Indicating all "foreground"
2499
2500#if O0164_MULTI_LAYER_HRD
2501        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2502#else
2503        m_seiWriter.writeSEImessage( nalu.m_Bitstream, seiGradualDecodingRefreshInfo, pcSlice->getSPS() );
2504#endif
2505        writeRBSPTrailingBits(nalu.m_Bitstream);
2506        accessUnit.push_back(new NALUnitEBSP(nalu));
2507      }
2508    // Recovery point SEI
2509      OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI);
2510      m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2511      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2512
2513      SEIRecoveryPoint sei_recovery_point;
2514      sei_recovery_point.m_recoveryPocCnt    = 0;
2515#if POC_RESET_FLAG
2516      sei_recovery_point.m_exactMatchingFlag = ( pocCurr == 0 ) ? (true) : (false);
2517#else
2518      sei_recovery_point.m_exactMatchingFlag = ( pcSlice->getPOC() == 0 ) ? (true) : (false);
2519#endif
2520      sei_recovery_point.m_brokenLinkFlag    = false;
2521#if ALLOW_RECOVERY_POINT_AS_RAP
2522      if(m_pcCfg->getDecodingRefreshType() == 3)
2523      {
2524        m_iLastRecoveryPicPOC = pocCurr;
2525      }
2526#endif
2527
2528#if O0164_MULTI_LAYER_HRD
2529      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, m_pcEncTop->getVPS(), pcSlice->getSPS() );
2530#else
2531      m_seiWriter.writeSEImessage( nalu.m_Bitstream, sei_recovery_point, pcSlice->getSPS() );
2532#endif
2533      writeRBSPTrailingBits(nalu.m_Bitstream);
2534      accessUnit.push_back(new NALUnitEBSP(nalu));
2535    }
2536
2537    /* use the main bitstream buffer for storing the marshalled picture */
2538    m_pcEntropyCoder->setBitstream(NULL);
2539
2540    startCUAddrSliceIdx = 0;
2541    startCUAddrSlice    = 0; 
2542
2543    startCUAddrSliceSegmentIdx = 0;
2544    startCUAddrSliceSegment    = 0; 
2545    nextCUAddr                 = 0;
2546    pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
2547
2548    Int processingState = (pcSlice->getSPS()->getUseSAO())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
2549    Bool skippedSlice=false;
2550    while (nextCUAddr < uiRealEndAddress) // Iterate over all slices
2551    {
2552      switch(processingState)
2553      {
2554      case ENCODE_SLICE:
2555        {
2556          pcSlice->setNextSlice       ( false );
2557          pcSlice->setNextSliceSegment( false );
2558          if (nextCUAddr == m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx])
2559          {
2560            pcSlice = pcPic->getSlice(startCUAddrSliceIdx);
2561            if(startCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
2562            {
2563              pcSlice->checkColRefIdx(startCUAddrSliceIdx, pcPic);
2564            }
2565            pcPic->setCurrSliceIdx(startCUAddrSliceIdx);
2566            m_pcSliceEncoder->setSliceIdx(startCUAddrSliceIdx);
2567            assert(startCUAddrSliceIdx == pcSlice->getSliceIdx());
2568            // Reconstruction slice
2569            pcSlice->setSliceCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
2570            pcSlice->setSliceCurEndCUAddr  ( m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx+1 ] );
2571            // Dependent slice
2572            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
2573            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
2574
2575            pcSlice->setNextSlice       ( true );
2576
2577            startCUAddrSliceIdx++;
2578            startCUAddrSliceSegmentIdx++;
2579          } 
2580          else if (nextCUAddr == m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx])
2581          {
2582            // Dependent slice
2583            pcSlice->setSliceSegmentCurStartCUAddr( nextCUAddr );  // to be used in encodeSlice() + context restriction
2584            pcSlice->setSliceSegmentCurEndCUAddr  ( m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx+1 ] );
2585
2586            pcSlice->setNextSliceSegment( true );
2587
2588            startCUAddrSliceSegmentIdx++;
2589          }
2590#if SVC_EXTENSION
2591          pcSlice->setNumMotionPredRefLayers(m_pcEncTop->getNumMotionPredRefLayers());
2592#endif
2593          pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
2594          pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
2595          UInt uiDummyStartCUAddr;
2596          UInt uiDummyBoundingCUAddr;
2597          m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
2598
2599          uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) % pcPic->getNumPartInCU();
2600          uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getSliceSegmentCurEndCUAddr()-1) / pcPic->getNumPartInCU();
2601          uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2602          uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2603
2604#if REPN_FORMAT_IN_VPS
2605          uiWidth = pcSlice->getPicWidthInLumaSamples();
2606          uiHeight = pcSlice->getPicHeightInLumaSamples();
2607#else
2608          uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
2609          uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
2610#endif
2611          while(uiPosX>=uiWidth||uiPosY>=uiHeight)
2612          {
2613            uiInternalAddress--;
2614            uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
2615            uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
2616          }
2617          uiInternalAddress++;
2618          if(uiInternalAddress==pcPic->getNumPartInCU())
2619          {
2620            uiInternalAddress = 0;
2621            uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
2622          }
2623          UInt endAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
2624          if(endAddress<=pcSlice->getSliceSegmentCurStartCUAddr()) 
2625          {
2626            UInt boundingAddrSlice, boundingAddrSliceSegment;
2627            boundingAddrSlice          = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
2628            boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
2629            nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
2630            if(pcSlice->isNextSlice())
2631            {
2632              skippedSlice=true;
2633            }
2634            continue;
2635          }
2636          if(skippedSlice) 
2637          {
2638            pcSlice->setNextSlice       ( true );
2639            pcSlice->setNextSliceSegment( false );
2640          }
2641          skippedSlice=false;
2642          pcSlice->allocSubstreamSizes( iNumSubstreams );
2643          for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
2644          {
2645            pcSubstreamsOut[ui].clear();
2646          }
2647
2648          m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2649          m_pcEntropyCoder->resetEntropy      ();
2650          /* start slice NALunit */
2651#if SVC_EXTENSION
2652          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer(), m_layerId );
2653#else
2654          OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->getTLayer() );
2655#endif
2656          Bool sliceSegment = (!pcSlice->isNextSlice());
2657          if (!sliceSegment)
2658          {
2659            uiOneBitstreamPerSliceLength = 0; // start of a new slice
2660          }
2661          m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2662
2663#if SETTING_NO_OUT_PIC_PRIOR
2664          if (pcSlice->isIRAP())
2665          {
2666            if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
2667            {
2668              pcSlice->setNoRaslOutputFlag(true);
2669            }
2670            //the inference for NoOutputPriorPicsFlag
2671            if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
2672            {
2673              if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
2674              {
2675                pcSlice->setNoOutputPriorPicsFlag(true);
2676              }
2677            }
2678          }
2679#endif
2680
2681          tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2682          m_pcEntropyCoder->encodeSliceHeader(pcSlice);
2683          actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2684
2685          // is it needed?
2686          {
2687            if (!sliceSegment)
2688            {
2689              pcBitstreamRedirect->writeAlignOne();
2690            }
2691            else
2692            {
2693              // We've not completed our slice header info yet, do the alignment later.
2694            }
2695            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
2696            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
2697            m_pcEntropyCoder->resetEntropy    ();
2698            for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
2699            {
2700              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
2701              m_pcEntropyCoder->resetEntropy    ();
2702            }
2703          }
2704
2705          if(pcSlice->isNextSlice())
2706          {
2707            // set entropy coder for writing
2708            m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
2709            {
2710              for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
2711              {
2712                m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
2713                m_pcEntropyCoder->resetEntropy    ();
2714              }
2715              pcSbacCoders[0].load(m_pcSbacCoder);
2716              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice );  //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below)
2717            }
2718            m_pcEntropyCoder->resetEntropy    ();
2719            // File writing
2720            if (!sliceSegment)
2721            {
2722              m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
2723            }
2724            else
2725            {
2726              m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2727            }
2728            // for now, override the TILES_DECODER setting in order to write substreams.
2729            m_pcEntropyCoder->setBitstream    ( &pcSubstreamsOut[0] );
2730
2731          }
2732          pcSlice->setFinalized(true);
2733
2734          m_pcSbacCoder->load( &pcSbacCoders[0] );
2735
2736          pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
2737            pcSlice->setTileLocationCount ( 0 );
2738          m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut);
2739
2740          {
2741            // Construct the final bitstream by flushing and concatenating substreams.
2742            // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
2743            UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes();
2744            UInt uiTotalCodedSize = 0; // for padding calcs.
2745            UInt uiNumSubstreamsPerTile = iNumSubstreams;
2746            if (iNumSubstreams > 1)
2747            {
2748              uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
2749            }
2750            for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
2751            {
2752              // Flush all substreams -- this includes empty ones.
2753              // Terminating bit and flush.
2754              m_pcEntropyCoder->setEntropyCoder   ( &pcSbacCoders[ui], pcSlice );
2755              m_pcEntropyCoder->setBitstream      (  &pcSubstreamsOut[ui] );
2756              m_pcEntropyCoder->encodeTerminatingBit( 1 );
2757              m_pcEntropyCoder->encodeSliceFinish();
2758
2759              pcSubstreamsOut[ui].writeByteAlignment();   // Byte-alignment in slice_data() at end of sub-stream
2760              // Byte alignment is necessary between tiles when tiles are independent.
2761              uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
2762
2763              Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0);
2764              if (bNextSubstreamInNewTile)
2765              {
2766                pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
2767              }
2768              if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
2769              {
2770                puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3);
2771              }
2772            }
2773
2774            // Complete the slice header info.
2775            m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
2776            m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
2777#if !POC_RESET_IDC_SIGNALLING
2778            m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2779#else
2780            tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
2781            m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
2782            actualHeadBits += ( m_pcEntropyCoder->getNumberOfWrittenBits() - tmpBitsBeforeWriting );
2783            m_pcEntropyCoder->encodeSliceHeaderExtn( pcSlice, actualHeadBits );
2784#endif
2785
2786            // Substreams...
2787            TComOutputBitstream *pcOut = pcBitstreamRedirect;
2788          Int offs = 0;
2789          Int nss = pcSlice->getPPS()->getNumSubstreams();
2790          if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
2791          {
2792            // 1st line present for WPP.
2793            offs = pcSlice->getSliceSegmentCurStartCUAddr()/pcSlice->getPic()->getNumPartInCU()/pcSlice->getPic()->getFrameWidthInCU();
2794            nss  = pcSlice->getNumEntryPointOffsets()+1;
2795          }
2796          for ( UInt ui = 0 ; ui < nss; ui++ )
2797          {
2798            pcOut->addSubstream(&pcSubstreamsOut[ui+offs]);
2799            }
2800          }
2801
2802          UInt boundingAddrSlice, boundingAddrSliceSegment;
2803          boundingAddrSlice        = m_storedStartCUAddrForEncodingSlice[startCUAddrSliceIdx];         
2804          boundingAddrSliceSegment = m_storedStartCUAddrForEncodingSliceSegment[startCUAddrSliceSegmentIdx];         
2805          nextCUAddr               = min(boundingAddrSlice, boundingAddrSliceSegment);
2806          // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple dependent slices) then buffer it.
2807          // 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.
2808          Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
2809          xAttachSliceDataToNalUnit(nalu, pcBitstreamRedirect);
2810          accessUnit.push_back(new NALUnitEBSP(nalu));
2811          actualTotalBits += UInt(accessUnit.back()->m_nalUnitData.str().size()) * 8;
2812          bNALUAlignedWrittenToList = true; 
2813          uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
2814
2815          if (!bNALUAlignedWrittenToList)
2816          {
2817            {
2818              nalu.m_Bitstream.writeAlignZero();
2819            }
2820            accessUnit.push_back(new NALUnitEBSP(nalu));
2821            uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001
2822          }
2823
2824          if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
2825              ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
2826              ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
2827             || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) &&
2828              ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getSubPicCpbParamsPresentFlag() ) )
2829          {
2830              UInt numNalus = 0;
2831            UInt numRBSPBytes = 0;
2832            for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2833            {
2834              UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
2835              if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
2836              {
2837                numRBSPBytes += numRBSPBytes_nal;
2838                numNalus ++;
2839              }
2840            }
2841            accumBitsDU[ pcSlice->getSliceIdx() ] = ( numRBSPBytes << 3 );
2842            accumNalsDU[ pcSlice->getSliceIdx() ] = numNalus;   // SEI not counted for bit count; hence shouldn't be counted for # of NALUs - only for consistency
2843          }
2844          processingState = ENCODE_SLICE;
2845          }
2846          break;
2847        case EXECUTE_INLOOPFILTER:
2848          {
2849            // set entropy coder for RD
2850            m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
2851#if HIGHER_LAYER_IRAP_SKIP_FLAG
2852            if ( pcSlice->getSPS()->getUseSAO() && !( m_pcEncTop->getSkipPictureAtArcSwitch() && m_pcEncTop->getAdaptiveResolutionChange() > 0 && pcSlice->getLayerId() == 1 && pcSlice->getPOC() == m_pcEncTop->getAdaptiveResolutionChange()) )
2853#else
2854            if ( pcSlice->getSPS()->getUseSAO() )
2855#endif
2856            {
2857              m_pcEntropyCoder->resetEntropy();
2858              m_pcEntropyCoder->setBitstream( m_pcBitCounter );
2859              Bool sliceEnabled[NUM_SAO_COMPONENTS];
2860              m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
2861              m_pcSAO->SAOProcess(pcPic
2862                , sliceEnabled
2863                , pcPic->getSlice(0)->getLambdas()
2864#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
2865                , m_pcCfg->getSaoLcuBoundary()
2866#endif
2867              );
2868              m_pcSAO->PCMLFDisableProcess(pcPic);   
2869
2870              //assign SAO slice header
2871              for(Int s=0; s< uiNumSlices; s++)
2872              {
2873                pcPic->getSlice(s)->setSaoEnabledFlag(sliceEnabled[SAO_Y]);
2874                assert(sliceEnabled[SAO_Cb] == sliceEnabled[SAO_Cr]);
2875                pcPic->getSlice(s)->setSaoEnabledFlagChroma(sliceEnabled[SAO_Cb]);
2876              }
2877            }
2878            processingState = ENCODE_SLICE;
2879          }
2880          break;
2881        default:
2882          {
2883            printf("Not a supported encoding state\n");
2884            assert(0);
2885            exit(-1);
2886          }
2887        }
2888      } // end iteration over slices
2889      pcPic->compressMotion(); 
2890     
2891      //-- For time output for each slice
2892      Double dEncTime = (Double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
2893
2894      const Char* digestStr = NULL;
2895      if (m_pcCfg->getDecodedPictureHashSEIEnabled())
2896      {
2897        /* calculate MD5sum for entire reconstructed picture */
2898        SEIDecodedPictureHash sei_recon_picture_digest;
2899        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2900        {
2901          sei_recon_picture_digest.method = SEIDecodedPictureHash::MD5;
2902          calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2903          digestStr = digestToString(sei_recon_picture_digest.digest, 16);
2904        }
2905        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
2906        {
2907          sei_recon_picture_digest.method = SEIDecodedPictureHash::CRC;
2908          calcCRC(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2909          digestStr = digestToString(sei_recon_picture_digest.digest, 2);
2910        }
2911        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
2912        {
2913          sei_recon_picture_digest.method = SEIDecodedPictureHash::CHECKSUM;
2914          calcChecksum(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
2915          digestStr = digestToString(sei_recon_picture_digest.digest, 4);
2916        }
2917#if SVC_EXTENSION
2918        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer(), m_layerId);
2919#else
2920        OutputNALUnit nalu(NAL_UNIT_SUFFIX_SEI, pcSlice->getTLayer());
2921#endif
2922
2923        /* write the SEI messages */
2924        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2925#if O0164_MULTI_LAYER_HRD
2926        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, m_pcEncTop->getVPS(), pcSlice->getSPS());
2927#else
2928        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_recon_picture_digest, pcSlice->getSPS());
2929#endif
2930        writeRBSPTrailingBits(nalu.m_Bitstream);
2931
2932        accessUnit.insert(accessUnit.end(), new NALUnitEBSP(nalu));
2933      }
2934      if (m_pcCfg->getTemporalLevel0IndexSEIEnabled())
2935      {
2936        SEITemporalLevel0Index sei_temporal_level0_index;
2937        if (pcSlice->getRapPicFlag())
2938        {
2939          m_tl0Idx = 0;
2940          m_rapIdx = (m_rapIdx + 1) & 0xFF;
2941        }
2942        else
2943        {
2944          m_tl0Idx = (m_tl0Idx + (pcSlice->getTLayer() ? 0 : 1)) & 0xFF;
2945        }
2946        sei_temporal_level0_index.tl0Idx = m_tl0Idx;
2947        sei_temporal_level0_index.rapIdx = m_rapIdx;
2948
2949        OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI); 
2950
2951        /* write the SEI messages */
2952        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
2953#if O0164_MULTI_LAYER_HRD
2954        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, m_pcEncTop->getVPS(), pcSlice->getSPS());
2955#else
2956        m_seiWriter.writeSEImessage(nalu.m_Bitstream, sei_temporal_level0_index, pcSlice->getSPS());
2957#endif
2958        writeRBSPTrailingBits(nalu.m_Bitstream);
2959
2960        /* insert the SEI message NALUnit before any Slice NALUnits */
2961        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
2962        accessUnit.insert(it, new NALUnitEBSP(nalu));
2963      }
2964
2965      xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime );
2966
2967      //In case of field coding, compute the interlaced PSNR for both fields
2968    if (isField && ((!pcPic->isTopField() && isTff) || (pcPic->isTopField() && !isTff)) && (pcPic->getPOC()%m_iGopSize != 1))
2969      {
2970        //get complementary top field
2971        TComPic* pcPicTop;
2972        TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
2973        while ((*iterPic)->getPOC() != pcPic->getPOC()-1)
2974        {
2975          iterPic ++;
2976        }
2977        pcPicTop = *(iterPic);
2978        xCalculateInterlacedAddPSNR(pcPicTop, pcPic, pcPicTop->getPicYuvRec(), pcPic->getPicYuvRec(), accessUnit, dEncTime );
2979      }
2980    else if (isField && pcPic->getPOC()!= 0 && (pcPic->getPOC()%m_iGopSize == 0))
2981    {
2982      //get complementary bottom field
2983      TComPic* pcPicBottom;
2984      TComList<TComPic*>::iterator   iterPic = rcListPic.begin();
2985      while ((*iterPic)->getPOC() != pcPic->getPOC()+1)
2986      {
2987        iterPic ++;
2988      }
2989      pcPicBottom = *(iterPic);
2990      xCalculateInterlacedAddPSNR(pcPic, pcPicBottom, pcPic->getPicYuvRec(), pcPicBottom->getPicYuvRec(), accessUnit, dEncTime );
2991    }
2992
2993      if (digestStr)
2994      {
2995        if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
2996        {
2997          printf(" [MD5:%s]", digestStr);
2998        }
2999        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
3000        {
3001          printf(" [CRC:%s]", digestStr);
3002        }
3003        else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
3004        {
3005          printf(" [Checksum:%s]", digestStr);
3006        }
3007      }
3008      if ( m_pcCfg->getUseRateCtrl() )
3009      {
3010        Double avgQP     = m_pcRateCtrl->getRCPic()->calAverageQP();
3011        Double avgLambda = m_pcRateCtrl->getRCPic()->calAverageLambda();
3012        if ( avgLambda < 0.0 )
3013        {
3014          avgLambda = lambda;
3015        }
3016        m_pcRateCtrl->getRCPic()->updateAfterPicture( actualHeadBits, actualTotalBits, avgQP, avgLambda, pcSlice->getSliceType());
3017        m_pcRateCtrl->getRCPic()->addToPictureLsit( m_pcRateCtrl->getPicList() );
3018
3019        m_pcRateCtrl->getRCSeq()->updateAfterPic( actualTotalBits );
3020        if ( pcSlice->getSliceType() != I_SLICE )
3021        {
3022          m_pcRateCtrl->getRCGOP()->updateAfterPicture( actualTotalBits );
3023        }
3024        else    // for intra picture, the estimated bits are used to update the current status in the GOP
3025        {
3026          m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
3027        }
3028      }
3029
3030      if( ( m_pcCfg->getPictureTimingSEIEnabled() || m_pcCfg->getDecodingUnitInfoSEIEnabled() ) &&
3031          ( pcSlice->getSPS()->getVuiParametersPresentFlag() ) &&
3032          ( ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getNalHrdParametersPresentFlag() ) 
3033         || ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getVclHrdParametersPresentFlag() ) ) )
3034      {
3035        TComVUI *vui = pcSlice->getSPS()->getVuiParameters();
3036        TComHRD *hrd = vui->getHrdParameters();
3037
3038        if( hrd->getSubPicCpbParamsPresentFlag() )
3039        {
3040          Int i;
3041          UInt64 ui64Tmp;
3042          UInt uiPrev = 0;
3043          UInt numDU = ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 );
3044          UInt *pCRD = &pictureTimingSEI.m_duCpbRemovalDelayMinus1[0];
3045          UInt maxDiff = ( hrd->getTickDivisorMinus2() + 2 ) - 1;
3046
3047          for( i = 0; i < numDU; i ++ )
3048          {
3049            pictureTimingSEI.m_numNalusInDuMinus1[ i ]       = ( i == 0 ) ? ( accumNalsDU[ i ] - 1 ) : ( accumNalsDU[ i ] - accumNalsDU[ i - 1] - 1 );
3050          }
3051
3052          if( numDU == 1 )
3053          {
3054            pCRD[ 0 ] = 0; /* don't care */
3055          }
3056          else
3057          {
3058            pCRD[ numDU - 1 ] = 0;/* by definition */
3059            UInt tmp = 0;
3060            UInt accum = 0;
3061
3062            for( i = ( numDU - 2 ); i >= 0; i -- )
3063            {
3064              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
3065              if( (UInt)ui64Tmp > maxDiff )
3066              {
3067                tmp ++;
3068              }
3069            }
3070            uiPrev = 0;
3071
3072            UInt flag = 0;
3073            for( i = ( numDU - 2 ); i >= 0; i -- )
3074            {
3075              flag = 0;
3076              ui64Tmp = ( ( ( accumBitsDU[ numDU - 1 ]  - accumBitsDU[ i ] ) * ( vui->getTimingInfo()->getTimeScale() / vui->getTimingInfo()->getNumUnitsInTick() ) * ( hrd->getTickDivisorMinus2() + 2 ) ) / ( m_pcCfg->getTargetBitrate() ) );
3077
3078              if( (UInt)ui64Tmp > maxDiff )
3079              {
3080                if(uiPrev >= maxDiff - tmp)
3081                {
3082                  ui64Tmp = uiPrev + 1;
3083                  flag = 1;
3084                }
3085                else                            ui64Tmp = maxDiff - tmp + 1;
3086              }
3087              pCRD[ i ] = (UInt)ui64Tmp - uiPrev - 1;
3088              if( (Int)pCRD[ i ] < 0 )
3089              {
3090                pCRD[ i ] = 0;
3091              }
3092              else if (tmp > 0 && flag == 1) 
3093              {
3094                tmp --;
3095              }
3096              accum += pCRD[ i ] + 1;
3097              uiPrev = accum;
3098            }
3099          }
3100        }
3101        if( m_pcCfg->getPictureTimingSEIEnabled() )
3102        {
3103          {
3104            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3105          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3106          pictureTimingSEI.m_picStruct = (isField && pcSlice->getPic()->isTopField())? 1 : isField? 2 : 0;
3107#if O0164_MULTI_LAYER_HRD
3108          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3109#else
3110          m_seiWriter.writeSEImessage(nalu.m_Bitstream, pictureTimingSEI, pcSlice->getSPS());
3111#endif
3112          writeRBSPTrailingBits(nalu.m_Bitstream);
3113          UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3114          UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3115                                    + m_bufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
3116          AccessUnit::iterator it;
3117          for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
3118          {
3119            it++;
3120          }
3121          accessUnit.insert(it, new NALUnitEBSP(nalu));
3122          m_pictureTimingSEIPresentInAU = true;
3123        }
3124          if ( m_pcCfg->getScalableNestingSEIEnabled() ) // put picture timing SEI into scalable nesting SEI
3125          {
3126            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3127            m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3128            scalableNestingSEI.m_nestedSEIs.clear();
3129            scalableNestingSEI.m_nestedSEIs.push_back(&pictureTimingSEI);
3130#if O0164_MULTI_LAYER_HRD
3131            m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3132#else
3133            m_seiWriter.writeSEImessage(nalu.m_Bitstream, scalableNestingSEI, pcSlice->getSPS());
3134#endif
3135            writeRBSPTrailingBits(nalu.m_Bitstream);
3136            UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3137            UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3138              + m_bufferingPeriodSEIPresentInAU + m_pictureTimingSEIPresentInAU + m_nestedBufferingPeriodSEIPresentInAU;    // Insert PT SEI after APS and BP SEI
3139            AccessUnit::iterator it;
3140            for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
3141            {
3142              it++;
3143            }
3144            accessUnit.insert(it, new NALUnitEBSP(nalu));
3145            m_nestedPictureTimingSEIPresentInAU = true;
3146          }
3147        }
3148        if( m_pcCfg->getDecodingUnitInfoSEIEnabled() && hrd->getSubPicCpbParamsPresentFlag() )
3149        {             
3150          m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
3151          for( Int i = 0; i < ( pictureTimingSEI.m_numDecodingUnitsMinus1 + 1 ); i ++ )
3152          {
3153            OutputNALUnit nalu(NAL_UNIT_PREFIX_SEI, pcSlice->getTLayer());
3154
3155            SEIDecodingUnitInfo tempSEI;
3156            tempSEI.m_decodingUnitIdx = i;
3157            tempSEI.m_duSptCpbRemovalDelay = pictureTimingSEI.m_duCpbRemovalDelayMinus1[i] + 1;
3158            tempSEI.m_dpbOutputDuDelayPresentFlag = false;
3159            tempSEI.m_picSptDpbOutputDuDelay = picSptDpbOutputDuDelay;
3160
3161            AccessUnit::iterator it;
3162            // Insert the first one in the right location, before the first slice
3163            if(i == 0)
3164            {
3165              // Insert before the first slice.
3166#if O0164_MULTI_LAYER_HRD
3167              m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3168#else
3169              m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
3170#endif
3171              writeRBSPTrailingBits(nalu.m_Bitstream);
3172
3173              UInt seiPositionInAu = xGetFirstSeiLocation(accessUnit);
3174              UInt offsetPosition = m_activeParameterSetSEIPresentInAU
3175                                    + m_bufferingPeriodSEIPresentInAU
3176                                    + m_pictureTimingSEIPresentInAU;  // Insert DU info SEI after APS, BP and PT SEI
3177              for(j = 0, it = accessUnit.begin(); j < seiPositionInAu + offsetPosition; j++)
3178              {
3179                it++;
3180              }
3181              accessUnit.insert(it, new NALUnitEBSP(nalu));
3182            }
3183            else
3184            {
3185              Int ctr;
3186              // For the second decoding unit onwards we know how many NALUs are present
3187              for (ctr = 0, it = accessUnit.begin(); it != accessUnit.end(); it++)
3188              {           
3189                if(ctr == accumNalsDU[ i - 1 ])
3190                {
3191                  // Insert before the first slice.
3192#if O0164_MULTI_LAYER_HRD
3193                  m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, m_pcEncTop->getVPS(), pcSlice->getSPS());
3194#else
3195                  m_seiWriter.writeSEImessage(nalu.m_Bitstream, tempSEI, pcSlice->getSPS());
3196#endif
3197                  writeRBSPTrailingBits(nalu.m_Bitstream);
3198
3199                  accessUnit.insert(it, new NALUnitEBSP(nalu));
3200                  break;
3201                }
3202                if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3203                {
3204                  ctr++;
3205                }
3206              }
3207            }           
3208          }
3209        }
3210      }
3211      xResetNonNestedSEIPresentFlags();
3212      xResetNestedSEIPresentFlags();
3213      pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
3214
3215#if M0040_ADAPTIVE_RESOLUTION_CHANGE
3216      pcPicYuvRecOut->setReconstructed(true);
3217#endif
3218
3219      pcPic->setReconMark   ( true );
3220      m_bFirst = false;
3221      m_iNumPicCoded++;
3222      m_totalCoded ++;
3223      /* logging: insert a newline at end of picture period */
3224      printf("\n");
3225      fflush(stdout);
3226
3227      delete[] pcSubstreamsOut;
3228
3229#if EFFICIENT_FIELD_IRAP
3230    if(IRAPtoReorder)
3231    {
3232      if(swapIRAPForward)
3233      {
3234        if(iGOPid == IRAPGOPid)
3235        {
3236          iGOPid = IRAPGOPid +1;
3237          IRAPtoReorder = false;
3238        }
3239        else if(iGOPid == IRAPGOPid +1)
3240        {
3241          iGOPid --;
3242        }
3243      }
3244      else
3245      {
3246        if(iGOPid == IRAPGOPid)
3247        {
3248          iGOPid = IRAPGOPid -1;
3249        }
3250        else if(iGOPid == IRAPGOPid -1)
3251        {
3252          iGOPid = IRAPGOPid;
3253          IRAPtoReorder = false;
3254        }
3255      }
3256    }
3257#endif
3258  }
3259  delete pcBitstreamRedirect;
3260
3261  if( accumBitsDU != NULL) delete accumBitsDU;
3262  if( accumNalsDU != NULL) delete accumNalsDU;
3263
3264#if SVC_EXTENSION
3265  assert ( m_iNumPicCoded <= 1 || (isField && iPOCLast == 1) );
3266#else
3267  assert ( (m_iNumPicCoded == iNumPicRcvd) || (isField && iPOCLast == 1) );
3268#endif
3269}
3270
3271#if !SVC_EXTENSION
3272Void TEncGOP::printOutSummary(UInt uiNumAllPicCoded, Bool isField)
3273{
3274  assert (uiNumAllPicCoded == m_gcAnalyzeAll.getNumPic());
3275 
3276   
3277  //--CFG_KDY
3278  if(isField)
3279  {
3280    m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() * 2);
3281    m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() * 2);
3282    m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() * 2);
3283    m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() * 2);
3284  }
3285   else
3286  {
3287    m_gcAnalyzeAll.setFrmRate( m_pcCfg->getFrameRate() );
3288    m_gcAnalyzeI.setFrmRate( m_pcCfg->getFrameRate() );
3289    m_gcAnalyzeP.setFrmRate( m_pcCfg->getFrameRate() );
3290    m_gcAnalyzeB.setFrmRate( m_pcCfg->getFrameRate() );
3291  }
3292 
3293  //-- all
3294  printf( "\n\nSUMMARY --------------------------------------------------------\n" );
3295  m_gcAnalyzeAll.printOut('a');
3296 
3297  printf( "\n\nI Slices--------------------------------------------------------\n" );
3298  m_gcAnalyzeI.printOut('i');
3299 
3300  printf( "\n\nP Slices--------------------------------------------------------\n" );
3301  m_gcAnalyzeP.printOut('p');
3302 
3303  printf( "\n\nB Slices--------------------------------------------------------\n" );
3304  m_gcAnalyzeB.printOut('b');
3305 
3306#if _SUMMARY_OUT_
3307  m_gcAnalyzeAll.printSummaryOut();
3308#endif
3309#if _SUMMARY_PIC_
3310  m_gcAnalyzeI.printSummary('I');
3311  m_gcAnalyzeP.printSummary('P');
3312  m_gcAnalyzeB.printSummary('B');
3313#endif
3314
3315  if(isField)
3316  {
3317    //-- interlaced summary
3318    m_gcAnalyzeAll_in.setFrmRate( m_pcCfg->getFrameRate());
3319    printf( "\n\nSUMMARY INTERLACED ---------------------------------------------\n" );
3320    m_gcAnalyzeAll_in.printOutInterlaced('a',  m_gcAnalyzeAll.getBits());
3321   
3322#if _SUMMARY_OUT_
3323    m_gcAnalyzeAll_in.printSummaryOutInterlaced();
3324#endif
3325  }
3326
3327  printf("\nRVM: %.3lf\n" , xCalculateRVM());
3328}
3329#endif
3330
3331Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
3332{
3333  TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
3334  Bool bCalcDist = false;
3335  m_pcLoopFilter->setCfg(m_pcCfg->getLFCrossTileBoundaryFlag());
3336  m_pcLoopFilter->loopFilterPic( pcPic );
3337 
3338  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
3339  m_pcEntropyCoder->resetEntropy    ();
3340  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
3341  m_pcEntropyCoder->resetEntropy    ();
3342  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
3343 
3344  if (!bCalcDist)
3345    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
3346}
3347
3348// ====================================================================================================================
3349// Protected member functions
3350// ====================================================================================================================
3351
3352
3353Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, Bool isField )
3354{
3355  assert( iNumPicRcvd > 0 );
3356  //  Exception for the first frames
3357  if ( ( isField && (iPOCLast == 0 || iPOCLast == 1) ) || (!isField  && (iPOCLast == 0))  )
3358  {
3359    m_iGopSize    = 1;
3360  }
3361  else
3362  {
3363    m_iGopSize    = m_pcCfg->getGOPSize();
3364  }
3365  assert (m_iGopSize > 0);
3366 
3367  return;
3368}
3369
3370Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut )
3371{
3372  assert( iNumPicRcvd > 0 );
3373  //  Exception for the first frame
3374  if ( iPOCLast == 0 )
3375  {
3376    m_iGopSize    = 1;
3377  }
3378  else
3379    m_iGopSize    = m_pcCfg->getGOPSize();
3380 
3381  assert (m_iGopSize > 0); 
3382
3383  return;
3384}
3385
3386Void TEncGOP::xGetBuffer( TComList<TComPic*>&      rcListPic,
3387                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
3388                         Int                       iNumPicRcvd,
3389                         Int                       iTimeOffset,
3390                         TComPic*&                 rpcPic,
3391                         TComPicYuv*&              rpcPicYuvRecOut,
3392                         Int                       pocCurr,
3393                         Bool                      isField)
3394{
3395  Int i;
3396  //  Rec. output
3397  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
3398
3399  if (isField)
3400  {
3401    for ( i = 0; i < ( (pocCurr == 0 ) || (pocCurr == 1 ) ? (iNumPicRcvd - iTimeOffset + 1) : (iNumPicRcvd - iTimeOffset + 2) ); i++ )
3402    {
3403      iterPicYuvRec--;
3404    }
3405  }
3406  else
3407  {
3408    for ( i = 0; i < (iNumPicRcvd - iTimeOffset + 1); i++ )
3409    {
3410      iterPicYuvRec--;
3411    }
3412   
3413  }
3414 
3415  if (isField)
3416  {
3417    if(pocCurr == 1)
3418    {
3419      iterPicYuvRec++;
3420    }
3421  }
3422  rpcPicYuvRecOut = *(iterPicYuvRec);
3423 
3424  //  Current pic.
3425  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
3426  while (iterPic != rcListPic.end())
3427  {
3428    rpcPic = *(iterPic);
3429    rpcPic->setCurrSliceIdx(0);
3430    if (rpcPic->getPOC() == pocCurr)
3431    {
3432      break;
3433    }
3434    iterPic++;
3435  }
3436 
3437  assert( rpcPic != NULL );
3438  assert( rpcPic->getPOC() == pocCurr );
3439 
3440  return;
3441}
3442
3443UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
3444{
3445  Int     x, y;
3446  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
3447  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
3448  UInt  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthY-8);
3449  Int   iTemp;
3450 
3451  Int   iStride = pcPic0->getStride();
3452  Int   iWidth  = pcPic0->getWidth();
3453  Int   iHeight = pcPic0->getHeight();
3454 
3455  UInt64  uiTotalDiff = 0;
3456 
3457  for( y = 0; y < iHeight; y++ )
3458  {
3459    for( x = 0; x < iWidth; x++ )
3460    {
3461      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
3462    }
3463    pSrc0 += iStride;
3464    pSrc1 += iStride;
3465  }
3466 
3467  uiShift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
3468  iHeight >>= 1;
3469  iWidth  >>= 1;
3470  iStride >>= 1;
3471 
3472  pSrc0  = pcPic0->getCbAddr();
3473  pSrc1  = pcPic1->getCbAddr();
3474 
3475  for( y = 0; y < iHeight; y++ )
3476  {
3477    for( x = 0; x < iWidth; x++ )
3478    {
3479      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
3480    }
3481    pSrc0 += iStride;
3482    pSrc1 += iStride;
3483  }
3484 
3485  pSrc0  = pcPic0->getCrAddr();
3486  pSrc1  = pcPic1->getCrAddr();
3487 
3488  for( y = 0; y < iHeight; y++ )
3489  {
3490    for( x = 0; x < iWidth; x++ )
3491    {
3492      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
3493    }
3494    pSrc0 += iStride;
3495    pSrc1 += iStride;
3496  }
3497 
3498  return uiTotalDiff;
3499}
3500
3501#if VERBOSE_RATE
3502static const Char* nalUnitTypeToString(NalUnitType type)
3503{
3504  switch (type)
3505  {
3506    case NAL_UNIT_CODED_SLICE_TRAIL_R:    return "TRAIL_R";
3507    case NAL_UNIT_CODED_SLICE_TRAIL_N:    return "TRAIL_N";
3508    case NAL_UNIT_CODED_SLICE_TSA_R:      return "TSA_R";
3509    case NAL_UNIT_CODED_SLICE_TSA_N:      return "TSA_N";
3510    case NAL_UNIT_CODED_SLICE_STSA_R:     return "STSA_R";
3511    case NAL_UNIT_CODED_SLICE_STSA_N:     return "STSA_N";
3512    case NAL_UNIT_CODED_SLICE_BLA_W_LP:   return "BLA_W_LP";
3513    case NAL_UNIT_CODED_SLICE_BLA_W_RADL: return "BLA_W_RADL";
3514    case NAL_UNIT_CODED_SLICE_BLA_N_LP:   return "BLA_N_LP";
3515    case NAL_UNIT_CODED_SLICE_IDR_W_RADL: return "IDR_W_RADL";
3516    case NAL_UNIT_CODED_SLICE_IDR_N_LP:   return "IDR_N_LP";
3517    case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
3518    case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
3519    case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
3520    case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
3521    case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
3522    case NAL_UNIT_VPS:                    return "VPS";
3523    case NAL_UNIT_SPS:                    return "SPS";
3524    case NAL_UNIT_PPS:                    return "PPS";
3525    case NAL_UNIT_ACCESS_UNIT_DELIMITER:  return "AUD";
3526    case NAL_UNIT_EOS:                    return "EOS";
3527    case NAL_UNIT_EOB:                    return "EOB";
3528    case NAL_UNIT_FILLER_DATA:            return "FILLER";
3529    case NAL_UNIT_PREFIX_SEI:             return "SEI";
3530    case NAL_UNIT_SUFFIX_SEI:             return "SEI";
3531    default:                              return "UNK";
3532  }
3533}
3534#endif
3535
3536Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime )
3537{
3538  Int     x, y;
3539  UInt64 uiSSDY  = 0;
3540  UInt64 uiSSDU  = 0;
3541  UInt64 uiSSDV  = 0;
3542 
3543  Double  dYPSNR  = 0.0;
3544  Double  dUPSNR  = 0.0;
3545  Double  dVPSNR  = 0.0;
3546 
3547  //===== calculate PSNR =====
3548  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
3549  Pel*  pRec    = pcPicD->getLumaAddr();
3550  Int   iStride = pcPicD->getStride();
3551 
3552  Int   iWidth;
3553  Int   iHeight;
3554 
3555  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
3556  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
3557 
3558  Int   iSize   = iWidth*iHeight;
3559 
3560  for( y = 0; y < iHeight; y++ )
3561  {
3562    for( x = 0; x < iWidth; x++ )
3563    {
3564      Int iDiff = (Int)( pOrg[x] - pRec[x] );
3565      uiSSDY   += iDiff * iDiff;
3566    }
3567    pOrg += iStride;
3568    pRec += iStride;
3569  }
3570 
3571  iHeight >>= 1;
3572  iWidth  >>= 1;
3573  iStride >>= 1;
3574  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
3575  pRec  = pcPicD->getCbAddr();
3576 
3577  for( y = 0; y < iHeight; y++ )
3578  {
3579    for( x = 0; x < iWidth; x++ )
3580    {
3581      Int iDiff = (Int)( pOrg[x] - pRec[x] );
3582      uiSSDU   += iDiff * iDiff;
3583    }
3584    pOrg += iStride;
3585    pRec += iStride;
3586  }
3587 
3588  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
3589  pRec  = pcPicD->getCrAddr();
3590 
3591  for( y = 0; y < iHeight; y++ )
3592  {
3593    for( x = 0; x < iWidth; x++ )
3594    {
3595      Int iDiff = (Int)( pOrg[x] - pRec[x] );
3596      uiSSDV   += iDiff * iDiff;
3597    }
3598    pOrg += iStride;
3599    pRec += iStride;
3600  }
3601 
3602  Int maxvalY = 255 << (g_bitDepthY-8);
3603  Int maxvalC = 255 << (g_bitDepthC-8);
3604  Double fRefValueY = (Double) maxvalY * maxvalY * iSize;
3605  Double fRefValueC = (Double) maxvalC * maxvalC * iSize / 4.0;
3606  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
3607  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
3608  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
3609
3610  /* calculate the size of the access unit, excluding:
3611   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3612   *  - SEI NAL units
3613   */
3614  UInt numRBSPBytes = 0;
3615  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3616  {
3617    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3618#if VERBOSE_RATE
3619    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
3620#endif
3621    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3622    {
3623      numRBSPBytes += numRBSPBytes_nal;
3624    }
3625  }
3626
3627  UInt uibits = numRBSPBytes * 8;
3628  m_vRVM_RP.push_back( uibits );
3629
3630  //===== add PSNR =====
3631#if SVC_EXTENSION
3632  m_gcAnalyzeAll[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3633  TComSlice*  pcSlice = pcPic->getSlice(0);
3634  if (pcSlice->isIntra())
3635  {
3636    m_gcAnalyzeI[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3637  }
3638  if (pcSlice->isInterP())
3639  {
3640    m_gcAnalyzeP[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3641  }
3642  if (pcSlice->isInterB())
3643  {
3644    m_gcAnalyzeB[m_layerId].addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3645  }
3646#else
3647  m_gcAnalyzeAll.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3648  TComSlice*  pcSlice = pcPic->getSlice(0);
3649  if (pcSlice->isIntra())
3650  {
3651    m_gcAnalyzeI.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3652  }
3653  if (pcSlice->isInterP())
3654  {
3655    m_gcAnalyzeP.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3656  }
3657  if (pcSlice->isInterB())
3658  {
3659    m_gcAnalyzeB.addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
3660  }
3661#endif
3662
3663  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
3664  if (!pcSlice->isReferenced()) c += 32;
3665
3666#if SVC_EXTENSION
3667#if ADAPTIVE_QP_SELECTION 
3668  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, nQP %d QP %d ) %10d bits",
3669         pcSlice->getPOC(),
3670         pcSlice->getLayerId(),
3671         pcSlice->getTLayer(),
3672         c,
3673         NaluToStr( pcSlice->getNalUnitType() ).data(),
3674         pcSlice->getSliceQpBase(),
3675         pcSlice->getSliceQp(),
3676         uibits );
3677#else
3678  printf("POC %4d LId: %1d TId: %1d ( %c-SLICE %s, QP %d ) %10d bits",
3679         pcSlice->getPOC()-pcSlice->getLastIDR(),
3680         pcSlice->getLayerId(),
3681         pcSlice->getTLayer(),
3682         c,
3683         NaluToStr( pcSlice->getNalUnitType() ).data(),
3684         pcSlice->getSliceQp(),
3685         uibits );
3686#endif
3687#else
3688#if ADAPTIVE_QP_SELECTION
3689  printf("POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
3690         pcSlice->getPOC(),
3691         pcSlice->getTLayer(),
3692         c,
3693         pcSlice->getSliceQpBase(),
3694         pcSlice->getSliceQp(),
3695         uibits );
3696#else
3697  printf("POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
3698         pcSlice->getPOC()-pcSlice->getLastIDR(),
3699         pcSlice->getTLayer(),
3700         c,
3701         pcSlice->getSliceQp(),
3702         uibits );
3703#endif
3704#endif
3705
3706  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR );
3707  printf(" [ET %5.0f ]", dEncTime );
3708 
3709  for (Int iRefList = 0; iRefList < 2; iRefList++)
3710  {
3711    printf(" [L%d ", iRefList);
3712    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
3713    {
3714#if SVC_EXTENSION
3715#if VPS_EXTN_DIRECT_REF_LAYERS
3716      if( pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->isILR(m_layerId) )
3717      {
3718        printf( "%d(%d)", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR(), pcSlice->getRefPic(RefPicList(iRefList), iRefIndex)->getLayerId() );
3719      }
3720      else
3721      {
3722        printf ("%d", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3723      }
3724#endif
3725      if( pcSlice->getEnableTMVPFlag() && iRefList == 1 - pcSlice->getColFromL0Flag() && iRefIndex == pcSlice->getColRefIdx() )
3726      {
3727        printf( "c" );
3728      }
3729
3730      printf( " " );
3731#else
3732      printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
3733#endif
3734    }
3735    printf("]");
3736  }
3737#if Q0048_CGS_3D_ASYMLUT
3738  pcPic->setFrameBit( (Int)uibits );
3739  if( m_layerId && pcSlice->getPPS()->getCGSFlag() )
3740  {
3741    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
3742  }
3743#endif
3744}
3745
3746
3747Void reinterlace(Pel* top, Pel* bottom, Pel* dst, UInt stride, UInt width, UInt height, Bool isTff)
3748{
3749 
3750  for (Int y = 0; y < height; y++)
3751  {
3752    for (Int x = 0; x < width; x++)
3753    {
3754      dst[x] = isTff ? top[x] : bottom[x];
3755      dst[stride+x] = isTff ? bottom[x] : top[x];
3756    }
3757    top += stride;
3758    bottom += stride;
3759    dst += stride*2;
3760  }
3761}
3762
3763Void TEncGOP::xCalculateInterlacedAddPSNR( TComPic* pcPicOrgTop, TComPic* pcPicOrgBottom, TComPicYuv* pcPicRecTop, TComPicYuv* pcPicRecBottom, const AccessUnit& accessUnit, Double dEncTime )
3764{
3765  Int     x, y;
3766 
3767  UInt64 uiSSDY_in  = 0;
3768  UInt64 uiSSDU_in  = 0;
3769  UInt64 uiSSDV_in  = 0;
3770 
3771  Double  dYPSNR_in  = 0.0;
3772  Double  dUPSNR_in  = 0.0;
3773  Double  dVPSNR_in  = 0.0;
3774 
3775  /*------ INTERLACED PSNR -----------*/
3776 
3777  /* Luma */
3778 
3779  Pel*  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getLumaAddr();
3780  Pel*  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getLumaAddr();
3781  Pel*  pRecTop = pcPicRecTop->getLumaAddr();
3782  Pel*  pRecBottom = pcPicRecBottom->getLumaAddr();
3783 
3784  Int   iWidth;
3785  Int   iHeight;
3786  Int iStride;
3787 
3788  iWidth  = pcPicOrgTop->getPicYuvOrg()->getWidth () - m_pcEncTop->getPad(0);
3789  iHeight = pcPicOrgTop->getPicYuvOrg()->getHeight() - m_pcEncTop->getPad(1);
3790  iStride = pcPicOrgTop->getPicYuvOrg()->getStride();
3791  Int   iSize   = iWidth*iHeight;
3792  bool isTff = pcPicOrgTop->isTopField();
3793 
3794  TComPicYuv* pcOrgInterlaced = new TComPicYuv;
3795#if AUXILIARY_PICTURES
3796  pcOrgInterlaced->create( iWidth, iHeight << 1, pcPicOrgTop->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
3797#else
3798  pcOrgInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
3799#endif
3800 
3801  TComPicYuv* pcRecInterlaced = new TComPicYuv;
3802#if AUXILIARY_PICTURES
3803  pcRecInterlaced->create( iWidth, iHeight << 1, pcPicOrgTop->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
3804#else
3805  pcRecInterlaced->create( iWidth, iHeight << 1, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
3806#endif
3807 
3808  Pel* pOrgInterlaced = pcOrgInterlaced->getLumaAddr();
3809  Pel* pRecInterlaced = pcRecInterlaced->getLumaAddr();
3810 
3811  //=== Interlace fields ====
3812  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
3813  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
3814 
3815  //===== calculate PSNR =====
3816  for( y = 0; y < iHeight << 1; y++ )
3817  {
3818    for( x = 0; x < iWidth; x++ )
3819    {
3820      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
3821      uiSSDY_in   += iDiff * iDiff;
3822    }
3823    pOrgInterlaced += iStride;
3824    pRecInterlaced += iStride;
3825  }
3826 
3827  /*Chroma*/
3828 
3829  iHeight >>= 1;
3830  iWidth  >>= 1;
3831  iStride >>= 1;
3832 
3833  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCbAddr();
3834  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCbAddr();
3835  pRecTop = pcPicRecTop->getCbAddr();
3836  pRecBottom = pcPicRecBottom->getCbAddr();
3837  pOrgInterlaced = pcOrgInterlaced->getCbAddr();
3838  pRecInterlaced = pcRecInterlaced->getCbAddr();
3839 
3840  //=== Interlace fields ====
3841  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
3842  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
3843 
3844  //===== calculate PSNR =====
3845  for( y = 0; y < iHeight << 1; y++ )
3846  {
3847    for( x = 0; x < iWidth; x++ )
3848    {
3849      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
3850      uiSSDU_in   += iDiff * iDiff;
3851    }
3852    pOrgInterlaced += iStride;
3853    pRecInterlaced += iStride;
3854  }
3855 
3856  pOrgTop = pcPicOrgTop->getPicYuvOrg()->getCrAddr();
3857  pOrgBottom = pcPicOrgBottom->getPicYuvOrg()->getCrAddr();
3858  pRecTop = pcPicRecTop->getCrAddr();
3859  pRecBottom = pcPicRecBottom->getCrAddr();
3860  pOrgInterlaced = pcOrgInterlaced->getCrAddr();
3861  pRecInterlaced = pcRecInterlaced->getCrAddr();
3862 
3863  //=== Interlace fields ====
3864  reinterlace(pOrgTop, pOrgBottom, pOrgInterlaced, iStride, iWidth, iHeight, isTff);
3865  reinterlace(pRecTop, pRecBottom, pRecInterlaced, iStride, iWidth, iHeight, isTff);
3866 
3867  //===== calculate PSNR =====
3868  for( y = 0; y < iHeight << 1; y++ )
3869  {
3870    for( x = 0; x < iWidth; x++ )
3871    {
3872      Int iDiff = (Int)( pOrgInterlaced[x] - pRecInterlaced[x] );
3873      uiSSDV_in   += iDiff * iDiff;
3874    }
3875    pOrgInterlaced += iStride;
3876    pRecInterlaced += iStride;
3877  }
3878 
3879  Int maxvalY = 255 << (g_bitDepthY-8);
3880  Int maxvalC = 255 << (g_bitDepthC-8);
3881  Double fRefValueY = (Double) maxvalY * maxvalY * iSize*2;
3882  Double fRefValueC = (Double) maxvalC * maxvalC * iSize*2 / 4.0;
3883  dYPSNR_in            = ( uiSSDY_in ? 10.0 * log10( fRefValueY / (Double)uiSSDY_in ) : 99.99 );
3884  dUPSNR_in            = ( uiSSDU_in ? 10.0 * log10( fRefValueC / (Double)uiSSDU_in ) : 99.99 );
3885  dVPSNR_in            = ( uiSSDV_in ? 10.0 * log10( fRefValueC / (Double)uiSSDV_in ) : 99.99 );
3886 
3887  /* calculate the size of the access unit, excluding:
3888   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
3889   *  - SEI NAL units
3890   */
3891  UInt numRBSPBytes = 0;
3892  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
3893  {
3894    UInt numRBSPBytes_nal = UInt((*it)->m_nalUnitData.str().size());
3895   
3896    if ((*it)->m_nalUnitType != NAL_UNIT_PREFIX_SEI && (*it)->m_nalUnitType != NAL_UNIT_SUFFIX_SEI)
3897      numRBSPBytes += numRBSPBytes_nal;
3898  }
3899 
3900  UInt uibits = numRBSPBytes * 8 ;
3901 
3902  //===== add PSNR =====
3903  m_gcAnalyzeAll_in.addResult (dYPSNR_in, dUPSNR_in, dVPSNR_in, (Double)uibits);
3904 
3905  printf("\n                                      Interlaced frame %d: [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", pcPicOrgBottom->getPOC()/2 , dYPSNR_in, dUPSNR_in, dVPSNR_in );
3906 
3907  pcOrgInterlaced->destroy();
3908  delete pcOrgInterlaced;
3909  pcRecInterlaced->destroy();
3910  delete pcRecInterlaced;
3911}
3912
3913
3914
3915/** Function for deciding the nal_unit_type.
3916 * \param pocCurr POC of the current picture
3917 * \returns the nal unit type of the picture
3918 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
3919 */
3920NalUnitType TEncGOP::getNalUnitType(Int pocCurr, Int lastIDR, Bool isField)
3921{
3922  if (pocCurr == 0)
3923  {
3924    return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3925  }
3926#if EFFICIENT_FIELD_IRAP
3927  if(isField && pocCurr == 1)
3928  {
3929    // to avoid the picture becoming an IRAP
3930    return NAL_UNIT_CODED_SLICE_TRAIL_R;
3931  }
3932#endif
3933
3934#if ALLOW_RECOVERY_POINT_AS_RAP
3935  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3936#else
3937  if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
3938#endif
3939  {
3940    if (m_pcCfg->getDecodingRefreshType() == 1)
3941    {
3942      return NAL_UNIT_CODED_SLICE_CRA;
3943    }
3944    else if (m_pcCfg->getDecodingRefreshType() == 2)
3945    {
3946      return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
3947    }
3948  }
3949  if(m_pocCRA>0)
3950  {
3951    if(pocCurr<m_pocCRA)
3952    {
3953      // All leading pictures are being marked as TFD pictures here since current encoder uses all
3954      // reference pictures while encoding leading pictures. An encoder can ensure that a leading
3955      // picture can be still decodable when random accessing to a CRA/CRANT/BLA/BLANT picture by
3956      // controlling the reference pictures used for encoding that leading picture. Such a leading
3957      // picture need not be marked as a TFD picture.
3958      return NAL_UNIT_CODED_SLICE_RASL_R;
3959    }
3960  }
3961  if (lastIDR>0)
3962  {
3963    if (pocCurr < lastIDR)
3964    {
3965      return NAL_UNIT_CODED_SLICE_RADL_R;
3966    }
3967  }
3968  return NAL_UNIT_CODED_SLICE_TRAIL_R;
3969}
3970
3971Double TEncGOP::xCalculateRVM()
3972{
3973  Double dRVM = 0;
3974 
3975  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFramesToBeEncoded() > RVM_VCEGAM10_M * 2 )
3976  {
3977    // calculate RVM only for lowdelay configurations
3978    std::vector<Double> vRL , vB;
3979    size_t N = m_vRVM_RP.size();
3980    vRL.resize( N );
3981    vB.resize( N );
3982   
3983    Int i;
3984    Double dRavg = 0 , dBavg = 0;
3985    vB[RVM_VCEGAM10_M] = 0;
3986    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
3987    {
3988      vRL[i] = 0;
3989      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
3990        vRL[i] += m_vRVM_RP[j];
3991      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
3992      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
3993      dRavg += m_vRVM_RP[i];
3994      dBavg += vB[i];
3995    }
3996   
3997    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
3998    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
3999   
4000    Double dSigamB = 0;
4001    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
4002    {
4003      Double tmp = vB[i] - dBavg;
4004      dSigamB += tmp * tmp;
4005    }
4006    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
4007   
4008    Double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
4009   
4010    dRVM = dSigamB / dRavg * f;
4011  }
4012 
4013  return( dRVM );
4014}
4015
4016/** Attaches the input bitstream to the stream in the output NAL unit
4017    Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
4018 *  \param codedSliceData contains the coded slice data (bitstream) to be concatenated to rNalu
4019 *  \param rNalu          target NAL unit
4020 */
4021Void TEncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, TComOutputBitstream*& codedSliceData)
4022{
4023  // Byte-align
4024  rNalu.m_Bitstream.writeByteAlignment();   // Slice header byte-alignment
4025
4026  // Perform bitstream concatenation
4027  if (codedSliceData->getNumberOfWrittenBits() > 0)
4028    {
4029    rNalu.m_Bitstream.addSubstream(codedSliceData);
4030  }
4031
4032  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
4033
4034  codedSliceData->clear();
4035}
4036
4037// Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt,
4038// and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value
4039Void TEncGOP::arrangeLongtermPicturesInRPS(TComSlice *pcSlice, TComList<TComPic*>& rcListPic)
4040{
4041  TComReferencePictureSet *rps = pcSlice->getRPS();
4042  if(!rps->getNumberOfLongtermPictures())
4043  {
4044    return;
4045  }
4046
4047  // Arrange long-term reference pictures in the correct order of LSB and MSB,
4048  // and assign values for pocLSBLT and MSB present flag
4049  Int longtermPicsPoc[MAX_NUM_REF_PICS], longtermPicsLSB[MAX_NUM_REF_PICS], indices[MAX_NUM_REF_PICS];
4050  Int longtermPicsMSB[MAX_NUM_REF_PICS];
4051  Bool mSBPresentFlag[MAX_NUM_REF_PICS];
4052  ::memset(longtermPicsPoc, 0, sizeof(longtermPicsPoc));    // Store POC values of LTRP
4053  ::memset(longtermPicsLSB, 0, sizeof(longtermPicsLSB));    // Store POC LSB values of LTRP
4054  ::memset(longtermPicsMSB, 0, sizeof(longtermPicsMSB));    // Store POC LSB values of LTRP
4055  ::memset(indices        , 0, sizeof(indices));            // Indices to aid in tracking sorted LTRPs
4056  ::memset(mSBPresentFlag , 0, sizeof(mSBPresentFlag));     // Indicate if MSB needs to be present
4057
4058  // Get the long-term reference pictures
4059  Int offset = rps->getNumberOfNegativePictures() + rps->getNumberOfPositivePictures();
4060  Int i, ctr = 0;
4061  Int maxPicOrderCntLSB = 1 << pcSlice->getSPS()->getBitsForPOC();
4062  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
4063  {
4064    longtermPicsPoc[ctr] = rps->getPOC(i);                                  // LTRP POC
4065    longtermPicsLSB[ctr] = getLSB(longtermPicsPoc[ctr], maxPicOrderCntLSB); // LTRP POC LSB
4066    indices[ctr]      = i; 
4067    longtermPicsMSB[ctr] = longtermPicsPoc[ctr] - longtermPicsLSB[ctr];
4068  }
4069  Int numLongPics = rps->getNumberOfLongtermPictures();
4070  assert(ctr == numLongPics);
4071
4072  // Arrange pictures in decreasing order of MSB;
4073  for(i = 0; i < numLongPics; i++)
4074  {
4075    for(Int j = 0; j < numLongPics - 1; j++)
4076    {
4077      if(longtermPicsMSB[j] < longtermPicsMSB[j+1])
4078      {
4079        std::swap(longtermPicsPoc[j], longtermPicsPoc[j+1]);
4080        std::swap(longtermPicsLSB[j], longtermPicsLSB[j+1]);
4081        std::swap(longtermPicsMSB[j], longtermPicsMSB[j+1]);
4082        std::swap(indices[j]        , indices[j+1]        );
4083      }
4084    }
4085  }
4086
4087  for(i = 0; i < numLongPics; i++)
4088  {
4089    // Check if MSB present flag should be enabled.
4090    // Check if the buffer contains any pictures that have the same LSB.
4091    TComList<TComPic*>::iterator  iterPic = rcListPic.begin(); 
4092    TComPic*                      pcPic;
4093    while ( iterPic != rcListPic.end() )
4094    {
4095      pcPic = *iterPic;
4096      if( (getLSB(pcPic->getPOC(), maxPicOrderCntLSB) == longtermPicsLSB[i])   &&     // Same LSB
4097                                      (pcPic->getSlice(0)->isReferenced())     &&    // Reference picture
4098                                        (pcPic->getPOC() != longtermPicsPoc[i])    )  // Not the LTRP itself
4099      {
4100        mSBPresentFlag[i] = true;
4101        break;
4102      }
4103      iterPic++;     
4104    }
4105  }
4106
4107  // tempArray for usedByCurr flag
4108  Bool tempArray[MAX_NUM_REF_PICS]; ::memset(tempArray, 0, sizeof(tempArray));
4109  for(i = 0; i < numLongPics; i++)
4110  {
4111    tempArray[i] = rps->getUsed(indices[i]);
4112  }
4113  // Now write the final values;
4114  ctr = 0;
4115  Int currMSB = 0, currLSB = 0;
4116  // currPicPoc = currMSB + currLSB
4117  currLSB = getLSB(pcSlice->getPOC(), maxPicOrderCntLSB); 
4118  currMSB = pcSlice->getPOC() - currLSB;
4119
4120  for(i = rps->getNumberOfPictures() - 1; i >= offset; i--, ctr++)
4121  {
4122    rps->setPOC                   (i, longtermPicsPoc[ctr]);
4123    rps->setDeltaPOC              (i, - pcSlice->getPOC() + longtermPicsPoc[ctr]);
4124    rps->setUsed                  (i, tempArray[ctr]);
4125    rps->setPocLSBLT              (i, longtermPicsLSB[ctr]);
4126    rps->setDeltaPocMSBCycleLT    (i, (currMSB - (longtermPicsPoc[ctr] - longtermPicsLSB[ctr])) / maxPicOrderCntLSB);
4127    rps->setDeltaPocMSBPresentFlag(i, mSBPresentFlag[ctr]);     
4128
4129    assert(rps->getDeltaPocMSBCycleLT(i) >= 0);   // Non-negative value
4130  }
4131  for(i = rps->getNumberOfPictures() - 1, ctr = 1; i >= offset; i--, ctr++)
4132  {
4133    for(Int j = rps->getNumberOfPictures() - 1 - ctr; j >= offset; j--)
4134    {
4135      // Here at the encoder we know that we have set the full POC value for the LTRPs, hence we
4136      // don't have to check the MSB present flag values for this constraint.
4137      assert( rps->getPOC(i) != rps->getPOC(j) ); // If assert fails, LTRP entry repeated in RPS!!!
4138    }
4139  }
4140}
4141
4142/** Function for finding the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
4143 * \param accessUnit Access Unit of the current picture
4144 * This function finds the position to insert the first of APS and non-nested BP, PT, DU info SEI messages.
4145 */
4146Int TEncGOP::xGetFirstSeiLocation(AccessUnit &accessUnit)
4147{
4148  // Find the location of the first SEI message
4149  AccessUnit::iterator it;
4150  Int seiStartPos = 0;
4151  for(it = accessUnit.begin(); it != accessUnit.end(); it++, seiStartPos++)
4152  {
4153     if ((*it)->isSei() || (*it)->isVcl())
4154     {
4155       break;
4156     }               
4157  }
4158//  assert(it != accessUnit.end());  // Triggers with some legit configurations
4159  return seiStartPos;
4160}
4161
4162Void TEncGOP::dblMetric( TComPic* pcPic, UInt uiNumSlices )
4163{
4164  TComPicYuv* pcPicYuvRec = pcPic->getPicYuvRec();
4165  Pel* Rec    = pcPicYuvRec->getLumaAddr( 0 );
4166  Pel* tempRec = Rec;
4167  Int  stride = pcPicYuvRec->getStride();
4168  UInt log2maxTB = pcPic->getSlice(0)->getSPS()->getQuadtreeTULog2MaxSize();
4169  UInt maxTBsize = (1<<log2maxTB);
4170  const UInt minBlockArtSize = 8;
4171  const UInt picWidth = pcPicYuvRec->getWidth();
4172  const UInt picHeight = pcPicYuvRec->getHeight();
4173  const UInt noCol = (picWidth>>log2maxTB);
4174  const UInt noRows = (picHeight>>log2maxTB);
4175  assert(noCol > 1);
4176  assert(noRows > 1);
4177  UInt64 *colSAD = (UInt64*)malloc(noCol*sizeof(UInt64));
4178  UInt64 *rowSAD = (UInt64*)malloc(noRows*sizeof(UInt64));
4179  UInt colIdx = 0;
4180  UInt rowIdx = 0;
4181  Pel p0, p1, p2, q0, q1, q2;
4182 
4183  Int qp = pcPic->getSlice(0)->getSliceQp();
4184  Int bitdepthScale = 1 << (g_bitDepthY-8);
4185  Int beta = TComLoopFilter::getBeta( qp ) * bitdepthScale;
4186  const Int thr2 = (beta>>2);
4187  const Int thr1 = 2*bitdepthScale;
4188  UInt a = 0;
4189 
4190  memset(colSAD, 0, noCol*sizeof(UInt64));
4191  memset(rowSAD, 0, noRows*sizeof(UInt64));
4192 
4193  if (maxTBsize > minBlockArtSize)
4194  {
4195    // Analyze vertical artifact edges
4196    for(Int c = maxTBsize; c < picWidth; c += maxTBsize)
4197    {
4198      for(Int r = 0; r < picHeight; r++)
4199      {
4200        p2 = Rec[c-3];
4201        p1 = Rec[c-2];
4202        p0 = Rec[c-1];
4203        q0 = Rec[c];
4204        q1 = Rec[c+1];
4205        q2 = Rec[c+2];
4206        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
4207        if ( thr1 < a && a < thr2)
4208        {
4209          colSAD[colIdx] += abs(p0 - q0);
4210        }
4211        Rec += stride;
4212      }
4213      colIdx++;
4214      Rec = tempRec;
4215    }
4216   
4217    // Analyze horizontal artifact edges
4218    for(Int r = maxTBsize; r < picHeight; r += maxTBsize)
4219    {
4220      for(Int c = 0; c < picWidth; c++)
4221      {
4222        p2 = Rec[c + (r-3)*stride];
4223        p1 = Rec[c + (r-2)*stride];
4224        p0 = Rec[c + (r-1)*stride];
4225        q0 = Rec[c + r*stride];
4226        q1 = Rec[c + (r+1)*stride];
4227        q2 = Rec[c + (r+2)*stride];
4228        a = ((abs(p2-(p1<<1)+p0)+abs(q0-(q1<<1)+q2))<<1);
4229        if (thr1 < a && a < thr2)
4230        {
4231          rowSAD[rowIdx] += abs(p0 - q0);
4232        }
4233      }
4234      rowIdx++;
4235    }
4236  }
4237 
4238  UInt64 colSADsum = 0;
4239  UInt64 rowSADsum = 0;
4240  for(Int c = 0; c < noCol-1; c++)
4241  {
4242    colSADsum += colSAD[c];
4243  }
4244  for(Int r = 0; r < noRows-1; r++)
4245  {
4246    rowSADsum += rowSAD[r];
4247  }
4248 
4249  colSADsum <<= 10;
4250  rowSADsum <<= 10;
4251  colSADsum /= (noCol-1);
4252  colSADsum /= picHeight;
4253  rowSADsum /= (noRows-1);
4254  rowSADsum /= picWidth;
4255 
4256  UInt64 avgSAD = ((colSADsum + rowSADsum)>>1);
4257  avgSAD >>= (g_bitDepthY-8);
4258 
4259  if ( avgSAD > 2048 )
4260  {
4261    avgSAD >>= 9;
4262    Int offset = Clip3(2,6,(Int)avgSAD);
4263    for (Int i=0; i<uiNumSlices; i++)
4264    {
4265      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(true);
4266      pcPic->getSlice(i)->setDeblockingFilterDisable(false);
4267      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( offset );
4268      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2( offset );
4269    }
4270  }
4271  else
4272  {
4273    for (Int i=0; i<uiNumSlices; i++)
4274    {
4275      pcPic->getSlice(i)->setDeblockingFilterOverrideFlag(false);
4276      pcPic->getSlice(i)->setDeblockingFilterDisable(        pcPic->getSlice(i)->getPPS()->getPicDisableDeblockingFilterFlag() );
4277      pcPic->getSlice(i)->setDeblockingFilterBetaOffsetDiv2( pcPic->getSlice(i)->getPPS()->getDeblockingFilterBetaOffsetDiv2() );
4278      pcPic->getSlice(i)->setDeblockingFilterTcOffsetDiv2(   pcPic->getSlice(i)->getPPS()->getDeblockingFilterTcOffsetDiv2()   );
4279    }
4280  }
4281 
4282  free(colSAD);
4283  free(rowSAD);
4284}
4285#if SVC_EXTENSION
4286#if LAYERS_NOT_PRESENT_SEI
4287SEILayersNotPresent* TEncGOP::xCreateSEILayersNotPresent ()
4288{
4289  UInt i = 0;
4290  SEILayersNotPresent *seiLayersNotPresent = new SEILayersNotPresent(); 
4291  seiLayersNotPresent->m_activeVpsId = m_pcCfg->getVPS()->getVPSId(); 
4292  seiLayersNotPresent->m_vpsMaxLayers = m_pcCfg->getVPS()->getMaxLayers();
4293  for ( ; i < seiLayersNotPresent->m_vpsMaxLayers; i++)
4294  {
4295    seiLayersNotPresent->m_layerNotPresentFlag[i] = true; 
4296  }
4297  for ( ; i < MAX_LAYERS; i++)
4298  {
4299    seiLayersNotPresent->m_layerNotPresentFlag[i] = false; 
4300  }
4301  return seiLayersNotPresent;
4302}
4303#endif
4304
4305#if N0383_IL_CONSTRAINED_TILE_SETS_SEI
4306SEIInterLayerConstrainedTileSets* TEncGOP::xCreateSEIInterLayerConstrainedTileSets()
4307{
4308  SEIInterLayerConstrainedTileSets *seiInterLayerConstrainedTileSets = new SEIInterLayerConstrainedTileSets();
4309  seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag = false;
4310  seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag = false;
4311  if (!seiInterLayerConstrainedTileSets->m_ilOneTilePerTileSetFlag)
4312  {
4313    seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 = m_pcCfg->getIlNumSetsInMessage() - 1;
4314    if (seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1)
4315    {
4316      seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = m_pcCfg->getSkippedTileSetPresentFlag();
4317    }
4318    else
4319    {
4320      seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag = false;
4321    }
4322    seiInterLayerConstrainedTileSets->m_ilNumSetsInMessageMinus1 += seiInterLayerConstrainedTileSets->m_skippedTileSetPresentFlag ? 1 : 0;
4323    for (UInt i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
4324    {
4325      seiInterLayerConstrainedTileSets->m_ilctsId[i] = i;
4326      seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i] = 0;
4327      for( UInt j = 0; j <= seiInterLayerConstrainedTileSets->m_ilNumTileRectsInSetMinus1[i]; j++)
4328      {
4329        seiInterLayerConstrainedTileSets->m_ilTopLeftTileIndex[i][j]     = m_pcCfg->getTopLeftTileIndex(i);
4330        seiInterLayerConstrainedTileSets->m_ilBottomRightTileIndex[i][j] = m_pcCfg->getBottomRightTileIndex(i);
4331      }
4332      seiInterLayerConstrainedTileSets->m_ilcIdc[i] = m_pcCfg->getIlcIdc(i);
4333      if (seiInterLayerConstrainedTileSets->m_ilAllTilesExactSampleValueMatchFlag)
4334      {
4335        seiInterLayerConstrainedTileSets->m_ilExactSampleValueMatchFlag[i] = false;
4336      }
4337    }
4338  }
4339
4340  return seiInterLayerConstrainedTileSets;
4341}
4342
4343Void TEncGOP::xBuildTileSetsMap(TComPicSym* picSym)
4344{
4345  Int numCUs = picSym->getFrameWidthInCU() * picSym->getFrameHeightInCU();
4346
4347  for (Int i = 0; i < numCUs; i++)
4348  {
4349    picSym->setTileSetIdxMap(i, -1, 0, false);
4350  }
4351
4352  for (Int i = 0; i < m_pcCfg->getIlNumSetsInMessage(); i++)
4353  {
4354    TComTile* topLeftTile     = picSym->getTComTile(m_pcCfg->getTopLeftTileIndex(i));
4355    TComTile* bottomRightTile = picSym->getTComTile(m_pcCfg->getBottomRightTileIndex(i));
4356    Int tileSetLeftEdgePosInCU = topLeftTile->getRightEdgePosInCU() - topLeftTile->getTileWidth() + 1;
4357    Int tileSetRightEdgePosInCU = bottomRightTile->getRightEdgePosInCU();
4358    Int tileSetTopEdgePosInCU = topLeftTile->getBottomEdgePosInCU() - topLeftTile->getTileHeight() + 1;
4359    Int tileSetBottomEdgePosInCU = bottomRightTile->getBottomEdgePosInCU();
4360    assert(tileSetLeftEdgePosInCU < tileSetRightEdgePosInCU && tileSetTopEdgePosInCU < tileSetBottomEdgePosInCU);
4361    for (Int j = tileSetTopEdgePosInCU; j <= tileSetBottomEdgePosInCU; j++)
4362    {
4363      for (Int k = tileSetLeftEdgePosInCU; k <= tileSetRightEdgePosInCU; k++)
4364      {
4365        picSym->setTileSetIdxMap(j * picSym->getFrameWidthInCU() + k, i, m_pcCfg->getIlcIdc(i), false);
4366      }
4367    }
4368  }
4369 
4370  if (m_pcCfg->getSkippedTileSetPresentFlag())
4371  {
4372    Int skippedTileSetIdx = m_pcCfg->getIlNumSetsInMessage();
4373    for (Int i = 0; i < numCUs; i++)
4374    {
4375      if (picSym->getTileSetIdxMap(i) < 0)
4376      {
4377        picSym->setTileSetIdxMap(i, skippedTileSetIdx, 0, true);
4378      }
4379    }
4380  }
4381}
4382#endif
4383
4384#if O0164_MULTI_LAYER_HRD
4385SEIScalableNesting* TEncGOP::xCreateBspNestingSEI(TComSlice *pcSlice)
4386{
4387  SEIScalableNesting *seiScalableNesting = new SEIScalableNesting();
4388  SEIBspInitialArrivalTime *seiBspInitialArrivalTime = new SEIBspInitialArrivalTime();
4389  SEIBspNesting *seiBspNesting = new SEIBspNesting();
4390  SEIBufferingPeriod *seiBufferingPeriod = new SEIBufferingPeriod();
4391
4392  // Scalable nesting SEI
4393
4394  seiScalableNesting->m_bitStreamSubsetFlag           = 1;      // If the nested SEI messages are picture buffereing SEI mesages, picure timing SEI messages or sub-picture timing SEI messages, bitstream_subset_flag shall be equal to 1
4395  seiScalableNesting->m_nestingOpFlag                 = 1;
4396  seiScalableNesting->m_defaultOpFlag                 = 0;
4397  seiScalableNesting->m_nestingNumOpsMinus1           = 0;      //nesting_num_ops_minus1
4398  seiScalableNesting->m_nestingOpIdx[0]               = 1;
4399  seiScalableNesting->m_allLayersFlag                 = 0;
4400  seiScalableNesting->m_nestingNoOpMaxTemporalIdPlus1 = 6 + 1;  //nesting_no_op_max_temporal_id_plus1
4401  seiScalableNesting->m_nestingNumLayersMinus1        = 1 - 1;  //nesting_num_layers_minus1
4402  seiScalableNesting->m_nestingLayerId[0]             = 0;
4403  seiScalableNesting->m_callerOwnsSEIs                = true;
4404
4405  // Bitstream partition nesting SEI
4406
4407  seiBspNesting->m_bspIdx = 0;
4408  seiBspNesting->m_callerOwnsSEIs = true;
4409
4410  // Buffering period SEI
4411
4412  UInt uiInitialCpbRemovalDelay = (90000/2);                      // 0.5 sec
4413  seiBufferingPeriod->m_initialCpbRemovalDelay      [0][0]     = uiInitialCpbRemovalDelay;
4414  seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][0]     = uiInitialCpbRemovalDelay;
4415  seiBufferingPeriod->m_initialCpbRemovalDelay      [0][1]     = uiInitialCpbRemovalDelay;
4416  seiBufferingPeriod->m_initialCpbRemovalDelayOffset[0][1]     = uiInitialCpbRemovalDelay;
4417
4418  Double dTmp = (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getNumUnitsInTick() / (Double)pcSlice->getSPS()->getVuiParameters()->getTimingInfo()->getTimeScale();
4419
4420  UInt uiTmp = (UInt)( dTmp * 90000.0 ); 
4421  uiInitialCpbRemovalDelay -= uiTmp;
4422  uiInitialCpbRemovalDelay -= uiTmp / ( pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2 );
4423  seiBufferingPeriod->m_initialAltCpbRemovalDelay      [0][0]  = uiInitialCpbRemovalDelay;
4424  seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][0]  = uiInitialCpbRemovalDelay;
4425  seiBufferingPeriod->m_initialAltCpbRemovalDelay      [0][1]  = uiInitialCpbRemovalDelay;
4426  seiBufferingPeriod->m_initialAltCpbRemovalDelayOffset[0][1]  = uiInitialCpbRemovalDelay;
4427
4428  seiBufferingPeriod->m_rapCpbParamsPresentFlag              = 0;
4429  //for the concatenation, it can be set to one during splicing.
4430  seiBufferingPeriod->m_concatenationFlag = 0;
4431  //since the temporal layer HRD is not ready, we assumed it is fixed
4432  seiBufferingPeriod->m_auCpbRemovalDelayDelta = 1;
4433  seiBufferingPeriod->m_cpbDelayOffset = 0;
4434  seiBufferingPeriod->m_dpbDelayOffset = 0;
4435
4436  // Intial arrival time SEI message
4437
4438  seiBspInitialArrivalTime->m_nalInitialArrivalDelay[0] = 0;
4439  seiBspInitialArrivalTime->m_vclInitialArrivalDelay[0] = 0;
4440
4441
4442  seiBspNesting->m_nestedSEIs.push_back(seiBufferingPeriod);
4443  seiBspNesting->m_nestedSEIs.push_back(seiBspInitialArrivalTime);
4444  seiScalableNesting->m_nestedSEIs.push_back(seiBspNesting); // BSP nesting SEI is contained in scalable nesting SEI
4445
4446  return seiScalableNesting;
4447}
4448#endif
4449
4450#if Q0048_CGS_3D_ASYMLUT
4451Void TEncGOP::xDetermin3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS )
4452{
4453  Int nCGSFlag = pSlice->getPPS()->getCGSFlag();
4454  m_Enc3DAsymLUTPPS.setPPSBit( 0 );
4455  Double dErrorUpdatedPPS = 0 , dErrorPPS = 0;
4456  dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() );
4457  if( bSignalPPS )
4458  {
4459    m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4460    pSlice->setCGSOverWritePPS( 1 ); // regular PPS update
4461  }
4462  else if( nCGSFlag )
4463  {
4464    dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc );
4465    Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9;
4466    pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS );
4467    if( pSlice->getCGSOverWritePPS() )
4468    {
4469      m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
4470    }
4471  }
4472  pSlice->getPPS()->setCGSOutputBitDepthY( m_Enc3DAsymLUTPPS.getOutputBitDepthY() );
4473  pSlice->getPPS()->setCGSOutputBitDepthC( m_Enc3DAsymLUTPPS.getOutputBitDepthC() );
4474}
4475
4476Void TEncGOP::downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest)
4477{
4478  Int inputBitDepth = g_bitDepthYLayer[m_layerId];
4479  Int outputBitDepth = g_bitDepthYLayer[m_layerId];
4480  {
4481    pcYuvSrc->setBorderExtension(false);
4482    pcYuvSrc->extendPicBorder   (); // extend the border.
4483    pcYuvSrc->setBorderExtension(false);
4484
4485    Int iWidth = pcYuvSrc->getWidth();
4486    Int iHeight =pcYuvSrc->getHeight(); 
4487
4488    if(!m_temp)
4489    {
4490      initDs(iWidth, iHeight, m_pcCfg->getIntraPeriod()>1);
4491    }
4492
4493    filterImg(pcYuvSrc->getLumaAddr(), pcYuvSrc->getStride(), pcYuvDest->getLumaAddr(), pcYuvDest->getStride(), iHeight, iWidth,  inputBitDepth-outputBitDepth, 0);
4494    filterImg(pcYuvSrc->getCbAddr(), pcYuvSrc->getCStride(), pcYuvDest->getCbAddr(), pcYuvDest->getCStride(), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 1);
4495    filterImg(pcYuvSrc->getCrAddr(), pcYuvSrc->getCStride(), pcYuvDest->getCrAddr(), pcYuvDest->getCStride(), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 2); 
4496  }
4497}
4498const Int TEncGOP::m_phase_filter_0_t0[4][13]={
4499  {0,  2,  -3,  -9,   6,  39,  58,  39,   6,  -9,  -3,  2,  0}, 
4500  {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},  //
4501  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4502  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4503};
4504
4505const Int TEncGOP::m_phase_filter_0_t1[4][13]={
4506  {0,  4,  0,  -12, 0,  40,  64,  40, 0, -12,  0,  4,  0},
4507  {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},  //
4508  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4509  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4510};
4511const Int TEncGOP::m_phase_filter_0_t1_chroma[4][13]={
4512  {0,  0,  0,   0,  0,   0,  128, 0,  0,  0,  0,  0,  0},
4513  {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},  //
4514  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1}, 
4515  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1} 
4516};
4517
4518const Int TEncGOP::m_phase_filter_1[8][13]={
4519  {0,   0,  5,  -6,  -10,37,  76,  37,-10,   -6, 5,  0,   0},   
4520  {0,  -1,  5,  -3,  -12,29,  75,  45,  -7,   -8, 5,  0,   0},   
4521  {0,  -1,  4,  -1,  -13,22,  73,  52,  -3,  -10, 4,  1,   0},   
4522  {0,  -1,  4,   1,  -13,14,  70,  59,   2,  -12, 3,  2,  -1}, 
4523  {0,  -1,  3,   2,  -13, 8,  65,  65,   8,  -13, 2,  3,  -1},   
4524  {0,  -1,  2,   3,  -12, 2,  59,  70,  14,  -13, 1,  4,  -1},   
4525  {0,   0,  1,   4,  -10,-3,  52,  73,  22,  -13,-1,  4,  -1},   
4526  {0,   0,  0,   5,   -8,-7,  45,  75,  29,  -12,-3,  5,  -1}   
4527};
4528
4529#if CGS_GCC_NO_VECTORIZATION 
4530#ifdef __GNUC__
4531#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
4532#if GCC_VERSION > 40600
4533__attribute__((optimize("no-tree-vectorize")))
4534#endif
4535#endif
4536#endif
4537Void TEncGOP::filterImg(
4538    Pel           *src,
4539    Int           iSrcStride,
4540    Pel           *dst,
4541    Int           iDstStride,
4542    Int           height1, 
4543    Int           width1, 
4544    Int           shift,
4545    Int           plane)
4546{
4547  Int length = m_iTap;
4548  Int height2,width2;
4549  Int k,iSum;
4550  Int i0, div_i0, i1;
4551  Int j0, div_j0, j1;
4552  const Int *p_filter;
4553  Pel *p_src, *p_dst;
4554  Pel *p_src_line, *p_dst_line;
4555  Int **p_temp, *p_tmp;
4556  Int shift2 = 2*7+shift;
4557  Int shift_round = (1 << (shift2 - 1));
4558  Int iMax = (1<<(g_bitDepthY-shift))-1;
4559  height2 = (height1 * m_iM) / m_iN;
4560  width2  = (width1  * m_iM) / m_iN;
4561
4562  m_phase_filter = plane? m_phase_filter_chroma : m_phase_filter_luma;
4563
4564  // horizontal filtering
4565  p_src_line = src;
4566  for(j1 = 0; j1 < height1; j1++)
4567  {
4568    i0=-m_iN;
4569    p_tmp = m_temp[j1];
4570   
4571    for(i1 = 0; i1 < width2; i1++)
4572    {
4573      i0      += m_iN;
4574      div_i0   = (i0 / m_iM);
4575      p_src    =  p_src_line + ( div_i0 - (length >> 1));
4576      p_filter = m_phase_filter[i0 - div_i0 * m_iM]; // phase_filter[i0 % M]
4577      iSum     = 0;
4578      for(k = 0; k < length; k++)
4579      {
4580        iSum += (*p_src++) * (*p_filter++);
4581      }
4582      *p_tmp++ = iSum;
4583    }
4584    p_src_line +=  iSrcStride;
4585  }
4586
4587  // pad temp (vertical)
4588  for (k=-(length>>1); k<0; k++)
4589  {
4590    memcpy(m_temp[k], m_temp[0], width2*sizeof(Int));
4591  }
4592  for (k=height1; k<(height1+(length>>1)); k++)
4593  {
4594    memcpy(m_temp[k], m_temp[k-1], (width2)* sizeof(Int));
4595  }
4596
4597  // vertical filtering
4598  j0 = (plane == 0) ? -m_iN : -(m_iN-1);
4599 
4600  p_dst_line = dst;
4601  for(j1 = 0; j1 < height2; j1++)
4602  {
4603    j0      += m_iN;
4604    div_j0   = (j0 / m_iM);
4605    p_dst = p_dst_line;
4606    p_temp   = &m_temp[div_j0 - (length>>1)];
4607    p_filter = m_phase_filter[j0 - div_j0 * m_iM]; // phase_filter[j0 % M]
4608    for(i1 = 0; i1 < width2;i1++)
4609    {
4610      iSum=0;
4611      for(k = 0; k < length; k++)
4612      {
4613        iSum += p_temp[k][i1] * p_filter[k];
4614      }
4615      iSum=((iSum + shift_round) >> shift2);
4616      *p_dst++ = (Short)(iSum > iMax ? iMax : (iSum < 0 ? 0 : iSum));
4617    }
4618    p_dst_line += iDstStride;
4619  }
4620}
4621
4622Void TEncGOP::initDs(Int iWidth, Int iHeight, Int iType)
4623{
4624  m_iTap = 13;
4625  if(g_posScalingFactor[0][0] == (1<<15))
4626  {
4627    m_iM = 4;
4628    m_iN = 8;
4629    m_phase_filter_luma = iType? m_phase_filter_0_t1 : m_phase_filter_0_t0;
4630    m_phase_filter_chroma = m_phase_filter_0_t1_chroma; 
4631  }
4632  else
4633  {
4634    m_iM = 8;
4635    m_iN = 12;
4636    m_phase_filter_luma = m_phase_filter_chroma =  m_phase_filter_1;
4637    m_phase_filter = m_phase_filter_1;
4638  }
4639
4640  get_mem2DintWithPad (&m_temp, iHeight, iWidth*m_iM/m_iN,   m_iTap>>1, 0);
4641}
4642
4643Int TEncGOP::get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX)
4644{
4645  Int i;
4646  Int *curr = NULL;
4647  Int iHeight, iWidth;
4648
4649  iHeight = dim0+2*iPadY;
4650  iWidth = dim1+2*iPadX;
4651  (*array2D) = (Int**)malloc(iHeight*sizeof(Int*));
4652  *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth);
4653
4654  (*array2D)[0] += iPadX;
4655  curr = (*array2D)[0];
4656  for(i = 1 ; i < iHeight; i++)
4657  {
4658    curr += iWidth;
4659    (*array2D)[i] = curr;
4660  }
4661  (*array2D) = &((*array2D)[iPadY]);
4662
4663  return 0;
4664}
4665
4666Void TEncGOP::free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX)
4667{
4668  if (array2D)
4669  {
4670    if (*array2D)
4671    {
4672      xFree(array2D[-iPadY]-iPadX);
4673    }
4674    else 
4675    {
4676      printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
4677    }
4678
4679    free (&array2D[-iPadY]);
4680  } 
4681  else
4682  {
4683    printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
4684  }
4685}
4686#endif
4687#endif //SVC_EXTENSION
4688
4689//! \}
Note: See TracBrowser for help on using the repository browser.