source: 3DVCSoftware/branches/HTM-5.0-Sony/source/Lib/TLibEncoder/TEncGOP.cpp @ 368

Last change on this file since 368 was 195, checked in by tech, 12 years ago

Changed macro switch names to match conventions.

  • Property svn:eol-style set to native
File size: 96.4 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-2012, 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
41#include "TEncTop.h"
42#include "TEncGOP.h"
43#include "TEncAnalyze.h"
44#include "libmd5/MD5.h"
45#include "TLibCommon/SEI.h"
46#include "TLibCommon/NAL.h"
47#include "NALwrite.h"
48#include "../../App/TAppEncoder/TAppEncTop.h"
49
50#include <time.h>
51#include <math.h>
52
53using namespace std;
54
55//! \ingroup TLibEncoder
56//! \{
57
58// ====================================================================================================================
59// Constructor / destructor / initialization / destroy
60// ====================================================================================================================
61
62TEncGOP::TEncGOP()
63{
64  m_iLastIDR            = 0;
65  m_iGopSize            = 0;
66  m_iNumPicCoded        = 0; //Niko
67  m_bFirst              = true;
68 
69  m_pcCfg               = NULL;
70  m_pcSliceEncoder      = NULL;
71  m_pcListPic           = NULL;
72 
73  m_pcEntropyCoder      = NULL;
74  m_pcCavlcCoder        = NULL;
75  m_pcSbacCoder         = NULL;
76  m_pcBinCABAC          = NULL;
77#if DEPTH_MAP_GENERATION
78  m_pcDepthMapGenerator = NULL;
79#endif
80#if HHI_INTER_VIEW_RESIDUAL_PRED
81  m_pcResidualGenerator = NULL;
82#endif
83 
84  m_bSeqFirst           = true;
85 
86  m_bRefreshPending     = 0;
87  m_pocCRA              = 0;
88
89  return;
90}
91
92TEncGOP::~TEncGOP()
93{
94}
95
96/** Create list to contain pointers to LCU start addresses of slice.
97 * \param iWidth, iHeight are picture width, height. iMaxCUWidth, iMaxCUHeight are LCU width, height.
98 */
99Void  TEncGOP::create( Int iWidth, Int iHeight, UInt iMaxCUWidth, UInt iMaxCUHeight )
100{
101  UInt uiWidthInCU       = ( iWidth %iMaxCUWidth  ) ? iWidth /iMaxCUWidth  + 1 : iWidth /iMaxCUWidth;
102  UInt uiHeightInCU      = ( iHeight%iMaxCUHeight ) ? iHeight/iMaxCUHeight + 1 : iHeight/iMaxCUHeight;
103  UInt uiNumCUsInFrame   = uiWidthInCU * uiHeightInCU;
104  m_uiStoredStartCUAddrForEncodingSlice = new UInt [uiNumCUsInFrame*(1<<(g_uiMaxCUDepth<<1))+1];
105  m_uiStoredStartCUAddrForEncodingEntropySlice = new UInt [uiNumCUsInFrame*(1<<(g_uiMaxCUDepth<<1))+1];
106  m_bLongtermTestPictureHasBeenCoded = 0;
107  m_bLongtermTestPictureHasBeenCoded2 = 0;
108}
109
110Void  TEncGOP::destroy()
111{
112  delete [] m_uiStoredStartCUAddrForEncodingSlice; m_uiStoredStartCUAddrForEncodingSlice = NULL;
113  delete [] m_uiStoredStartCUAddrForEncodingEntropySlice; m_uiStoredStartCUAddrForEncodingEntropySlice = NULL;
114}
115
116Void TEncGOP::init ( TEncTop* pcTEncTop )
117{
118  m_pcEncTop     = pcTEncTop;
119  m_pcCfg                = pcTEncTop;
120  m_pcSliceEncoder       = pcTEncTop->getSliceEncoder();
121  m_pcListPic            = pcTEncTop->getListPic();
122 
123  m_pcEntropyCoder       = pcTEncTop->getEntropyCoder();
124  m_pcCavlcCoder         = pcTEncTop->getCavlcCoder();
125  m_pcSbacCoder          = pcTEncTop->getSbacCoder();
126  m_pcBinCABAC           = pcTEncTop->getBinCABAC();
127  m_pcLoopFilter         = pcTEncTop->getLoopFilter();
128  m_pcBitCounter         = pcTEncTop->getBitCounter();
129 
130#if DEPTH_MAP_GENERATION
131  m_pcDepthMapGenerator  = pcTEncTop->getDepthMapGenerator();
132#endif
133#if HHI_INTER_VIEW_RESIDUAL_PRED
134  m_pcResidualGenerator  = pcTEncTop->getResidualGenerator();
135#endif
136 
137  // Adaptive Loop filter
138  m_pcAdaptiveLoopFilter = pcTEncTop->getAdaptiveLoopFilter();
139  //--Adaptive Loop filter
140  m_pcSAO                = pcTEncTop->getSAO();
141  m_pcRdCost             = pcTEncTop->getRdCost();
142}
143
144// ====================================================================================================================
145// Public member functions
146// ====================================================================================================================
147
148Void TEncGOP::initGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP)
149{
150  xInitGOP( iPOCLast, iNumPicRcvd, rcListPic, rcListPicYuvRecOut );
151  m_iNumPicCoded = 0;
152}
153
154Void TEncGOP::compressPicInGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP, Int iGOPid)
155{
156  TComPic*        pcPic;
157  TComPicYuv*     pcPicYuvRecOut;
158  TComSlice*      pcSlice;
159  TComOutputBitstream  *pcBitstreamRedirect;
160  pcBitstreamRedirect = new TComOutputBitstream;
161#if !REMOVE_TILE_DEPENDENCE
162  OutputNALUnit        *naluBuffered             = NULL;
163  Bool                  bIteratorAtListStart     = false;
164#endif
165  AccessUnit::iterator  itLocationToPushSliceHeaderNALU; // used to store location where NALU containing slice header is to be inserted
166  UInt                  uiOneBitstreamPerSliceLength = 0;
167  TEncSbac* pcSbacCoders = NULL;
168  TComOutputBitstream* pcSubstreamsOut = NULL;
169
170  {
171      UInt uiColDir = 1;
172      //-- For time output for each slice
173      long iBeforeTime = clock();
174     
175      //select uiColDir
176      Int iCloseLeft=1, iCloseRight=-1;
177      for(Int i = 0; i<m_pcCfg->getGOPEntry(iGOPid).m_numRefPics; i++) 
178      {
179        Int iRef = m_pcCfg->getGOPEntry(iGOPid).m_referencePics[i];
180        if(iRef>0&&(iRef<iCloseRight||iCloseRight==-1))
181        {
182          iCloseRight=iRef;
183        }
184        else if(iRef<0&&(iRef>iCloseLeft||iCloseLeft==1))
185        {
186          iCloseLeft=iRef;
187        }
188      }
189      if(iCloseRight>-1)
190      {
191        iCloseRight=iCloseRight+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
192      }
193      if(iCloseLeft<1) 
194      {
195        iCloseLeft=iCloseLeft+m_pcCfg->getGOPEntry(iGOPid).m_POC-1;
196        while(iCloseLeft<0)
197        {
198          iCloseLeft+=m_iGopSize;
199        }
200      }
201      Int iLeftQP=0, iRightQP=0;
202      for(Int i=0; i<m_iGopSize; i++)
203      {
204        if(m_pcCfg->getGOPEntry(i).m_POC==(iCloseLeft%m_iGopSize)+1)
205        {
206          iLeftQP= m_pcCfg->getGOPEntry(i).m_QPOffset;
207        }
208        if (m_pcCfg->getGOPEntry(i).m_POC==(iCloseRight%m_iGopSize)+1)
209        {
210          iRightQP=m_pcCfg->getGOPEntry(i).m_QPOffset;
211        }
212      }
213      if(iCloseRight>-1&&iRightQP<iLeftQP)
214      {
215        uiColDir=0;
216      }
217
218      /////////////////////////////////////////////////////////////////////////////////////////////////// Initial to start encoding
219      UInt uiPOCCurr = iPOCLast -iNumPicRcvd+ m_pcCfg->getGOPEntry(iGOPid).m_POC;
220      Int iTimeOffset = m_pcCfg->getGOPEntry(iGOPid).m_POC;
221      if(iPOCLast == 0)
222      {
223        uiPOCCurr=0;
224        iTimeOffset = 1;
225      }
226      if(uiPOCCurr>=m_pcCfg->getFrameToBeEncoded())
227      {
228        return;
229      }       
230      if( getNalUnitTypeBaseViewMvc( uiPOCCurr ) == NAL_UNIT_CODED_SLICE_IDR )
231      {
232        m_iLastIDR = uiPOCCurr;
233      }       
234
235      /* start a new access unit: create an entry in the list of output
236       * access units */
237      accessUnitsInGOP.push_back(AccessUnit());
238      AccessUnit& accessUnit = accessUnitsInGOP.back();
239      xGetBuffer( rcListPic, rcListPicYuvRecOut, iNumPicRcvd, iTimeOffset, pcPic, pcPicYuvRecOut, uiPOCCurr );
240     
241      //  Slice data initialization
242      pcPic->clearSliceBuffer();
243      assert(pcPic->getNumAllocatedSlice() == 1);
244      m_pcSliceEncoder->setSliceIdx(0);
245      pcPic->setCurrSliceIdx(0);
246
247      std::vector<TComAPS>& vAPS = m_pcEncTop->getAPS();
248#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
249    m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, uiPOCCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getEncTop()->getVPS(), m_pcEncTop->getSPS(), m_pcEncTop->getPPS() );
250#else
251      m_pcSliceEncoder->initEncSlice ( pcPic, iPOCLast, uiPOCCurr, iNumPicRcvd, iGOPid, pcSlice, m_pcEncTop->getSPS(), m_pcEncTop->getPPS() );
252#endif
253      pcSlice->setLastIDR(m_iLastIDR);
254      pcSlice->setSliceIdx(0);
255      pcSlice->setViewId( m_pcEncTop->getViewId() );
256      pcSlice->setIsDepth( m_pcEncTop->getIsDepth() ); 
257
258      m_pcEncTop->getSPS()->setDisInter4x4(m_pcEncTop->getDisInter4x4());
259      pcSlice->setScalingList ( m_pcEncTop->getScalingList()  );
260      if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_OFF)
261      {
262        m_pcEncTop->getTrQuant()->setFlatScalingList();
263        m_pcEncTop->getTrQuant()->setUseScalingList(false);
264      }
265      else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_DEFAULT)
266      {
267        pcSlice->setDefaultScalingList ();
268        pcSlice->getScalingList()->setScalingListPresentFlag(true);
269        m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
270        m_pcEncTop->getTrQuant()->setUseScalingList(true);
271      }
272      else if(m_pcEncTop->getUseScalingListId() == SCALING_LIST_FILE_READ)
273      {
274        if(pcSlice->getScalingList()->xParseScalingList(m_pcCfg->getScalingListFile()))
275        {
276          pcSlice->setDefaultScalingList ();
277        }
278#if SCALING_LIST
279        pcSlice->getScalingList()->checkDcOfMatrix();
280#endif
281        pcSlice->getScalingList()->setScalingListPresentFlag(pcSlice->checkDefaultScalingList());
282        m_pcEncTop->getTrQuant()->setScalingList(pcSlice->getScalingList());
283        m_pcEncTop->getTrQuant()->setUseScalingList(true);
284      }
285      else
286      {
287        printf("error : ScalingList == %d no support\n",m_pcEncTop->getUseScalingListId());
288        assert(0);
289      }
290
291#if HHI_INTERVIEW_SKIP
292      if ( m_pcEncTop->getInterViewSkip() )
293      {
294        m_pcEncTop->getEncTop()->getUsedPelsMap( pcPic->getViewId(), pcPic->getPOC(), pcPic->getUsedPelsMap() );
295      }
296#endif
297      //  Slice info. refinement
298      if( pcSlice->getSliceType() == B_SLICE )
299      {
300#if QC_REM_IDV_B0046
301      if( m_pcCfg->getGOPEntry(pcSlice->getSPS()->getViewId() && ((getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR) || (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_CRA))? MAX_GOP : iGOPid ).m_sliceType == 'P' ) { pcSlice->setSliceType( P_SLICE ); }
302#else
303      if( m_pcCfg->getGOPEntry( (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDV) ? MAX_GOP : iGOPid ).m_sliceType == 'P' ) { pcSlice->setSliceType( P_SLICE ); }
304#endif
305    }
306
307      // Set the nal unit type
308      pcSlice->setNalUnitType( getNalUnitType(uiPOCCurr) );
309      pcSlice->setNalUnitTypeBaseViewMvc( getNalUnitTypeBaseViewMvc(uiPOCCurr) );
310
311      // Do decoding refresh marking if any
312      pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
313
314      if ( !pcSlice->getPPS()->getEnableTMVPFlag() && pcPic->getTLayer() == 0 )
315      {
316        pcSlice->decodingMarkingForNoTMVP( rcListPic, pcSlice->getPOC() );
317      }
318
319      m_pcEncTop->selectReferencePictureSet(pcSlice, uiPOCCurr, iGOPid,rcListPic);
320      pcSlice->getRPS()->setNumberOfLongtermPictures(0);
321
322      if(pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0)
323      {
324         pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS());
325      }
326      pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS());
327
328#if H0566_TLA && H0566_TLA_SET_FOR_SWITCHING_POINTS
329      if(pcSlice->getTLayer() > 0)
330      {
331        if(pcSlice->isTemporalLayerSwitchingPoint(rcListPic, pcSlice->getRPS()))
332        {
333          pcSlice->setNalUnitType(NAL_UNIT_CODED_SLICE_TLA);
334        }
335      }
336#endif
337
338#if !QC_REM_IDV_B0046
339      pcSlice->setNumRefIdx( REF_PIC_LIST_0, min( m_pcCfg->getGOPEntry( (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDV) ? MAX_GOP : iGOPid ).m_numRefPicsActive, (pcSlice->getRPS()->getNumberOfPictures() + pcSlice->getSPS()->getNumberOfUsableInterViewRefs()) ) );
340      pcSlice->setNumRefIdx( REF_PIC_LIST_1, min( m_pcCfg->getGOPEntry( (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDV) ? MAX_GOP : iGOPid ).m_numRefPicsActive, (pcSlice->getRPS()->getNumberOfPictures() + pcSlice->getSPS()->getNumberOfUsableInterViewRefs()) ) );
341#else
342
343    Bool bNalRAP = ((getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_CRA) || (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR)) && (pcSlice->getSPS()->getViewId())  ? 1: 0;
344    pcSlice->setNumRefIdx( REF_PIC_LIST_0, min( m_pcCfg->getGOPEntry( bNalRAP ? MAX_GOP : iGOPid ).m_numRefPicsActive, (pcSlice->getRPS()->getNumberOfPictures() + pcSlice->getSPS()->getNumberOfUsableInterViewRefs()) ) );
345    pcSlice->setNumRefIdx( REF_PIC_LIST_1, min( m_pcCfg->getGOPEntry( bNalRAP ? MAX_GOP : iGOPid ).m_numRefPicsActive, (pcSlice->getRPS()->getNumberOfPictures() + pcSlice->getSPS()->getNumberOfUsableInterViewRefs()) ) );
346#endif
347    TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
348    refPicListModification->setRefPicListModificationFlagL0( false );
349#if !H0137_0138_LIST_MODIFICATION
350      refPicListModification->setNumberOfRefPicListModificationsL0(0);
351#endif
352      refPicListModification->setRefPicListModificationFlagL1( false );
353#if !H0137_0138_LIST_MODIFICATION
354      refPicListModification->setNumberOfRefPicListModificationsL1(0);
355#endif
356      xSetRefPicListModificationsMvc( pcSlice, uiPOCCurr, iGOPid );
357
358#if ADAPTIVE_QP_SELECTION
359      pcSlice->setTrQuant( m_pcEncTop->getTrQuant() );
360#endif     
361      //  Set reference list
362      TAppEncTop* tAppEncTop = m_pcEncTop->getEncTop();
363      assert( tAppEncTop != NULL );
364
365      TComPic * const pcTexturePic = m_pcEncTop->getIsDepth() ? tAppEncTop->getPicFromView( m_pcEncTop->getViewId(), pcSlice->getPOC(), false ) : NULL;
366      assert( !m_pcEncTop->getIsDepth() || pcTexturePic != NULL );
367      pcSlice->setTexturePic( pcTexturePic );
368
369      std::vector<TComPic*> apcInterViewRefPics = tAppEncTop->getInterViewRefPics( m_pcEncTop->getViewId(), pcSlice->getPOC(), m_pcEncTop->getIsDepth(), pcSlice->getSPS() );
370      pcSlice->setRefPicListMvc( rcListPic, apcInterViewRefPics );
371
372      //  Slice info. refinement
373      if( pcSlice->getSliceType() == B_SLICE )
374      {
375#if !QC_REM_IDV_B0046
376        if( m_pcCfg->getGOPEntry( (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDV) ? MAX_GOP : iGOPid ).m_sliceType == 'P' ) { pcSlice->setSliceType( P_SLICE ); }
377#else
378      Bool bRAP = ((getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_CRA) || (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR)) && (pcSlice->getSPS()->getViewId())  ? 1: 0;
379      if( m_pcCfg->getGOPEntry( bRAP ? MAX_GOP : iGOPid ).m_sliceType == 'P' ) { pcSlice->setSliceType( P_SLICE ); }
380#endif
381      }
382     
383      if (pcSlice->getSliceType() != B_SLICE || !pcSlice->getSPS()->getUseLComb())
384      {
385        pcSlice->setNumRefIdx(REF_PIC_LIST_C, 0);
386        pcSlice->setRefPicListCombinationFlag(false);
387        pcSlice->setRefPicListModificationFlagLC(false);
388      }
389      else
390      {
391        pcSlice->setRefPicListCombinationFlag(pcSlice->getSPS()->getUseLComb());
392        pcSlice->setRefPicListModificationFlagLC(pcSlice->getSPS()->getLCMod());
393        pcSlice->setNumRefIdx(REF_PIC_LIST_C, pcSlice->getNumRefIdx(REF_PIC_LIST_0));
394      }
395     
396      if (pcSlice->getSliceType() == B_SLICE)
397      {
398        pcSlice->setColDir(uiColDir);
399        Bool bLowDelay = true;
400        Int  iCurrPOC  = pcSlice->getPOC();
401        Int iRefIdx = 0;
402
403        for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_0) && bLowDelay; iRefIdx++)
404        {
405          if ( pcSlice->getRefPic(REF_PIC_LIST_0, iRefIdx)->getPOC() > iCurrPOC )
406          {
407            bLowDelay = false;
408          }
409        }
410        for (iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(REF_PIC_LIST_1) && bLowDelay; iRefIdx++)
411        {
412          if ( pcSlice->getRefPic(REF_PIC_LIST_1, iRefIdx)->getPOC() > iCurrPOC )
413          {
414            bLowDelay = false;
415          }
416        }
417
418        pcSlice->setCheckLDC(bLowDelay); 
419      }
420     
421      uiColDir = 1-uiColDir;
422     
423      //-------------------------------------------------------------
424      pcSlice->setRefPOCnViewListsMvc();
425     
426      pcSlice->setNoBackPredFlag( false );
427      if ( pcSlice->getSliceType() == B_SLICE && !pcSlice->getRefPicListCombinationFlag())
428      {
429        if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
430        {
431          pcSlice->setNoBackPredFlag( true );
432          int i;
433          for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
434          {
435            if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
436            {
437              pcSlice->setNoBackPredFlag( false );
438              break;
439            }
440          }
441        }
442      }
443
444      if(pcSlice->getNoBackPredFlag())
445      {
446        pcSlice->setNumRefIdx(REF_PIC_LIST_C, 0);
447      }
448      pcSlice->generateCombinedList();
449     
450#if HHI_VSO
451  Bool bUseVSO = m_pcEncTop->getUseVSO();
452  m_pcRdCost->setUseVSO( bUseVSO );
453#if SAIT_VSO_EST_A0033
454  m_pcRdCost->setUseEstimatedVSD( m_pcEncTop->getUseEstimatedVSD() );
455#endif
456
457  if ( bUseVSO )
458  {
459    Int iVSOMode = m_pcEncTop->getVSOMode();
460    m_pcRdCost->setVSOMode( iVSOMode  );
461
462#if HHI_VSO_DIST_INT
463    m_pcRdCost->setAllowNegDist( m_pcEncTop->getAllowNegDist() );
464#endif
465
466
467#if SAIT_VSO_EST_A0033
468    m_pcRdCost->setVideoRecPicYuv( m_pcEncTop->getEncTop()->getPicYuvFromView( pcSlice->getViewId(), pcSlice->getPOC(), false, true ) );
469    m_pcRdCost->setDepthPicYuv   ( m_pcEncTop->getEncTop()->getPicYuvFromView( pcSlice->getViewId(), pcSlice->getPOC(), true, false ) );
470#endif
471#if LGE_WVSO_A0119
472    Bool bUseWVSO  = m_pcEncTop->getUseWVSO();
473    m_pcRdCost->setUseWVSO( bUseWVSO );
474#endif
475
476  }
477#endif
478      /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
479      //  Slice compression
480      if (m_pcCfg->getUseASR())
481      {
482        m_pcSliceEncoder->setSearchRange(pcSlice);
483      }
484
485#if H0111_MVD_L1_ZERO
486      Bool bGPBcheck=false;
487      if ( pcSlice->getSliceType() == B_SLICE)
488      {
489        if ( pcSlice->getNumRefIdx(RefPicList( 0 ) ) == pcSlice->getNumRefIdx(RefPicList( 1 ) ) )
490        {
491          bGPBcheck=true;
492          int i;
493          for ( i=0; i < pcSlice->getNumRefIdx(RefPicList( 1 ) ); i++ )
494          {
495            if ( pcSlice->getRefPOC(RefPicList(1), i) != pcSlice->getRefPOC(RefPicList(0), i) ) 
496            {
497              bGPBcheck=false;
498              break;
499            }
500          }
501        }
502      }
503      if(bGPBcheck)
504      {
505        pcSlice->setMvdL1ZeroFlag(true);
506      }
507      else
508      {
509        pcSlice->setMvdL1ZeroFlag(false);
510      }
511      pcPic->getSlice(pcSlice->getSliceIdx())->setMvdL1ZeroFlag(pcSlice->getMvdL1ZeroFlag());
512#endif
513
514      UInt uiNumSlices = 1;
515
516      UInt uiInternalAddress = pcPic->getNumPartInCU()-4;
517      UInt uiExternalAddress = pcPic->getPicSym()->getNumberOfCUsInFrame()-1;
518      UInt uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
519      UInt uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
520      UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
521      UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
522      while(uiPosX>=uiWidth||uiPosY>=uiHeight) 
523      {
524        uiInternalAddress--;
525        uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
526        uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
527      }
528      uiInternalAddress++;
529      if(uiInternalAddress==pcPic->getNumPartInCU()) 
530      {
531        uiInternalAddress = 0;
532        uiExternalAddress++;
533      }
534      UInt uiRealEndAddress = uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress;
535
536    UInt uiCummulativeTileWidth;
537    UInt uiCummulativeTileHeight;
538    Int  p, j;
539    UInt uiEncCUAddr;
540   
541#if !REMOVE_TILE_DEPENDENCE
542    if(pcSlice->getPPS()->getTileBehaviorControlPresentFlag() == 1)
543    {
544      pcPic->getPicSym()->setTileBoundaryIndependenceIdr( pcSlice->getPPS()->getTileBoundaryIndependenceIdr() );
545    }
546    else
547    {
548      pcPic->getPicSym()->setTileBoundaryIndependenceIdr( pcSlice->getPPS()->getSPS()->getTileBoundaryIndependenceIdr() );
549
550    }
551#endif
552
553    if( pcSlice->getPPS()->getColumnRowInfoPresent() == 1 )    //derive the tile parameters from PPS
554    {
555      //set NumColumnsMinus1 and NumRowsMinus1
556      pcPic->getPicSym()->setNumColumnsMinus1( pcSlice->getPPS()->getNumColumnsMinus1() );
557      pcPic->getPicSym()->setNumRowsMinus1( pcSlice->getPPS()->getNumRowsMinus1() );
558
559      //create the TComTileArray
560      pcPic->getPicSym()->xCreateTComTileArray();
561
562      if( pcSlice->getPPS()->getUniformSpacingIdr() == 1 )
563      {
564        //set the width for each tile
565        for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
566        {
567          for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1()+1; p++)
568          {
569            pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->
570              setTileWidth( (p+1)*pcPic->getPicSym()->getFrameWidthInCU()/(pcPic->getPicSym()->getNumColumnsMinus1()+1) 
571              - (p*pcPic->getPicSym()->getFrameWidthInCU())/(pcPic->getPicSym()->getNumColumnsMinus1()+1) );
572          }
573        }
574
575        //set the height for each tile
576        for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
577        {
578          for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1()+1; p++)
579          {
580            pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->
581              setTileHeight( (p+1)*pcPic->getPicSym()->getFrameHeightInCU()/(pcPic->getPicSym()->getNumRowsMinus1()+1) 
582              - (p*pcPic->getPicSym()->getFrameHeightInCU())/(pcPic->getPicSym()->getNumRowsMinus1()+1) );   
583          }
584        }
585      }
586      else
587      {
588        //set the width for each tile
589        for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
590        {
591          uiCummulativeTileWidth = 0;
592          for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1(); p++)
593          {
594            pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->setTileWidth( pcSlice->getPPS()->getColumnWidth(p) );
595            uiCummulativeTileWidth += pcSlice->getPPS()->getColumnWidth(p);
596          }
597          pcPic->getPicSym()->getTComTile(j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p)->setTileWidth( pcPic->getPicSym()->getFrameWidthInCU()-uiCummulativeTileWidth );
598        }
599
600        //set the height for each tile
601        for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
602        {
603          uiCummulativeTileHeight = 0;
604          for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1(); p++)
605          {
606            pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->setTileHeight( pcSlice->getPPS()->getRowHeight(p) );
607            uiCummulativeTileHeight += pcSlice->getPPS()->getRowHeight(p);
608          }
609          pcPic->getPicSym()->getTComTile(p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j)->setTileHeight( pcPic->getPicSym()->getFrameHeightInCU()-uiCummulativeTileHeight );
610        }
611      }
612    }
613    else //derive the tile parameters from SPS
614    {
615      //set NumColumnsMins1 and NumRowsMinus1
616      pcPic->getPicSym()->setNumColumnsMinus1( pcSlice->getSPS()->getNumColumnsMinus1() );
617      pcPic->getPicSym()->setNumRowsMinus1( pcSlice->getSPS()->getNumRowsMinus1() );
618
619      //create the TComTileArray
620      pcPic->getPicSym()->xCreateTComTileArray();
621
622      if( pcSlice->getSPS()->getUniformSpacingIdr() == 1 )
623      {
624        //set the width for each tile
625        for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
626        {
627          for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1()+1; p++)
628          {
629            pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->
630              setTileWidth( (p+1)*pcPic->getPicSym()->getFrameWidthInCU()/(pcPic->getPicSym()->getNumColumnsMinus1()+1) 
631              - (p*pcPic->getPicSym()->getFrameWidthInCU())/(pcPic->getPicSym()->getNumColumnsMinus1()+1) );
632          }
633        }
634
635        //set the height for each tile
636        for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
637        {
638          for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1()+1; p++)
639          {
640            pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->
641              setTileHeight( (p+1)*pcPic->getPicSym()->getFrameHeightInCU()/(pcPic->getPicSym()->getNumRowsMinus1()+1) 
642              - (p*pcPic->getPicSym()->getFrameHeightInCU())/(pcPic->getPicSym()->getNumRowsMinus1()+1) );   
643          }
644        }
645      }
646
647      else
648      {
649        //set the width for each tile
650        for(j=0; j < pcPic->getPicSym()->getNumRowsMinus1()+1; j++)
651        {
652          uiCummulativeTileWidth = 0;
653          for(p=0; p < pcPic->getPicSym()->getNumColumnsMinus1(); p++)
654          {
655            pcPic->getPicSym()->getTComTile( j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p )->setTileWidth( pcSlice->getSPS()->getColumnWidth(p) );
656            uiCummulativeTileWidth += pcSlice->getSPS()->getColumnWidth(p);
657          }
658          pcPic->getPicSym()->getTComTile(j * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + p)->setTileWidth( pcPic->getPicSym()->getFrameWidthInCU()-uiCummulativeTileWidth );
659        }
660
661        //set the height for each tile
662        for(j=0; j < pcPic->getPicSym()->getNumColumnsMinus1()+1; j++)
663        {
664          uiCummulativeTileHeight = 0;
665          for(p=0; p < pcPic->getPicSym()->getNumRowsMinus1(); p++)
666          {
667            pcPic->getPicSym()->getTComTile( p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j )->setTileHeight( pcSlice->getSPS()->getRowHeight(p) );
668            uiCummulativeTileHeight += pcSlice->getSPS()->getRowHeight(p);
669          }
670          pcPic->getPicSym()->getTComTile(p * (pcPic->getPicSym()->getNumColumnsMinus1()+1) + j)->setTileHeight( pcPic->getPicSym()->getFrameHeightInCU()-uiCummulativeTileHeight );
671        }
672      }
673    }
674
675    //initialize each tile of the current picture
676    pcPic->getPicSym()->xInitTiles();
677
678    // Allocate some coders, now we know how many tiles there are.
679    Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
680   
681    //generate the Coding Order Map and Inverse Coding Order Map
682    for(p=0, uiEncCUAddr=0; p<pcPic->getPicSym()->getNumberOfCUsInFrame(); p++, uiEncCUAddr = pcPic->getPicSym()->xCalculateNxtCUAddr(uiEncCUAddr))
683    {
684      pcPic->getPicSym()->setCUOrderMap(p, uiEncCUAddr);
685      pcPic->getPicSym()->setInverseCUOrderMap(uiEncCUAddr, p);
686    }
687    pcPic->getPicSym()->setCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());   
688    pcPic->getPicSym()->setInverseCUOrderMap(pcPic->getPicSym()->getNumberOfCUsInFrame(), pcPic->getPicSym()->getNumberOfCUsInFrame());
689    if (pcSlice->getPPS()->getEntropyCodingMode())
690    {
691      // Allocate some coders, now we know how many tiles there are.
692      m_pcEncTop->createWPPCoders(iNumSubstreams);
693      pcSbacCoders = m_pcEncTop->getSbacCoders();
694      pcSubstreamsOut = new TComOutputBitstream[iNumSubstreams];
695    }
696
697      UInt uiStartCUAddrSliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEncodingSlice" containing locations of slice boundaries
698      UInt uiStartCUAddrSlice    = 0; // used to keep track of current slice's starting CU addr.
699      pcSlice->setSliceCurStartCUAddr( uiStartCUAddrSlice ); // Setting "start CU addr" for current slice
700      memset(m_uiStoredStartCUAddrForEncodingSlice, 0, sizeof(UInt) * (pcPic->getPicSym()->getNumberOfCUsInFrame()*pcPic->getNumPartInCU()+1));
701
702      UInt uiStartCUAddrEntropySliceIdx = 0; // used to index "m_uiStoredStartCUAddrForEntropyEncodingSlice" containing locations of slice boundaries
703      UInt uiStartCUAddrEntropySlice    = 0; // used to keep track of current Entropy slice's starting CU addr.
704      pcSlice->setEntropySliceCurStartCUAddr( uiStartCUAddrEntropySlice ); // Setting "start CU addr" for current Entropy slice
705     
706      memset(m_uiStoredStartCUAddrForEncodingEntropySlice, 0, sizeof(UInt) * (pcPic->getPicSym()->getNumberOfCUsInFrame()*pcPic->getNumPartInCU()+1));
707      UInt uiNextCUAddr = 0;
708      m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx++]                = uiNextCUAddr;
709      m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = uiNextCUAddr;
710
711#if DEPTH_MAP_GENERATION
712      // init view component and predict virtual depth map
713      m_pcDepthMapGenerator->initViewComponent( pcPic );
714#if !QC_MULTI_DIS_CAN_A0097
715      m_pcDepthMapGenerator->predictDepthMap  ( pcPic );
716#endif
717#endif
718#if HHI_INTER_VIEW_MOTION_PRED
719      m_pcDepthMapGenerator->covertOrgDepthMap( pcPic );
720#endif
721#if HHI_INTER_VIEW_RESIDUAL_PRED
722      m_pcResidualGenerator->initViewComponent( pcPic );
723#endif
724
725#if QC_SIMPLE_NBDV_B0047
726      if(pcSlice->getViewId() && pcSlice->getSPS()->getMultiviewMvPredMode())
727      {
728        Int iColPoc = pcSlice->getRefPOC(RefPicList(pcSlice->getColDir()), pcSlice->getColRefIdx());
729        pcPic->setRapbCheck(pcPic->getDisCandRefPictures(iColPoc));
730      }
731#endif
732      while(uiNextCUAddr<uiRealEndAddress) // determine slice boundaries
733      {
734        pcSlice->setNextSlice       ( false );
735        pcSlice->setNextEntropySlice( false );
736        assert(pcPic->getNumAllocatedSlice() == uiStartCUAddrSliceIdx);
737        m_pcSliceEncoder->precompressSlice( pcPic );
738        m_pcSliceEncoder->compressSlice   ( pcPic );
739
740        Bool bNoBinBitConstraintViolated = (!pcSlice->isNextSlice() && !pcSlice->isNextEntropySlice());
741        if (pcSlice->isNextSlice() || (bNoBinBitConstraintViolated && m_pcCfg->getSliceMode()==AD_HOC_SLICES_FIXED_NUMBER_OF_LCU_IN_SLICE))
742        {
743          uiStartCUAddrSlice                                              = pcSlice->getSliceCurEndCUAddr();
744          // Reconstruction slice
745          m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx++]  = uiStartCUAddrSlice;
746          // Entropy slice
747          if (uiStartCUAddrEntropySliceIdx>0 && m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx-1] != uiStartCUAddrSlice)
748          {
749            m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = uiStartCUAddrSlice;
750          }
751         
752          if (uiStartCUAddrSlice < uiRealEndAddress)
753          {
754            pcPic->allocateNewSlice();         
755            pcPic->setCurrSliceIdx                  ( uiStartCUAddrSliceIdx-1 );
756            m_pcSliceEncoder->setSliceIdx           ( uiStartCUAddrSliceIdx-1 );
757            pcSlice = pcPic->getSlice               ( uiStartCUAddrSliceIdx-1 );
758            pcSlice->copySliceInfo                  ( pcPic->getSlice(0)      );
759            pcSlice->setSliceIdx                    ( uiStartCUAddrSliceIdx-1 );
760            pcSlice->setSliceCurStartCUAddr         ( uiStartCUAddrSlice      );
761            pcSlice->setEntropySliceCurStartCUAddr  ( uiStartCUAddrSlice      );
762            pcSlice->setSliceBits(0);
763            uiNumSlices ++;
764          }
765        }
766        else if (pcSlice->isNextEntropySlice() || (bNoBinBitConstraintViolated && m_pcCfg->getEntropySliceMode()==SHARP_FIXED_NUMBER_OF_LCU_IN_ENTROPY_SLICE))
767        {
768          uiStartCUAddrEntropySlice                                                     = pcSlice->getEntropySliceCurEndCUAddr();
769          m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = uiStartCUAddrEntropySlice;
770          pcSlice->setEntropySliceCurStartCUAddr( uiStartCUAddrEntropySlice );
771        }
772        else
773        {
774          uiStartCUAddrSlice                                                            = pcSlice->getSliceCurEndCUAddr();
775          uiStartCUAddrEntropySlice                                                     = pcSlice->getEntropySliceCurEndCUAddr();
776        }       
777
778        uiNextCUAddr = (uiStartCUAddrSlice > uiStartCUAddrEntropySlice) ? uiStartCUAddrSlice : uiStartCUAddrEntropySlice;
779      }
780      m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx++]                = pcSlice->getSliceCurEndCUAddr();
781      m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx++]  = pcSlice->getSliceCurEndCUAddr();
782     
783      pcSlice = pcPic->getSlice(0);
784
785#if HHI_INTER_VIEW_RESIDUAL_PRED
786      // set residual picture
787      m_pcResidualGenerator->setRecResidualPic( pcPic );
788#endif
789#if DEPTH_MAP_GENERATION
790#if !QC_MULTI_DIS_CAN_A0097
791      // update virtual depth map
792      m_pcDepthMapGenerator->updateDepthMap( pcPic );
793#endif
794#endif
795
796      //-- Loop filter
797      Bool bLFCrossTileBoundary = (pcSlice->getPPS()->getTileBehaviorControlPresentFlag() == 1)?
798                                  (pcSlice->getPPS()->getLFCrossTileBoundaryFlag()):(pcSlice->getPPS()->getSPS()->getLFCrossTileBoundaryFlag());
799#if DBL_CONTROL
800      m_pcLoopFilter->setCfg(pcSlice->getPPS()->getDeblockingFilterControlPresent(), pcSlice->getLoopFilterDisable(), pcSlice->getLoopFilterBetaOffset(), pcSlice->getLoopFilterTcOffset(), bLFCrossTileBoundary);
801#else
802      m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), pcSlice->getLoopFilterBetaOffset(), pcSlice->getLoopFilterTcOffset(), bLFCrossTileBoundary);
803#endif
804      m_pcLoopFilter->loopFilterPic( pcPic );
805
806      pcSlice = pcPic->getSlice(0);
807      if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
808      {
809        Int sliceGranularity = pcSlice->getPPS()->getSliceGranularity();
810        pcPic->createNonDBFilterInfo(m_uiStoredStartCUAddrForEncodingSlice, uiNumSlices, sliceGranularity, pcSlice->getSPS()->getLFCrossSliceBoundaryFlag(),pcPic->getPicSym()->getNumTiles() ,bLFCrossTileBoundary);
811      }
812
813
814      pcSlice = pcPic->getSlice(0);
815
816      if(pcSlice->getSPS()->getUseSAO())
817      {
818        m_pcSAO->createPicSaoInfo(pcPic, uiNumSlices);
819      }
820
821#if LCU_SYNTAX_ALF
822      AlfParamSet* alfSliceParams = NULL;
823      std::vector<AlfCUCtrlInfo>* alfCUCtrlParam = NULL;
824#else
825      std::vector<AlfCUCtrlInfo> vAlfCUCtrlParam;
826#endif
827      pcSlice = pcPic->getSlice(0);
828
829      if(pcSlice->getSPS()->getUseALF())
830      {
831#if LCU_SYNTAX_ALF
832        m_pcAdaptiveLoopFilter->createPicAlfInfo(pcPic, uiNumSlices, pcSlice->getSliceQp());
833        m_pcAdaptiveLoopFilter->initALFEnc(m_pcCfg->getALFParamInSlice(), m_pcCfg->getALFPicBasedEncode(), uiNumSlices, alfSliceParams, alfCUCtrlParam);
834#else
835        vAlfCUCtrlParam.resize(uiNumSlices);
836        m_pcAdaptiveLoopFilter->createPicAlfInfo(pcPic, uiNumSlices);
837#endif
838      }
839
840      /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
841      // Set entropy coder
842      m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
843
844      /* write various header sets. */
845      if ( m_bSeqFirst )
846      {
847#if QC_MVHEVC_B0046
848      if(!m_pcEncTop->getLayerId())
849      {
850#endif
851#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
852        {
853          OutputNALUnit nalu(NAL_UNIT_VPS, true, m_pcEncTop->getLayerId());
854          m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
855          m_pcEntropyCoder->encodeVPS(m_pcEncTop->getEncTop()->getVPS());
856          writeRBSPTrailingBits(nalu.m_Bitstream);
857          accessUnit.push_back(new NALUnitEBSP(nalu));
858        }
859#endif
860#if NAL_REF_FLAG
861#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
862        OutputNALUnit nalu(NAL_UNIT_SPS, true, m_pcEncTop->getLayerId());
863#else
864        OutputNALUnit nalu(NAL_UNIT_SPS, true, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
865#endif
866#else
867        OutputNALUnit nalu(NAL_UNIT_SPS, NAL_REF_IDC_PRIORITY_HIGHEST, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
868#endif
869        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
870#if TILES_WPP_ENTRY_POINT_SIGNALLING
871        pcSlice->getSPS()->setNumSubstreams( pcSlice->getPPS()->getNumSubstreams() );
872#endif
873#if HHI_MPI
874        m_pcEntropyCoder->encodeSPS(pcSlice->getSPS(), m_pcEncTop->getIsDepth());
875#else
876        m_pcEntropyCoder->encodeSPS(pcSlice->getSPS());
877#endif
878        writeRBSPTrailingBits(nalu.m_Bitstream);
879        accessUnit.push_back(new NALUnitEBSP(nalu));
880
881#if NAL_REF_FLAG
882#if VIDYO_VPS_INTEGRATION|QC_MVHEVC_B0046
883#if QC_MVHEVC_B0046
884        nalu = NALUnit(NAL_UNIT_PPS, true, m_pcEncTop->getLayerId());
885#else
886        nalu = NALUnit(NAL_UNIT_PPS, true, m_pcEncTop->getLayerId());
887#endif
888#else
889        nalu = NALUnit(NAL_UNIT_PPS, true, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
890#endif
891#else
892        nalu = NALUnit(NAL_UNIT_PPS, NAL_REF_IDC_PRIORITY_HIGHEST, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
893#endif
894        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
895        m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
896        writeRBSPTrailingBits(nalu.m_Bitstream);
897        accessUnit.push_back(new NALUnitEBSP(nalu));
898#if QC_MVHEVC_B0046
899      }
900#endif
901      m_bSeqFirst = false;
902    }
903
904      /* use the main bitstream buffer for storing the marshalled picture */
905      m_pcEntropyCoder->setBitstream(NULL);
906
907      uiStartCUAddrSliceIdx = 0;
908      uiStartCUAddrSlice    = 0; 
909
910      uiStartCUAddrEntropySliceIdx = 0;
911      uiStartCUAddrEntropySlice    = 0; 
912      uiNextCUAddr                 = 0;
913      pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
914
915      Int processingState = (pcSlice->getSPS()->getUseALF() || pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getScalingListFlag() || pcSlice->getSPS()->getUseDF())?(EXECUTE_INLOOPFILTER):(ENCODE_SLICE);
916
917      static Int iCurrAPSIdx = 0;
918      Int iCodedAPSIdx = 0;
919      TComSlice* pcSliceForAPS = NULL;
920
921      bool skippedSlice=false;
922      while (uiNextCUAddr < uiRealEndAddress) // Iterate over all slices
923      {
924        switch(processingState)
925        {
926        case ENCODE_SLICE:
927          {
928        pcSlice->setNextSlice       ( false );
929        pcSlice->setNextEntropySlice( false );
930        if (uiNextCUAddr == m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx])
931        {
932          pcSlice = pcPic->getSlice(uiStartCUAddrSliceIdx);
933#if COLLOCATED_REF_IDX
934          if(uiStartCUAddrSliceIdx > 0 && pcSlice->getSliceType()!= I_SLICE)
935          {
936            pcSlice->checkColRefIdx(uiStartCUAddrSliceIdx, pcPic);
937          }
938#endif
939          pcPic->setCurrSliceIdx(uiStartCUAddrSliceIdx);
940          m_pcSliceEncoder->setSliceIdx(uiStartCUAddrSliceIdx);
941          assert(uiStartCUAddrSliceIdx == pcSlice->getSliceIdx());
942          // Reconstruction slice
943          pcSlice->setSliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
944          pcSlice->setSliceCurEndCUAddr  ( m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx+1 ] );
945          // Entropy slice
946          pcSlice->setEntropySliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
947          pcSlice->setEntropySliceCurEndCUAddr  ( m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx+1 ] );
948
949          pcSlice->setNextSlice       ( true );
950
951          uiStartCUAddrSliceIdx++;
952          uiStartCUAddrEntropySliceIdx++;
953        } 
954        else if (uiNextCUAddr == m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx])
955        {
956          // Entropy slice
957          pcSlice->setEntropySliceCurStartCUAddr( uiNextCUAddr );  // to be used in encodeSlice() + context restriction
958          pcSlice->setEntropySliceCurEndCUAddr  ( m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx+1 ] );
959
960          pcSlice->setNextEntropySlice( true );
961
962          uiStartCUAddrEntropySliceIdx++;
963        }
964
965      pcSlice->setRPS(pcPic->getSlice(0)->getRPS());
966      pcSlice->setRPSidx(pcPic->getSlice(0)->getRPSidx());
967        UInt uiDummyStartCUAddr;
968        UInt uiDummyBoundingCUAddr;
969        m_pcSliceEncoder->xDetermineStartAndBoundingCUAddr(uiDummyStartCUAddr,uiDummyBoundingCUAddr,pcPic,true);
970
971        uiInternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurEndCUAddr()-1) % pcPic->getNumPartInCU();
972        uiExternalAddress = pcPic->getPicSym()->getPicSCUAddr(pcSlice->getEntropySliceCurEndCUAddr()-1) / pcPic->getNumPartInCU();
973        uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
974        uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
975        uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples();
976        uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples();
977        while(uiPosX>=uiWidth||uiPosY>=uiHeight)
978        {
979          uiInternalAddress--;
980          uiPosX = ( uiExternalAddress % pcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ];
981          uiPosY = ( uiExternalAddress / pcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ];
982        }
983        uiInternalAddress++;
984        if(uiInternalAddress==pcPic->getNumPartInCU())
985        {
986          uiInternalAddress = 0;
987          uiExternalAddress = pcPic->getPicSym()->getCUOrderMap(pcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1);
988        }
989        UInt uiEndAddress = pcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*pcPic->getNumPartInCU()+uiInternalAddress);
990        if(uiEndAddress<=pcSlice->getEntropySliceCurStartCUAddr()) {
991          UInt uiBoundingAddrSlice, uiBoundingAddrEntropySlice;
992          uiBoundingAddrSlice        = m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx];         
993          uiBoundingAddrEntropySlice = m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx];         
994          uiNextCUAddr               = min(uiBoundingAddrSlice, uiBoundingAddrEntropySlice);
995          if(pcSlice->isNextSlice())
996          {
997            skippedSlice=true;
998          }
999          continue;
1000        }
1001        if(skippedSlice) 
1002        {
1003          pcSlice->setNextSlice       ( true );
1004          pcSlice->setNextEntropySlice( false );
1005        }
1006        skippedSlice=false;
1007        if (pcSlice->getPPS()->getEntropyCodingMode())
1008        {
1009          pcSlice->allocSubstreamSizes( iNumSubstreams );
1010          for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1011          pcSubstreamsOut[ui].clear();
1012        }
1013
1014        m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1015        m_pcEntropyCoder->resetEntropy      ();
1016        /* start slice NALunit */
1017#if H0388
1018#if NAL_REF_FLAG
1019        OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->isReferenced(),
1020#if !VIDYO_VPS_INTEGRATION &!QC_MVHEVC_B0046
1021                           m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth(), pcSlice->getTLayer() );
1022#else
1023                           m_pcEncTop->getLayerId(), pcSlice->getTLayer() );
1024#endif
1025#else
1026        OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->isReferenced() ? NAL_REF_IDC_PRIORITY_HIGHEST: NAL_REF_IDC_PRIORITY_LOWEST, 
1027#if !VIDYO_VPS_INTEGRATION
1028                           m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth(), pcSlice->getTLayer() );
1029#else
1030                           m_pcEncTop->getLayerId(), pcSlice->getTLayer() );
1031#endif
1032#endif
1033#else
1034        OutputNALUnit nalu( pcSlice->getNalUnitType(), pcSlice->isReferenced() ? NAL_REF_IDC_PRIORITY_HIGHEST: NAL_REF_IDC_PRIORITY_LOWEST, 
1035#if !VIDYO_VPS_INTEGRATION
1036                           m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth(), pcSlice->getTLayer(), true );
1037#else
1038                           m_pcEncTop->getLayerId(), pcSlice->getTLayer(), true );
1039#endif
1040
1041#endif
1042           
1043        Bool bEntropySlice = (!pcSlice->isNextSlice());
1044        if (!bEntropySlice)
1045        {
1046          uiOneBitstreamPerSliceLength = 0; // start of a new slice
1047        }
1048
1049        // used while writing slice header
1050        Int iTransmitLWHeader = (m_pcCfg->getTileMarkerFlag()==0) ? 0 : 1;
1051        pcSlice->setTileMarkerFlag ( iTransmitLWHeader );
1052        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1053#if !CABAC_INIT_FLAG
1054        pcSlice->setCABACinitIDC(pcSlice->getSliceType());
1055#endif
1056
1057        m_pcEntropyCoder->encodeSliceHeader(pcSlice);
1058
1059        if(pcSlice->isNextSlice())
1060        {
1061          if (pcSlice->getSPS()->getUseALF())
1062          {
1063#if LCU_SYNTAX_ALF
1064            if(pcSlice->getAlfEnabledFlag())
1065#else
1066            if(pcSlice->getAPS()->getAlfEnabled())
1067#endif
1068            {
1069
1070#if LCU_SYNTAX_ALF
1071              if( pcSlice->getSPS()->getUseALFCoefInSlice())
1072              {
1073                Int iNumSUinLCU    = 1<< (g_uiMaxCUDepth << 1); 
1074                Int firstLCUAddr   = pcSlice->getSliceCurStartCUAddr() / iNumSUinLCU; 
1075                Bool isAcrossSlice = pcSlice->getSPS()->getLFCrossSliceBoundaryFlag();
1076                m_pcEntropyCoder->encodeAlfParam( &(alfSliceParams[pcSlice->getSliceIdx()]), false, firstLCUAddr, isAcrossSlice);
1077              }
1078
1079              if( !pcSlice->getSPS()->getUseALFCoefInSlice())
1080              {
1081                AlfCUCtrlInfo& cAlfCUCtrlParam = (*alfCUCtrlParam)[pcSlice->getSliceIdx()];
1082#else
1083              AlfCUCtrlInfo& cAlfCUCtrlParam = vAlfCUCtrlParam[pcSlice->getSliceIdx()];
1084#endif
1085              if(cAlfCUCtrlParam.cu_control_flag)
1086              {
1087                m_pcEntropyCoder->setAlfCtrl( true );
1088                m_pcEntropyCoder->setMaxAlfCtrlDepth(cAlfCUCtrlParam.alf_max_depth);
1089                m_pcCavlcCoder->setAlfCtrl(true);
1090                m_pcCavlcCoder->setMaxAlfCtrlDepth(cAlfCUCtrlParam.alf_max_depth); 
1091              }
1092              else
1093              {
1094                m_pcEntropyCoder->setAlfCtrl(false);
1095              }
1096              m_pcEntropyCoder->encodeAlfCtrlParam(cAlfCUCtrlParam, m_pcAdaptiveLoopFilter->getNumCUsInPic());
1097           
1098#if LCU_SYNTAX_ALF
1099              }
1100#endif           
1101            }
1102          }
1103        }
1104        m_pcEntropyCoder->encodeTileMarkerFlag(pcSlice);
1105
1106        // is it needed?
1107        {
1108          if (!bEntropySlice)
1109          {
1110            pcBitstreamRedirect->writeAlignOne();
1111          }
1112          else
1113          {
1114          // We've not completed our slice header info yet, do the alignment later.
1115          }
1116          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1117          m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
1118          m_pcEntropyCoder->resetEntropy    ();
1119          for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1120          {
1121            m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1122            m_pcEntropyCoder->resetEntropy    ();
1123          }
1124        }
1125
1126        if(pcSlice->isNextSlice())
1127        {
1128          // set entropy coder for writing
1129          m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
1130          {
1131            for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
1132            {
1133              m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
1134              m_pcEntropyCoder->resetEntropy    ();
1135            }
1136            pcSbacCoders[0].load(m_pcSbacCoder);
1137            m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[0], pcSlice );  //ALF is written in substream #0 with CABAC coder #0 (see ALF param encoding below)
1138          }
1139          m_pcEntropyCoder->resetEntropy    ();
1140          // File writing
1141          if (!bEntropySlice)
1142          {
1143            m_pcEntropyCoder->setBitstream(pcBitstreamRedirect);
1144          }
1145          else
1146          {
1147            m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1148          }
1149          // for now, override the TILES_DECODER setting in order to write substreams.
1150            m_pcEntropyCoder->setBitstream    ( &pcSubstreamsOut[0] );
1151
1152        }
1153        pcSlice->setFinalized(true);
1154
1155          m_pcSbacCoder->load( &pcSbacCoders[0] );
1156
1157        pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
1158        if (!bEntropySlice)
1159        {
1160          pcSlice->setTileLocationCount ( 0 );
1161          m_pcSliceEncoder->encodeSlice(pcPic, pcBitstreamRedirect, pcSubstreamsOut); // redirect is only used for CAVLC tile position info.
1162        }
1163        else
1164        {
1165          m_pcSliceEncoder->encodeSlice(pcPic, &nalu.m_Bitstream, pcSubstreamsOut); // nalu.m_Bitstream is only used for CAVLC tile position info.
1166        }
1167
1168        {
1169          // Construct the final bitstream by flushing and concatenating substreams.
1170          // The final bitstream is either nalu.m_Bitstream or pcBitstreamRedirect;
1171          UInt* puiSubstreamSizes = pcSlice->getSubstreamSizes();
1172          UInt uiTotalCodedSize = 0; // for padding calcs.
1173          UInt uiNumSubstreamsPerTile = iNumSubstreams;
1174#if !REMOVE_TILE_DEPENDENCE
1175#if WPP_SIMPLIFICATION
1176         if (pcPic->getPicSym()->getTileBoundaryIndependenceIdr() && iNumSubstreams > 1)
1177#else
1178          if (pcPic->getPicSym()->getTileBoundaryIndependenceIdr() && pcSlice->getPPS()->getEntropyCodingSynchro())
1179#endif
1180            uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
1181#else
1182#if WPP_SIMPLIFICATION
1183          if (iNumSubstreams > 1)
1184#else
1185          if (pcSlice->getPPS()->getEntropyCodingSynchro())
1186#endif
1187          {
1188            uiNumSubstreamsPerTile /= pcPic->getPicSym()->getNumTiles();
1189          }
1190#endif
1191          for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
1192          {
1193            // Flush all substreams -- this includes empty ones.
1194            // Terminating bit and flush.
1195            m_pcEntropyCoder->setEntropyCoder   ( &pcSbacCoders[ui], pcSlice );
1196            m_pcEntropyCoder->setBitstream      (  &pcSubstreamsOut[ui] );
1197            m_pcEntropyCoder->encodeTerminatingBit( 1 );
1198            m_pcEntropyCoder->encodeSliceFinish();
1199            pcSubstreamsOut[ui].write( 1, 1 ); // stop bit.
1200#if TILES_WPP_ENTRY_POINT_SIGNALLING
1201            pcSubstreamsOut[ui].writeAlignZero();
1202#endif
1203            // Byte alignment is necessary between tiles when tiles are independent.
1204            uiTotalCodedSize += pcSubstreamsOut[ui].getNumberOfWrittenBits();
1205
1206            {
1207              Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)
1208                                             && ((ui+1)%uiNumSubstreamsPerTile == 0);
1209              if (bNextSubstreamInNewTile)
1210              {
1211                // byte align.
1212                while (uiTotalCodedSize&0x7)
1213                {
1214                  pcSubstreamsOut[ui].write(0, 1);
1215                  uiTotalCodedSize++;
1216                }
1217              }
1218              Bool bRecordOffsetNext = m_pcCfg->getTileLocationInSliceHeaderFlag()
1219                                            && bNextSubstreamInNewTile;
1220              if (bRecordOffsetNext)
1221                pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
1222            }
1223            if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
1224              puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits();
1225          }
1226          // Complete the slice header info.
1227          m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice );
1228          m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1229#if TILES_WPP_ENTRY_POINT_SIGNALLING
1230          if (m_pcCfg->getTileLocationInSliceHeaderFlag()==0) 
1231          {
1232            pcSlice->setTileLocationCount( 0 );
1233          }
1234          m_pcEntropyCoder->encodeTilesWPPEntryPoint( pcSlice );
1235#else
1236          m_pcEntropyCoder->encodeSliceHeaderSubstreamTable(pcSlice);
1237#endif
1238          // Substreams...
1239          TComOutputBitstream *pcOut = pcBitstreamRedirect;
1240          // xWriteTileLocation will perform byte-alignment...
1241          {
1242            if (bEntropySlice)
1243            {
1244              // In these cases, padding is necessary here.
1245              pcOut = &nalu.m_Bitstream;
1246              pcOut->writeAlignOne();
1247            }
1248          }
1249          UInt uiAccumulatedLength = 0;
1250          for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams(); ui++ )
1251          {
1252            pcOut->addSubstream(&pcSubstreamsOut[ui]);
1253
1254            // Update tile marker location information
1255            for (Int uiMrkIdx = 0; uiMrkIdx < pcSubstreamsOut[ui].getTileMarkerLocationCount(); uiMrkIdx++)
1256            {
1257              UInt uiBottom = pcOut->getTileMarkerLocationCount();
1258              pcOut->setTileMarkerLocation      ( uiBottom, uiAccumulatedLength + pcSubstreamsOut[ui].getTileMarkerLocation( uiMrkIdx ) );
1259              pcOut->setTileMarkerLocationCount ( uiBottom + 1 );
1260            }
1261            uiAccumulatedLength = (pcOut->getNumberOfWrittenBits() >> 3);
1262          }
1263        }
1264
1265        UInt uiBoundingAddrSlice, uiBoundingAddrEntropySlice;
1266        uiBoundingAddrSlice        = m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx];         
1267        uiBoundingAddrEntropySlice = m_uiStoredStartCUAddrForEncodingEntropySlice[uiStartCUAddrEntropySliceIdx];         
1268        uiNextCUAddr               = min(uiBoundingAddrSlice, uiBoundingAddrEntropySlice);
1269#if !REMOVE_TILE_DEPENDENCE
1270        Bool bNextCUInNewSlice     = (uiNextCUAddr >= uiRealEndAddress) || (uiNextCUAddr == m_uiStoredStartCUAddrForEncodingSlice[uiStartCUAddrSliceIdx]);
1271#endif
1272        // If current NALU is the first NALU of slice (containing slice header) and more NALUs exist (due to multiple entropy slices) then buffer it.
1273        // 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.
1274        Bool bNALUAlignedWrittenToList    = false; // used to ensure current NALU is not written more than once to the NALU list.
1275#if !REMOVE_TILE_DEPENDENCE
1276        if (pcSlice->getSPS()->getTileBoundaryIndependenceIdr() && !pcSlice->getSPS()->getTileBoundaryIndependenceIdr())
1277        {
1278          if (bNextCUInNewSlice)
1279          {
1280            if (!bEntropySlice) // there were no entropy slices
1281            {
1282              xWriteTileLocationToSliceHeader(nalu, pcBitstreamRedirect, pcSlice);
1283            }
1284            // (a) writing current NALU
1285            writeRBSPTrailingBits(nalu.m_Bitstream);
1286            accessUnit.push_back(new NALUnitEBSP(nalu));
1287            bNALUAlignedWrittenToList = true;
1288
1289            // (b) update and write buffered NALU
1290            if (bEntropySlice) // if entropy slices existed in the slice then perform concatenation for the buffered nalu-bitstream and buffered payload bitstream
1291            {
1292              // Perform bitstream concatenation of slice header and partial slice payload
1293              xWriteTileLocationToSliceHeader((*naluBuffered), pcBitstreamRedirect, pcSlice);
1294              if (bIteratorAtListStart)
1295              {
1296                itLocationToPushSliceHeaderNALU = accessUnit.begin();
1297              }
1298              else
1299              {
1300                itLocationToPushSliceHeaderNALU++;
1301              }
1302              accessUnit.insert(itLocationToPushSliceHeaderNALU, (new NALUnitEBSP((*naluBuffered))) );
1303
1304              // free buffered nalu
1305              delete naluBuffered;
1306              naluBuffered     = NULL;
1307            }
1308          }
1309          else // another entropy slice exists
1310          {
1311            // Is this start-of-slice NALU? i.e. the one containing slice header. If Yes, then buffer it.
1312            if (!bEntropySlice)
1313            {
1314              // store a pointer to where NALU for slice header is to be written in NALU list
1315              itLocationToPushSliceHeaderNALU = accessUnit.end();
1316              if (accessUnit.begin() == accessUnit.end())
1317              {
1318                bIteratorAtListStart = true;
1319              }
1320              else
1321              {
1322                bIteratorAtListStart = false;
1323                itLocationToPushSliceHeaderNALU--;
1324              }
1325
1326              // buffer nalu for later writing
1327#if H0388
1328              naluBuffered = new OutputNALUnit( pcSlice->getNalUnitType(), pcSlice->isReferenced() ? NAL_REF_IDC_PRIORITY_HIGHEST: NAL_REF_IDC_PRIORITY_LOWEST, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth(), pcSlice->getTLayer() );
1329#else
1330              naluBuffered = new OutputNALUnit(pcSlice->getNalUnitType(), pcSlice->isReferenced() ? NAL_REF_IDC_PRIORITY_HIGHEST: NAL_REF_IDC_PRIORITY_LOWEST, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth(), pcSlice->getTLayer(), true);
1331#endif
1332              copyNaluData( (*naluBuffered), nalu );
1333
1334              // perform byte-alignment to get appropriate bitstream length (used for explicit tile location signaling in slice header)
1335              writeRBSPTrailingBits((*pcBitstreamRedirect));
1336              bNALUAlignedWrittenToList = true; // This is not really a write to bitsream but buffered for later. The flag is set to prevent writing of current NALU to list.
1337              uiOneBitstreamPerSliceLength += pcBitstreamRedirect->getNumberOfWrittenBits(); // length of bitstream after byte-alignment
1338            }
1339            else // write out entropy slice
1340            {
1341              writeRBSPTrailingBits(nalu.m_Bitstream);
1342              accessUnit.push_back(new NALUnitEBSP(nalu));
1343              bNALUAlignedWrittenToList = true; 
1344              uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
1345            }
1346          }
1347        }
1348        else
1349        {
1350#endif
1351        xWriteTileLocationToSliceHeader(nalu, pcBitstreamRedirect, pcSlice);
1352        writeRBSPTrailingBits(nalu.m_Bitstream);
1353        accessUnit.push_back(new NALUnitEBSP(nalu));
1354        bNALUAlignedWrittenToList = true; 
1355        uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits(); // length of bitstream after byte-alignment
1356#if !REMOVE_TILE_DEPENDENCE
1357        }
1358#endif
1359
1360        if (!bNALUAlignedWrittenToList)
1361        {
1362        {
1363          nalu.m_Bitstream.writeAlignZero();
1364        }
1365        accessUnit.push_back(new NALUnitEBSP(nalu));
1366        uiOneBitstreamPerSliceLength += nalu.m_Bitstream.getNumberOfWrittenBits() + 24; // length of bitstream after byte-alignment + 3 byte startcode 0x000001
1367        }
1368
1369
1370        processingState = ENCODE_SLICE;
1371          }
1372          break;
1373        case EXECUTE_INLOOPFILTER:
1374          {
1375            TComAPS cAPS;
1376            allocAPS(&cAPS, pcSlice->getSPS());
1377#if SAO_UNIT_INTERLEAVING
1378            cAPS.setSaoInterleavingFlag(m_pcCfg->getSaoInterleavingFlag());
1379#endif
1380            // set entropy coder for RD
1381            m_pcEntropyCoder->setEntropyCoder ( m_pcCavlcCoder, pcSlice );
1382
1383            if ( pcSlice->getSPS()->getUseSAO() )
1384            {
1385              m_pcEntropyCoder->resetEntropy();
1386              m_pcEntropyCoder->setBitstream( m_pcBitCounter );
1387              m_pcSAO->startSaoEnc(pcPic, m_pcEntropyCoder, m_pcEncTop->getRDSbacCoder(), NULL);
1388              SAOParam& cSaoParam = *(cAPS.getSaoParam());
1389
1390#if SAO_CHROMA_LAMBDA
1391              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma());
1392#else
1393#if ALF_CHROMA_LAMBDA
1394              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma());
1395#else
1396              m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambda());
1397#endif
1398#endif
1399              m_pcSAO->endSaoEnc();
1400
1401              m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
1402            }
1403
1404            // adaptive loop filter
1405#if !LCU_SYNTAX_ALF
1406            UInt64 uiDist, uiBits;
1407#endif
1408            if ( pcSlice->getSPS()->getUseALF())
1409            {
1410              m_pcEntropyCoder->resetEntropy    ();
1411              m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
1412              m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder );
1413#if LCU_SYNTAX_ALF
1414              AlfParamSet* pAlfEncParam = (pcSlice->getSPS()->getUseALFCoefInSlice())?( alfSliceParams ):( cAPS.getAlfParam());
1415#if ALF_CHROMA_LAMBDA
1416#if HHI_INTERVIEW_SKIP
1417              m_pcAdaptiveLoopFilter->ALFProcess(pAlfEncParam, alfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), m_pcEncTop->getInterViewSkip()  );
1418#else
1419              m_pcAdaptiveLoopFilter->ALFProcess(pAlfEncParam, alfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma() );
1420#endif
1421#else
1422#if SAO_CHROMA_LAMBDA
1423#if HHI_INTERVIEW_SKIP
1424              m_pcAdaptiveLoopFilter->ALFProcess(pAlfEncParam, alfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), m_pcEncTop->getInterViewSkip());
1425#else
1426              m_pcAdaptiveLoopFilter->ALFProcess(pAlfEncParam, alfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma());
1427#endif
1428#else
1429#if HHI_INTERVIEW_SKIP
1430              m_pcAdaptiveLoopFilter->ALFProcess(pAlfEncParam, alfCUCtrlParam, pcPic->getSlice(0)->getLambda(), m_pcEncTop->getInterViewSkip() );
1431#else
1432              m_pcAdaptiveLoopFilter->ALFProcess(pAlfEncParam, alfCUCtrlParam, pcPic->getSlice(0)->getLambda());
1433#endif
1434#endif
1435#endif
1436
1437#else
1438              ALFParam& cAlfParam = *( cAPS.getAlfParam());
1439
1440#if ALF_CHROMA_LAMBDA
1441#if HHI_INTERVIEW_SKIP
1442              m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, &vAlfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), uiDist, uiBits, m_pcEncTop->getInterViewSkip());
1443#else
1444              m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, &vAlfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), uiDist, uiBits);
1445#endif
1446#else
1447#if SAO_CHROMA_LAMBDA
1448#if HHI_INTERVIEW_SKIP
1449              m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, &vAlfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), uiDist, uiBits, m_pcEncTop->getInterViewSkip());
1450#else
1451              m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, &vAlfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), uiDist, uiBits);
1452#endif
1453#else
1454#if HHI_INTERVIEW_SKIP
1455              m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, &vAlfCUCtrlParam, pcPic->getSlice(0)->getLambdaLuma(), uiDist, uiBits, m_pcEncTop->getInterViewSkip());
1456#else
1457              m_pcAdaptiveLoopFilter->ALFProcess( &cAlfParam, &vAlfCUCtrlParam, pcPic->getSlice(0)->getLambda(), uiDist, uiBits);
1458#endif
1459#endif
1460#endif
1461#endif
1462              m_pcAdaptiveLoopFilter->endALFEnc();
1463
1464              m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
1465            }
1466            iCodedAPSIdx = iCurrAPSIdx; 
1467            pcSliceForAPS = pcSlice;
1468
1469            assignNewAPS(cAPS, iCodedAPSIdx, vAPS, pcSliceForAPS);
1470            iCurrAPSIdx = (iCurrAPSIdx +1)%MAX_NUM_SUPPORTED_APS;
1471            processingState = ENCODE_APS;
1472
1473            //set APS link to the slices
1474            for(Int s=0; s< uiNumSlices; s++)
1475            {
1476              if (pcSlice->getSPS()->getUseALF())
1477              {
1478#if LCU_SYNTAX_ALF
1479                pcPic->getSlice(s)->setAlfEnabledFlag(  (pcSlice->getSPS()->getUseALFCoefInSlice())?(alfSliceParams[s].isEnabled[ALF_Y]):(cAPS.getAlfEnabled())   );
1480#else
1481                pcPic->getSlice(s)->setAlfEnabledFlag((cAPS.getAlfParam()->alf_flag==1)?true:false);
1482#endif
1483              }
1484              if (pcSlice->getSPS()->getUseSAO())
1485              {
1486                pcPic->getSlice(s)->setSaoEnabledFlag((cAPS.getSaoParam()->bSaoFlag[0]==1)?true:false);
1487              }
1488              pcPic->getSlice(s)->setAPS(&(vAPS[iCodedAPSIdx]));
1489              pcPic->getSlice(s)->setAPSId(iCodedAPSIdx);
1490            }
1491          }
1492          break;
1493        case ENCODE_APS:
1494          {
1495#if NAL_REF_FLAG
1496#if VIDYO_VPS_INTEGRATION | QC_MVHEVC_B0046
1497            OutputNALUnit nalu(NAL_UNIT_APS, true, m_pcEncTop->getLayerId());
1498#else
1499            OutputNALUnit nalu(NAL_UNIT_APS, true, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
1500#endif
1501#else
1502            OutputNALUnit nalu(NAL_UNIT_APS, NAL_REF_IDC_PRIORITY_HIGHEST, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
1503#endif
1504            encodeAPS(&(vAPS[iCodedAPSIdx]), nalu.m_Bitstream, pcSliceForAPS);
1505            accessUnit.push_back(new NALUnitEBSP(nalu));
1506
1507            processingState = ENCODE_SLICE;
1508          }
1509          break;
1510        default:
1511          {
1512            printf("Not a supported encoding state\n");
1513            assert(0);
1514            exit(-1);
1515          }
1516        }
1517      } // end iteration over slices
1518
1519
1520      if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
1521      {
1522        if(pcSlice->getSPS()->getUseSAO())
1523        {
1524          m_pcSAO->destroyPicSaoInfo();
1525        }
1526
1527        if(pcSlice->getSPS()->getUseALF())
1528        {
1529#if LCU_SYNTAX_ALF
1530          m_pcAdaptiveLoopFilter->uninitALFEnc(alfSliceParams, alfCUCtrlParam);
1531#endif
1532          m_pcAdaptiveLoopFilter->destroyPicAlfInfo();
1533        }
1534
1535        pcPic->destroyNonDBFilterInfo();
1536      }
1537
1538#if HHI_INTERVIEW_SKIP
1539      if (pcPic->getUsedPelsMap())
1540        pcPic->removeUsedPelsMapBuffer() ;
1541#endif
1542#if HHI_INTER_VIEW_MOTION_PRED
1543      pcPic->removeOrgDepthMapBuffer();
1544#endif
1545   
1546   //   pcPic->compressMotion();
1547      m_pocLastCoded = pcPic->getPOC();
1548     
1549      //-- For time output for each slice
1550      Double dEncTime = (double)(clock()-iBeforeTime) / CLOCKS_PER_SEC;
1551
1552      const char* digestStr = NULL;
1553      if (m_pcCfg->getPictureDigestEnabled())
1554      {
1555        /* calculate MD5sum for entire reconstructed picture */
1556        SEIpictureDigest sei_recon_picture_digest;
1557        sei_recon_picture_digest.method = SEIpictureDigest::MD5;
1558        calcMD5(*pcPic->getPicYuvRec(), sei_recon_picture_digest.digest);
1559        digestStr = digestToString(sei_recon_picture_digest.digest);
1560
1561#if NAL_REF_FLAG
1562#if VIDYO_VPS_INTEGRATION | QC_MVHEVC_B0046
1563        OutputNALUnit nalu(NAL_UNIT_SEI, false, m_pcEncTop->getLayerId());
1564#else
1565        OutputNALUnit nalu(NAL_UNIT_SEI, false, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
1566#endif
1567#else
1568        OutputNALUnit nalu(NAL_UNIT_SEI, NAL_REF_IDC_PRIORITY_LOWEST, m_pcEncTop->getViewId(), m_pcEncTop->getIsDepth());
1569#endif
1570
1571        /* write the SEI messages */
1572        m_pcEntropyCoder->setEntropyCoder(m_pcCavlcCoder, pcSlice);
1573        m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
1574        m_pcEntropyCoder->encodeSEI(sei_recon_picture_digest);
1575        writeRBSPTrailingBits(nalu.m_Bitstream);
1576
1577        /* insert the SEI message NALUnit before any Slice NALUnits */
1578        AccessUnit::iterator it = find_if(accessUnit.begin(), accessUnit.end(), mem_fun(&NALUnit::isSlice));
1579        accessUnit.insert(it, new NALUnitEBSP(nalu));
1580      }
1581
1582      xCalculateAddPSNR( pcPic, pcPic->getPicYuvRec(), accessUnit, dEncTime );
1583      if (digestStr)
1584        printf(" [MD5:%s]", digestStr);
1585
1586#if FIXED_ROUNDING_FRAME_MEMORY
1587      /* TODO: this should happen after copyToPic(pcPicYuvRecOut) */
1588      pcPic->getPicYuvRec()->xFixedRoundingPic();
1589#endif
1590      pcPic->getPicYuvRec()->copyToPic(pcPicYuvRecOut);
1591     
1592      pcPic->setReconMark   ( true );
1593
1594      pcPic->setUsedForTMVP ( true );
1595
1596      m_bFirst = false;
1597      m_iNumPicCoded++;
1598
1599      /* logging: insert a newline at end of picture period */
1600      printf("\n");
1601      fflush(stdout);
1602  }
1603 
1604  delete[] pcSubstreamsOut;
1605  delete pcBitstreamRedirect;
1606
1607}
1608
1609/** Memory allocation for APS
1610  * \param [out] pAPS APS pointer
1611  * \param [in] pSPS SPS pointer
1612  */
1613Void TEncGOP::allocAPS (TComAPS* pAPS, TComSPS* pSPS)
1614{
1615  if(pSPS->getUseSAO())
1616  {
1617    pAPS->createSaoParam();
1618    m_pcSAO->allocSaoParam(pAPS->getSaoParam());
1619  }
1620  if(pSPS->getUseALF())
1621  {
1622    pAPS->createAlfParam();
1623#if LCU_SYNTAX_ALF
1624    //alf Enabled flag in APS is false after pAPS->createAlfParam();
1625    if(!pSPS->getUseALFCoefInSlice())
1626    {
1627      pAPS->getAlfParam()->create(m_pcAdaptiveLoopFilter->getNumLCUInPicWidth(), m_pcAdaptiveLoopFilter->getNumLCUInPicHeight(), m_pcAdaptiveLoopFilter->getNumCUsInPic());
1628      pAPS->getAlfParam()->createALFParam();
1629    }
1630#else
1631    m_pcAdaptiveLoopFilter->allocALFParam(pAPS->getAlfParam());
1632#endif
1633  }
1634}
1635
1636/** Memory deallocation for APS
1637  * \param [out] pAPS APS pointer
1638  * \param [in] pSPS SPS pointer
1639  */
1640Void TEncGOP::freeAPS (TComAPS* pAPS, TComSPS* pSPS)
1641{
1642  if(pSPS->getUseSAO())
1643  {
1644    if(pAPS->getSaoParam() != NULL)
1645    {
1646      m_pcSAO->freeSaoParam(pAPS->getSaoParam());
1647      pAPS->destroySaoParam();
1648
1649    }
1650  }
1651  if(pSPS->getUseALF())
1652  {
1653    if(pAPS->getAlfParam() != NULL)
1654    {
1655#if LCU_SYNTAX_ALF
1656      if(!pSPS->getUseALFCoefInSlice())
1657      {
1658        pAPS->getAlfParam()->releaseALFParam();
1659      }
1660#else
1661      m_pcAdaptiveLoopFilter->freeALFParam(pAPS->getAlfParam());
1662#endif
1663      pAPS->destroyAlfParam();
1664    }
1665  }
1666}
1667
1668/** Assign APS object into APS container according to APS ID
1669  * \param [in] cAPS APS object
1670  * \param [in] apsID APS ID
1671  * \param [in,out] vAPS APS container
1672  * \param [in] pcSlice pointer to slice
1673  */
1674Void TEncGOP::assignNewAPS(TComAPS& cAPS, Int apsID, std::vector<TComAPS>& vAPS, TComSlice* pcSlice)
1675{
1676
1677  cAPS.setAPSID(apsID);
1678  if(pcSlice->getPOC() == 0)
1679  {
1680    cAPS.setScalingListEnabled(pcSlice->getSPS()->getScalingListFlag());
1681  }
1682  else
1683  {
1684    cAPS.setScalingListEnabled(false);
1685  }
1686
1687  cAPS.setSaoEnabled(pcSlice->getSPS()->getUseSAO() ? (cAPS.getSaoParam()->bSaoFlag[0] ):(false));
1688#if LCU_SYNTAX_ALF
1689  cAPS.setAlfEnabled(pcSlice->getSPS()->getUseALF() ? (cAPS.getAlfParam()->isEnabled[0]):(false));
1690#else
1691  cAPS.setAlfEnabled(pcSlice->getSPS()->getUseALF() ? (cAPS.getAlfParam()->alf_flag ==1):(false));
1692#endif
1693  cAPS.setLoopFilterOffsetInAPS(m_pcCfg->getLoopFilterOffsetInAPS());
1694  cAPS.setLoopFilterDisable(m_pcCfg->getLoopFilterDisable());
1695  cAPS.setLoopFilterBetaOffset(m_pcCfg->getLoopFilterBetaOffset());
1696  cAPS.setLoopFilterTcOffset(m_pcCfg->getLoopFilterTcOffset());
1697
1698  //assign new APS into APS container
1699  Int apsBufSize= (Int)vAPS.size();
1700
1701  if(apsID >= apsBufSize)
1702  {
1703    vAPS.resize(apsID +1);
1704  }
1705
1706  freeAPS(&(vAPS[apsID]), pcSlice->getSPS());
1707  vAPS[apsID] = cAPS;
1708}
1709
1710
1711/** encode APS syntax elements
1712  * \param [in] pcAPS APS pointer
1713  * \param [in, out] APSbs bitstream
1714  * \param [in] pointer to slice (just used for entropy coder initialization)
1715  */
1716Void TEncGOP::encodeAPS(TComAPS* pcAPS, TComOutputBitstream& APSbs, TComSlice* pcSlice)
1717{
1718  m_pcEntropyCoder->setEntropyCoder   ( m_pcCavlcCoder, pcSlice);
1719  m_pcEntropyCoder->resetEntropy      ();
1720  m_pcEntropyCoder->setBitstream(&APSbs);
1721
1722  m_pcEntropyCoder->encodeAPSInitInfo(pcAPS);
1723  if(pcAPS->getScalingListEnabled())
1724  {
1725    m_pcEntropyCoder->encodeScalingList( pcSlice->getScalingList() );
1726  }
1727  if(pcAPS->getLoopFilterOffsetInAPS())
1728  {
1729    m_pcEntropyCoder->encodeDFParams(pcAPS);
1730  }
1731#if SAO_UNIT_INTERLEAVING
1732  m_pcEntropyCoder->encodeSaoParam(pcAPS);
1733#else
1734  if(pcAPS->getSaoEnabled())
1735  {
1736    m_pcEntropyCoder->encodeSaoParam(pcAPS->getSaoParam());
1737  }
1738#endif
1739#if LCU_SYNTAX_ALF
1740  m_pcEntropyCoder->encodeAPSAlfFlag( pcAPS->getAlfEnabled()?1:0);
1741#endif
1742  if(pcAPS->getAlfEnabled())
1743  {
1744    m_pcEntropyCoder->encodeAlfParam(pcAPS->getAlfParam());
1745  }
1746
1747  m_pcEntropyCoder->encodeApsExtensionFlag();
1748  //neither SAO and ALF is enabled
1749  writeRBSPTrailingBits(APSbs);
1750}
1751
1752Void TEncGOP::preLoopFilterPicAll( TComPic* pcPic, UInt64& ruiDist, UInt64& ruiBits )
1753{
1754  TComSlice* pcSlice = pcPic->getSlice(pcPic->getCurrSliceIdx());
1755  Bool bCalcDist = false;
1756#if DBL_CONTROL
1757  m_pcLoopFilter->setCfg(pcSlice->getPPS()->getDeblockingFilterControlPresent(), pcSlice->getLoopFilterDisable(), m_pcCfg->getLoopFilterBetaOffset(), m_pcCfg->getLoopFilterTcOffset(), m_pcCfg->getLFCrossTileBoundaryFlag());
1758#else
1759  m_pcLoopFilter->setCfg(pcSlice->getLoopFilterDisable(), m_pcCfg->getLoopFilterBetaOffset(), m_pcCfg->getLoopFilterTcOffset(), m_pcCfg->getLFCrossTileBoundaryFlag());
1760#endif
1761  m_pcLoopFilter->loopFilterPic( pcPic );
1762 
1763  m_pcEntropyCoder->setEntropyCoder ( m_pcEncTop->getRDGoOnSbacCoder(), pcSlice );
1764  m_pcEntropyCoder->resetEntropy    ();
1765  m_pcEntropyCoder->setBitstream    ( m_pcBitCounter );
1766  pcSlice = pcPic->getSlice(0);
1767  if(pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
1768  {
1769    pcPic->createNonDBFilterInfo();
1770  }
1771 
1772  // Adaptive Loop filter
1773  if( pcSlice->getSPS()->getUseALF() )
1774  {
1775    m_pcAdaptiveLoopFilter->createPicAlfInfo(pcPic);
1776
1777#if LCU_SYNTAX_ALF
1778    AlfParamSet* alfParamSet;
1779    std::vector<AlfCUCtrlInfo>* alfCUCtrlParam = NULL;
1780    alfParamSet= new AlfParamSet;
1781    alfParamSet->create( m_pcAdaptiveLoopFilter->getNumLCUInPicWidth(), m_pcAdaptiveLoopFilter->getNumLCUInPicHeight(), m_pcAdaptiveLoopFilter->getNumCUsInPic());
1782    alfParamSet->createALFParam();
1783    m_pcAdaptiveLoopFilter->initALFEnc(false, true, 1, alfParamSet, alfCUCtrlParam);
1784#else
1785    ALFParam cAlfParam;
1786    m_pcAdaptiveLoopFilter->allocALFParam(&cAlfParam);
1787#endif   
1788    m_pcAdaptiveLoopFilter->startALFEnc(pcPic, m_pcEntropyCoder);
1789   
1790
1791#if LCU_SYNTAX_ALF
1792
1793#if ALF_CHROMA_LAMBDA
1794#if HHI_INTERVIEW_SKIP
1795    m_pcAdaptiveLoopFilter->ALFProcess(alfParamSet, NULL, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), m_pcEncTop->getInterViewSkip()  );
1796#else
1797    m_pcAdaptiveLoopFilter->ALFProcess(alfParamSet, NULL, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma() );
1798#endif
1799#else
1800#if SAO_CHROMA_LAMBDA
1801    m_pcAdaptiveLoopFilter->ALFProcess(alfParamSet, NULL, pcPic->getSlice(0)->getLambdaLuma(), m_pcEncTop->getInterViewSkip());
1802#if HHI_INTERVIEW_SKIP
1803#else
1804    m_pcAdaptiveLoopFilter->ALFProcess(alfParamSet, NULL, pcPic->getSlice(0)->getLambdaLuma());
1805#endif
1806#else
1807#if HHI_INTERVIEW_SKIP
1808    m_pcAdaptiveLoopFilter->ALFProcess(alfParamSet, NULL, pcPic->getSlice(0)->getLambda(), m_pcEncTop->getInterViewSkip());
1809#else
1810    m_pcAdaptiveLoopFilter->ALFProcess(alfParamSet, NULL, pcPic->getSlice(0)->getLambda());
1811#endif
1812#endif
1813#endif
1814
1815#else
1816#if ALF_CHROMA_LAMBDA 
1817    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, NULL, pcSlice->getLambdaLuma(), pcSlice->getLambdaChroma(), ruiDist, ruiBits, m_pcEncTop->getInterViewSkip());
1818#if HHI_INTERVIEW_SKIP
1819#else
1820    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, NULL, pcSlice->getLambdaLuma(), pcSlice->getLambdaChroma(), ruiDist, ruiBits);
1821#endif
1822#else
1823#if SAO_CHROMA_LAMBDA
1824#if HHI_INTERVIEW_SKIP
1825    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, NULL, pcSlice->getLambdaLuma(), ruiDist, ruiBits, m_pcEncTop->getInterViewSkip());
1826#else
1827    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, NULL, pcSlice->getLambdaLuma(), ruiDist, ruiBits);
1828#endif
1829#else
1830#if HHI_INTERVIEW_SKIP
1831    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, NULL, pcSlice->getLambda(), ruiDist, ruiBits, m_pcEncTop->getInterViewSkip());
1832#else
1833    m_pcAdaptiveLoopFilter->ALFProcess(&cAlfParam, NULL, pcSlice->getLambda(), ruiDist, ruiBits);
1834#endif
1835#endif
1836
1837#endif
1838#endif
1839    m_pcAdaptiveLoopFilter->endALFEnc();
1840
1841#if LCU_SYNTAX_ALF
1842    alfParamSet->releaseALFParam();
1843    delete alfParamSet;
1844    delete alfCUCtrlParam;
1845#else
1846    m_pcAdaptiveLoopFilter->freeALFParam(&cAlfParam);
1847#endif
1848    m_pcAdaptiveLoopFilter->PCMLFDisableProcess(pcPic);
1849    m_pcAdaptiveLoopFilter->destroyPicAlfInfo();
1850  }
1851  if( pcSlice->getSPS()->getUseSAO() || pcSlice->getSPS()->getUseALF())
1852  {
1853    pcPic->destroyNonDBFilterInfo();
1854  }
1855 
1856  m_pcEntropyCoder->resetEntropy    ();
1857  ruiBits += m_pcEntropyCoder->getNumberOfWrittenBits();
1858 
1859  if (!bCalcDist)
1860    ruiDist = xFindDistortionFrame(pcPic->getPicYuvOrg(), pcPic->getPicYuvRec());
1861}
1862
1863// ====================================================================================================================
1864// Protected member functions
1865// ====================================================================================================================
1866
1867Void TEncGOP::xInitGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic, TComList<TComPicYuv*>& rcListPicYuvRecOut )
1868{
1869  assert( iNumPicRcvd > 0 );
1870  //  Exception for the first frame
1871  if ( iPOCLast == 0 )
1872  {
1873    m_iGopSize    = 1;
1874  }
1875  else
1876    m_iGopSize    = m_pcCfg->getGOPSize();
1877 
1878  assert (m_iGopSize > 0); 
1879
1880  return;
1881}
1882
1883Void TEncGOP::xGetBuffer( TComList<TComPic*>&       rcListPic,
1884                         TComList<TComPicYuv*>&    rcListPicYuvRecOut,
1885                         Int                       iNumPicRcvd,
1886                         Int                       iTimeOffset,
1887                         TComPic*&                 rpcPic,
1888                         TComPicYuv*&              rpcPicYuvRecOut,
1889                         UInt                      uiPOCCurr )
1890{
1891  Int i;
1892  //  Rec. output
1893  TComList<TComPicYuv*>::iterator     iterPicYuvRec = rcListPicYuvRecOut.end();
1894  for ( i = 0; i < iNumPicRcvd - iTimeOffset + 1; i++ )
1895  {
1896    iterPicYuvRec--;
1897  }
1898 
1899  rpcPicYuvRecOut = *(iterPicYuvRec);
1900 
1901  //  Current pic.
1902  TComList<TComPic*>::iterator        iterPic       = rcListPic.begin();
1903  while (iterPic != rcListPic.end())
1904  {
1905    rpcPic = *(iterPic);
1906    rpcPic->setCurrSliceIdx(0);
1907    if (rpcPic->getPOC() == (Int)uiPOCCurr)
1908    {
1909      break;
1910    }
1911    iterPic++;
1912  }
1913 
1914  assert (rpcPic->getPOC() == (Int)uiPOCCurr);
1915 
1916  return;
1917}
1918
1919UInt64 TEncGOP::xFindDistortionFrame (TComPicYuv* pcPic0, TComPicYuv* pcPic1)
1920{
1921  Int     x, y;
1922  Pel*  pSrc0   = pcPic0 ->getLumaAddr();
1923  Pel*  pSrc1   = pcPic1 ->getLumaAddr();
1924#if IBDI_DISTORTION
1925  Int  iShift = g_uiBitIncrement;
1926  Int  iOffset = 1<<(g_uiBitIncrement-1);
1927#else
1928  UInt  uiShift = g_uiBitIncrement<<1;
1929#endif
1930  Int   iTemp;
1931 
1932  Int   iStride = pcPic0->getStride();
1933  Int   iWidth  = pcPic0->getWidth();
1934  Int   iHeight = pcPic0->getHeight();
1935 
1936  UInt64  uiTotalDiff = 0;
1937 
1938  for( y = 0; y < iHeight; y++ )
1939  {
1940    for( x = 0; x < iWidth; x++ )
1941    {
1942#if IBDI_DISTORTION
1943      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
1944#else
1945      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
1946#endif
1947    }
1948    pSrc0 += iStride;
1949    pSrc1 += iStride;
1950  }
1951 
1952  iHeight >>= 1;
1953  iWidth  >>= 1;
1954  iStride >>= 1;
1955 
1956  pSrc0  = pcPic0->getCbAddr();
1957  pSrc1  = pcPic1->getCbAddr();
1958 
1959  for( y = 0; y < iHeight; y++ )
1960  {
1961    for( x = 0; x < iWidth; x++ )
1962    {
1963#if IBDI_DISTORTION
1964      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
1965#else
1966      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
1967#endif
1968    }
1969    pSrc0 += iStride;
1970    pSrc1 += iStride;
1971  }
1972 
1973  pSrc0  = pcPic0->getCrAddr();
1974  pSrc1  = pcPic1->getCrAddr();
1975 
1976  for( y = 0; y < iHeight; y++ )
1977  {
1978    for( x = 0; x < iWidth; x++ )
1979    {
1980#if IBDI_DISTORTION
1981      iTemp = ((pSrc0[x]+iOffset)>>iShift) - ((pSrc1[x]+iOffset)>>iShift); uiTotalDiff += iTemp * iTemp;
1982#else
1983      iTemp = pSrc0[x] - pSrc1[x]; uiTotalDiff += (iTemp*iTemp) >> uiShift;
1984#endif
1985    }
1986    pSrc0 += iStride;
1987    pSrc1 += iStride;
1988  }
1989 
1990  return uiTotalDiff;
1991}
1992
1993#if VERBOSE_RATE
1994static const char* nalUnitTypeToString(NalUnitType type)
1995{
1996  switch (type)
1997  {
1998  case NAL_UNIT_CODED_SLICE: return "SLICE";
1999#if H0566_TLA
2000#if !QC_REM_IDV_B0046
2001  case NAL_UNIT_CODED_SLICE_IDV: return "IDV";
2002#endif
2003  case NAL_UNIT_CODED_SLICE_CRA: return "CRA";
2004  case NAL_UNIT_CODED_SLICE_TLA: return "TLA";
2005#else
2006  case NAL_UNIT_CODED_SLICE_CDR: return "CDR";
2007#endif
2008  case NAL_UNIT_CODED_SLICE_IDR: return "IDR";
2009  case NAL_UNIT_SEI: return "SEI";
2010  case NAL_UNIT_SPS: return "SPS";
2011  case NAL_UNIT_PPS: return "PPS";
2012  case NAL_UNIT_FILLER_DATA: return "FILLER";
2013  default: return "UNK";
2014  }
2015}
2016#endif
2017
2018Void TEncGOP::xCalculateAddPSNR( TComPic* pcPic, TComPicYuv* pcPicD, const AccessUnit& accessUnit, Double dEncTime )
2019{
2020  Int     x, y;
2021  UInt64 uiSSDY  = 0;
2022  UInt64 uiSSDU  = 0;
2023  UInt64 uiSSDV  = 0;
2024 
2025  Double  dYPSNR  = 0.0;
2026  Double  dUPSNR  = 0.0;
2027  Double  dVPSNR  = 0.0;
2028 
2029  //===== calculate PSNR =====
2030  Pel*  pOrg    = pcPic ->getPicYuvOrg()->getLumaAddr();
2031  Pel*  pRec    = pcPicD->getLumaAddr();
2032  Int   iStride = pcPicD->getStride();
2033 
2034  Int   iWidth;
2035  Int   iHeight;
2036 
2037  iWidth  = pcPicD->getWidth () - m_pcEncTop->getPad(0);
2038  iHeight = pcPicD->getHeight() - m_pcEncTop->getPad(1);
2039 
2040  Int   iSize   = iWidth*iHeight;
2041 
2042  for( y = 0; y < iHeight; y++ )
2043  {
2044    for( x = 0; x < iWidth; x++ )
2045    {
2046      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2047      uiSSDY   += iDiff * iDiff;
2048    }
2049    pOrg += iStride;
2050    pRec += iStride;
2051  }
2052 
2053#if HHI_VSO
2054#if HHI_VSO_SYNTH_DIST_OUT
2055  if ( m_pcRdCost->getUseRenModel() )
2056  {
2057    unsigned int maxval = 255 * (1<<(g_uiBitDepth + g_uiBitIncrement -8));
2058    Double fRefValueY = (double) maxval * maxval * iSize;
2059    Double fRefValueC = fRefValueY / 4.0;
2060    TRenModel*  pcRenModel = m_pcEncTop->getEncTop()->getRenModel();
2061    Int64 iDistVSOY, iDistVSOU, iDistVSOV;
2062    pcRenModel->getTotalSSE( iDistVSOY, iDistVSOU, iDistVSOV );
2063    dYPSNR = ( iDistVSOY ? 10.0 * log10( fRefValueY / (Double) iDistVSOY ) : 99.99 );
2064    dUPSNR = ( iDistVSOU ? 10.0 * log10( fRefValueC / (Double) iDistVSOU ) : 99.99 );
2065    dVPSNR = ( iDistVSOV ? 10.0 * log10( fRefValueC / (Double) iDistVSOV ) : 99.99 );
2066  }
2067  else
2068#endif
2069#endif
2070  {
2071  iHeight >>= 1;
2072  iWidth  >>= 1;
2073  iStride >>= 1;
2074  pOrg  = pcPic ->getPicYuvOrg()->getCbAddr();
2075  pRec  = pcPicD->getCbAddr();
2076 
2077  for( y = 0; y < iHeight; y++ )
2078  {
2079    for( x = 0; x < iWidth; x++ )
2080    {
2081      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2082      uiSSDU   += iDiff * iDiff;
2083    }
2084    pOrg += iStride;
2085    pRec += iStride;
2086  }
2087 
2088  pOrg  = pcPic ->getPicYuvOrg()->getCrAddr();
2089  pRec  = pcPicD->getCrAddr();
2090 
2091  for( y = 0; y < iHeight; y++ )
2092  {
2093    for( x = 0; x < iWidth; x++ )
2094    {
2095      Int iDiff = (Int)( pOrg[x] - pRec[x] );
2096      uiSSDV   += iDiff * iDiff;
2097    }
2098    pOrg += iStride;
2099    pRec += iStride;
2100  }
2101 
2102  unsigned int maxval = 255 * (1<<(g_uiBitDepth + g_uiBitIncrement -8));
2103  Double fRefValueY = (double) maxval * maxval * iSize;
2104  Double fRefValueC = fRefValueY / 4.0;
2105  dYPSNR            = ( uiSSDY ? 10.0 * log10( fRefValueY / (Double)uiSSDY ) : 99.99 );
2106  dUPSNR            = ( uiSSDU ? 10.0 * log10( fRefValueC / (Double)uiSSDU ) : 99.99 );
2107  dVPSNR            = ( uiSSDV ? 10.0 * log10( fRefValueC / (Double)uiSSDV ) : 99.99 );
2108  }
2109  /* calculate the size of the access unit, excluding:
2110   *  - any AnnexB contributions (start_code_prefix, zero_byte, etc.,)
2111   *  - SEI NAL units
2112   */
2113  unsigned numRBSPBytes = 0;
2114  for (AccessUnit::const_iterator it = accessUnit.begin(); it != accessUnit.end(); it++)
2115  {
2116    unsigned numRBSPBytes_nal = unsigned((*it)->m_nalUnitData.str().size());
2117#if VERBOSE_RATE
2118    printf("*** %6s numBytesInNALunit: %u\n", nalUnitTypeToString((*it)->m_nalUnitType), numRBSPBytes_nal);
2119#endif
2120    if ((*it)->m_nalUnitType != NAL_UNIT_SEI)
2121      numRBSPBytes += numRBSPBytes_nal;
2122  }
2123
2124  unsigned uibits = numRBSPBytes * 8;
2125  m_vRVM_RP.push_back( uibits );
2126
2127  //===== add PSNR =====
2128  m_pcEncTop->getAnalyzeAll()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2129  TComSlice*  pcSlice = pcPic->getSlice(0);
2130  if (pcSlice->isIntra())
2131  {
2132    m_pcEncTop->getAnalyzeI()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2133  }
2134  if (pcSlice->isInterP())
2135  {
2136    m_pcEncTop->getAnalyzeP()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2137  }
2138  if (pcSlice->isInterB())
2139  {
2140    m_pcEncTop->getAnalyzeB()->addResult (dYPSNR, dUPSNR, dVPSNR, (Double)uibits);
2141  }
2142
2143  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
2144  if (!pcSlice->isReferenced()) c += 32;
2145
2146#if ADAPTIVE_QP_SELECTION
2147  printf("%s   View %3d POC %4d TId: %1d ( %c-SLICE, nQP %d QP %d ) %10d bits",
2148         pcSlice->getIsDepth() ? "Depth  " : "Texture",
2149         pcSlice->getViewId(),
2150         pcSlice->getPOC(),
2151         pcSlice->getTLayer(),
2152         c,
2153         pcSlice->getSliceQpBase(),
2154         pcSlice->getSliceQp(),
2155         uibits );
2156#else
2157  printf("%s   View %3d POC %4d TId: %1d ( %c-SLICE, QP %d ) %10d bits",
2158         pcSlice->getIsDepth() ? "Depth  " : "Texture",
2159         pcSlice->getViewId(),
2160         pcSlice->getPOC()-pcSlice->getLastIDR(),
2161         pcSlice->getTLayer(),
2162         c,
2163         pcSlice->getSliceQp(),
2164         uibits );
2165#endif
2166
2167  printf(" [Y %6.4lf dB    U %6.4lf dB    V %6.4lf dB]", dYPSNR, dUPSNR, dVPSNR );
2168  printf(" [ET %5.0f ]", dEncTime );
2169 
2170  for (Int iRefList = 0; iRefList < 2; iRefList++)
2171  {
2172    printf(" [L%d ", iRefList);
2173    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(RefPicList(iRefList)); iRefIndex++)
2174    {
2175      if( pcSlice->getViewId() != pcSlice->getRefViewId( RefPicList(iRefList), iRefIndex ) )
2176      {
2177        printf( "V%d ", pcSlice->getRefViewId( RefPicList(iRefList), iRefIndex ) );
2178      }
2179      else
2180      {
2181        printf ("%d ", pcSlice->getRefPOC(RefPicList(iRefList), iRefIndex)-pcSlice->getLastIDR());
2182      }
2183    }
2184    printf("]");
2185  }
2186  if(pcSlice->getNumRefIdx(REF_PIC_LIST_C)>0 && !pcSlice->getNoBackPredFlag())
2187  {
2188    printf(" [LC ");
2189    for (Int iRefIndex = 0; iRefIndex < pcSlice->getNumRefIdx(REF_PIC_LIST_C); iRefIndex++)
2190    {
2191      if( pcSlice->getViewId() != pcSlice->getRefViewId( (RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex) ) )
2192      {
2193        printf( "V%d ", pcSlice->getRefViewId( (RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex) ) );
2194      }
2195      else
2196      {
2197        printf ("%d ", pcSlice->getRefPOC((RefPicList)pcSlice->getListIdFromIdxOfLC(iRefIndex), pcSlice->getRefIdxFromIdxOfLC(iRefIndex))-pcSlice->getLastIDR());
2198      }
2199    }
2200    printf("]");
2201  }
2202}
2203
2204/** Function for deciding the nal_unit_type.
2205 * \param uiPOCCurr POC of the current picture
2206 * \returns the nal_unit type of the picture
2207 * This function checks the configuration and returns the appropriate nal_unit_type for the picture.
2208 */
2209NalUnitType TEncGOP::getNalUnitType(UInt uiPOCCurr)
2210{
2211  Bool bInterViewOnlySlice = ( m_pcCfg->getGOPEntry(MAX_GOP).m_POC == 0 && (m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType == 'P' || m_pcCfg->getGOPEntry(MAX_GOP).m_sliceType == 'B') );
2212
2213  if (uiPOCCurr == 0)
2214  {
2215    if( bInterViewOnlySlice ) 
2216    { 
2217#if !QC_REM_IDV_B0046
2218      return NAL_UNIT_CODED_SLICE_IDV; 
2219#else
2220      return NAL_UNIT_CODED_SLICE_IDR;
2221#endif
2222    }
2223    else
2224    { 
2225      return NAL_UNIT_CODED_SLICE_IDR;
2226    }
2227  }
2228  if (uiPOCCurr % m_pcCfg->getIntraPeriod() == 0)
2229  {
2230    if (m_pcCfg->getDecodingRefreshType() == 1)
2231    {
2232      if( bInterViewOnlySlice ) 
2233      { 
2234#if !QC_REM_IDV_B0046
2235        return NAL_UNIT_CODED_SLICE_IDV; 
2236#else
2237        return NAL_UNIT_CODED_SLICE_CRA; 
2238#endif
2239      }
2240      else
2241      { 
2242#if H0566_TLA
2243      return NAL_UNIT_CODED_SLICE_CRA;
2244#else
2245      return NAL_UNIT_CODED_SLICE_CDR;
2246#endif
2247      }
2248    }
2249    else if (m_pcCfg->getDecodingRefreshType() == 2)
2250    {
2251      if( bInterViewOnlySlice ) 
2252      { 
2253#if !QC_REM_IDV_B0046
2254        return NAL_UNIT_CODED_SLICE_IDV; 
2255#else
2256        return NAL_UNIT_CODED_SLICE_IDR;
2257#endif
2258      }
2259      else
2260      { 
2261        return NAL_UNIT_CODED_SLICE_IDR;
2262      }
2263    }
2264  }
2265  return NAL_UNIT_CODED_SLICE;
2266}
2267
2268NalUnitType TEncGOP::getNalUnitTypeBaseViewMvc(UInt uiPOCCurr)
2269{
2270  if( uiPOCCurr == 0 )
2271  {
2272    return NAL_UNIT_CODED_SLICE_IDR;
2273  }
2274  if( uiPOCCurr % m_pcCfg->getIntraPeriod() == 0 )
2275  {
2276    if( m_pcCfg->getDecodingRefreshType() == 1 )
2277    {
2278#if H0566_TLA
2279      return NAL_UNIT_CODED_SLICE_CRA;
2280#else
2281      return NAL_UNIT_CODED_SLICE_CDR;
2282#endif
2283    }
2284    else if( m_pcCfg->getDecodingRefreshType() == 2 )
2285    {
2286      return NAL_UNIT_CODED_SLICE_IDR;
2287    }
2288  }
2289  return NAL_UNIT_CODED_SLICE;
2290}
2291
2292Double TEncGOP::xCalculateRVM()
2293{
2294  Double dRVM = 0;
2295 
2296  if( m_pcCfg->getGOPSize() == 1 && m_pcCfg->getIntraPeriod() != 1 && m_pcCfg->getFrameToBeEncoded() > RVM_VCEGAM10_M * 2 )
2297  {
2298    // calculate RVM only for lowdelay configurations
2299    std::vector<Double> vRL , vB;
2300    size_t N = m_vRVM_RP.size();
2301    vRL.resize( N );
2302    vB.resize( N );
2303   
2304    Int i;
2305    Double dRavg = 0 , dBavg = 0;
2306    vB[RVM_VCEGAM10_M] = 0;
2307    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
2308    {
2309      vRL[i] = 0;
2310      for( Int j = i - RVM_VCEGAM10_M ; j <= i + RVM_VCEGAM10_M - 1 ; j++ )
2311        vRL[i] += m_vRVM_RP[j];
2312      vRL[i] /= ( 2 * RVM_VCEGAM10_M );
2313      vB[i] = vB[i-1] + m_vRVM_RP[i] - vRL[i];
2314      dRavg += m_vRVM_RP[i];
2315      dBavg += vB[i];
2316    }
2317   
2318    dRavg /= ( N - 2 * RVM_VCEGAM10_M );
2319    dBavg /= ( N - 2 * RVM_VCEGAM10_M );
2320   
2321    double dSigamB = 0;
2322    for( i = RVM_VCEGAM10_M + 1 ; i < N - RVM_VCEGAM10_M + 1 ; i++ )
2323    {
2324      Double tmp = vB[i] - dBavg;
2325      dSigamB += tmp * tmp;
2326    }
2327    dSigamB = sqrt( dSigamB / ( N - 2 * RVM_VCEGAM10_M ) );
2328   
2329    double f = sqrt( 12.0 * ( RVM_VCEGAM10_M - 1 ) / ( RVM_VCEGAM10_M + 1 ) );
2330   
2331    dRVM = dSigamB / dRavg * f;
2332  }
2333 
2334  return( dRVM );
2335}
2336
2337/** Determine the difference between consecutive tile sizes (in bytes) and writes it to  bistream rNalu [slice header]
2338 * \param rpcBitstreamRedirect contains the bitstream to be concatenated to rNalu. rpcBitstreamRedirect contains slice payload. rpcSlice contains tile location information.
2339 * \returns Updates rNalu to contain concatenated bitstream. rpcBitstreamRedirect is cleared at the end of this function call.
2340 */
2341Void TEncGOP::xWriteTileLocationToSliceHeader (OutputNALUnit& rNalu, TComOutputBitstream*& rpcBitstreamRedirect, TComSlice*& rpcSlice)
2342{
2343  {
2344#if !TILES_WPP_ENTRY_POINT_SIGNALLING
2345    Int iTransmitTileLocationInSliceHeader = (rpcSlice->getTileLocationCount()==0 || m_pcCfg->getTileLocationInSliceHeaderFlag()==0) ? 0 : 1;
2346    rNalu.m_Bitstream.write(iTransmitTileLocationInSliceHeader, 1);   // write flag indicating whether tile location information communicated in slice header
2347
2348    if (iTransmitTileLocationInSliceHeader)
2349    {
2350      rNalu.m_Bitstream.write(rpcSlice->getTileLocationCount()-1, 5);   // write number of tiles
2351
2352      Int *aiDiff;
2353      aiDiff = new Int [rpcSlice->getTileLocationCount()];
2354
2355      // Find largest number of bits required by Diff
2356      Int iLastSize = 0, iDiffMax = 0, iDiffMin = 0;
2357      for (UInt uiIdx=0; uiIdx<rpcSlice->getTileLocationCount(); uiIdx++)
2358      {
2359        Int iCurDiff, iCurSize;
2360        if (uiIdx==0)
2361        {
2362          iCurDiff  = rpcSlice->getTileLocation( uiIdx );
2363          iLastSize = rpcSlice->getTileLocation( uiIdx );
2364        }
2365        else
2366        {
2367          iCurSize  = rpcSlice->getTileLocation( uiIdx )  - rpcSlice->getTileLocation( uiIdx-1 );
2368          iCurDiff  = iCurSize - iLastSize;
2369          iLastSize = iCurSize;
2370        }
2371        // Store Diff so it may be written to slice header later without re-calculating.
2372        aiDiff[uiIdx] = iCurDiff;
2373
2374        if (iCurDiff>iDiffMax)
2375        {
2376          iDiffMax = iCurDiff;
2377        }
2378        if (iCurDiff<iDiffMin)
2379        {
2380          iDiffMin = iCurDiff;
2381        }
2382      }
2383
2384      Int iDiffMinAbs, iDiffMaxAbs;
2385      iDiffMinAbs = (iDiffMin<0) ? (-iDiffMin) : iDiffMin;
2386      iDiffMaxAbs = (iDiffMax<0) ? (-iDiffMax) : iDiffMax;
2387
2388      Int iBitsUsedByDiff = 0, iDiffAbsLargest;
2389      iDiffAbsLargest = (iDiffMinAbs < iDiffMaxAbs) ? iDiffMaxAbs : iDiffMinAbs;       
2390      while (1)
2391      {
2392        if (iDiffAbsLargest >= (1 << iBitsUsedByDiff) )
2393        {
2394          iBitsUsedByDiff++;
2395        }
2396        else
2397        {
2398          break;
2399        }
2400      }
2401      iBitsUsedByDiff++;
2402
2403      if (iBitsUsedByDiff > 32)
2404      {
2405        printf("\nDiff magnitude uses more than 32-bits");
2406        assert ( 0 );
2407        exit ( 0 ); // trying to catch any problems with using fixed bits for Diff information
2408      }
2409
2410      rNalu.m_Bitstream.write( iBitsUsedByDiff-1, 5 ); // write number of bits used by Diff
2411
2412      // Write diff to slice header (rNalu)
2413      for (UInt uiIdx=0; uiIdx<rpcSlice->getTileLocationCount(); uiIdx++)
2414      {
2415        Int iCurDiff = aiDiff[uiIdx];
2416
2417        // write sign of diff
2418        if (uiIdx!=0)
2419        {
2420          if (iCurDiff<0)         
2421          {
2422            rNalu.m_Bitstream.write(1, 1);
2423          }
2424          else
2425          {
2426            rNalu.m_Bitstream.write(0, 1);
2427          }
2428        }
2429
2430        // write abs value of diff
2431        Int iAbsDiff = (iCurDiff<0) ? (-iCurDiff) : iCurDiff;
2432        if (iAbsDiff > ((((UInt64)1)<<32)-1))
2433        {
2434          printf("\niAbsDiff exceeds 32-bit limit");
2435          exit(0);
2436        }
2437        rNalu.m_Bitstream.write( iAbsDiff, iBitsUsedByDiff-1 ); 
2438      }
2439
2440      delete [] aiDiff;
2441    }
2442#endif
2443  }
2444
2445  // Byte-align
2446  rNalu.m_Bitstream.writeAlignOne();
2447
2448  // Update tile marker locations
2449  TComOutputBitstream *pcOut = &rNalu.m_Bitstream;
2450  UInt uiAccumulatedLength   = pcOut->getNumberOfWrittenBits() >> 3;
2451  for (Int uiMrkIdx = 0; uiMrkIdx < rpcBitstreamRedirect->getTileMarkerLocationCount(); uiMrkIdx++)
2452  {
2453    UInt uiBottom = pcOut->getTileMarkerLocationCount();
2454    pcOut->setTileMarkerLocation      ( uiBottom, uiAccumulatedLength + rpcBitstreamRedirect->getTileMarkerLocation( uiMrkIdx ) );
2455    pcOut->setTileMarkerLocationCount ( uiBottom + 1 );
2456  }
2457
2458  // Perform bitstream concatenation
2459  if (rpcBitstreamRedirect->getNumberOfWrittenBits() > 0)
2460  {
2461    UInt uiBitCount  = rpcBitstreamRedirect->getNumberOfWrittenBits();
2462    if (rpcBitstreamRedirect->getByteStreamLength()>0)
2463    {
2464      UChar *pucStart  =  reinterpret_cast<UChar*>(rpcBitstreamRedirect->getByteStream());
2465      UInt uiWriteByteCount = 0;
2466      while (uiWriteByteCount < (uiBitCount >> 3) )
2467      {
2468        UInt uiBits = (*pucStart);
2469        rNalu.m_Bitstream.write(uiBits, 8);
2470        pucStart++;
2471        uiWriteByteCount++;
2472      }
2473    }
2474    UInt uiBitsHeld = (uiBitCount & 0x07);
2475    for (UInt uiIdx=0; uiIdx < uiBitsHeld; uiIdx++)
2476    {
2477      rNalu.m_Bitstream.write((rpcBitstreamRedirect->getHeldBits() & (1 << (7-uiIdx))) >> (7-uiIdx), 1);
2478    }         
2479  }
2480
2481  m_pcEntropyCoder->setBitstream(&rNalu.m_Bitstream);
2482
2483  delete rpcBitstreamRedirect;
2484  rpcBitstreamRedirect = new TComOutputBitstream;
2485}
2486
2487Void TEncGOP::xSetRefPicListModificationsMvc( TComSlice* pcSlice, UInt uiPOCCurr, UInt iGOPid )
2488{
2489  if( pcSlice->getSliceType() == I_SLICE || !(pcSlice->getSPS()->getListsModificationPresentFlag()) || pcSlice->getSPS()->getNumberOfUsableInterViewRefs() == 0 )
2490  {
2491    return;
2492  }
2493
2494  // analyze inter-view modifications
2495#if !QC_REM_IDV_B0046
2496  GOPEntryMvc gem = m_pcCfg->getGOPEntry( (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDV) ? MAX_GOP : iGOPid );
2497#else
2498  Bool bRAP = ((getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_IDR) || (getNalUnitType(uiPOCCurr) == NAL_UNIT_CODED_SLICE_CRA)) && (pcSlice->getSPS()->getViewId()) ? 1:0;
2499  GOPEntryMvc gem = m_pcCfg->getGOPEntry( bRAP ? MAX_GOP : iGOPid );
2500#endif
2501  Int numL0Modifications = 0;
2502  Int numL1Modifications = 0;
2503  for( Int k = 0; k < gem.m_numInterViewRefPics; k++ )
2504  {
2505    if( gem.m_interViewRefPosL0[k] > 0 ) { numL0Modifications++; }
2506    if( gem.m_interViewRefPosL1[k] > 0 ) { numL1Modifications++; }
2507  }
2508
2509  TComRefPicListModification* refPicListModification = pcSlice->getRefPicListModification();
2510  Int maxRefListSize = pcSlice->getNumPocTotalCurrMvc();
2511  Int numTemporalRefs = pcSlice->getNumPocTotalCurr();
2512
2513  // set L0 inter-view modifications
2514  if( (maxRefListSize > 1) && (numL0Modifications > 0) )
2515  {
2516    refPicListModification->setRefPicListModificationFlagL0( true );
2517    Int tempListEntryL0[16];
2518    for( Int k = 0; k < 16; k++ ) { tempListEntryL0[k] = -1; }
2519   
2520    Bool hasModification = false;
2521    for( Int k = 0; k < gem.m_numInterViewRefPics; k++ )
2522    {
2523      if( gem.m_interViewRefPosL0[k] > 0 )
2524      {
2525        for( Int l = 0; l < pcSlice->getSPS()->getNumberOfUsableInterViewRefs(); l++ )
2526        {
2527          if( gem.m_interViewRefs[k] == pcSlice->getSPS()->getUsableInterViewRef( l ) && (gem.m_interViewRefPosL0[k] - 1) != (numTemporalRefs + l) )
2528          {
2529            tempListEntryL0[gem.m_interViewRefPosL0[k]-1] = numTemporalRefs + l;
2530            hasModification = true;
2531          }
2532        }
2533      }
2534    }
2535
2536    if( hasModification )
2537    {
2538      Int temporalRefIdx = 0;
2539      for( Int i = 0; i < pcSlice->getNumRefIdx( REF_PIC_LIST_0 ); i++ )
2540      {
2541        if( tempListEntryL0[i] >= 0 ) 
2542        {
2543          refPicListModification->setRefPicSetIdxL0( i, tempListEntryL0[i] );
2544        }
2545        else
2546        {
2547          refPicListModification->setRefPicSetIdxL0( i, temporalRefIdx );
2548          temporalRefIdx++;
2549        }
2550      }
2551    }
2552    else
2553    {
2554      refPicListModification->setRefPicListModificationFlagL0( false );
2555    }
2556  }
2557
2558  // set L1 inter-view modifications
2559  if( (maxRefListSize > 1) && (numL1Modifications > 0) )
2560  {
2561    refPicListModification->setRefPicListModificationFlagL1( true );
2562    Int tempListEntryL1[16];
2563    for( Int k = 0; k < 16; k++ ) { tempListEntryL1[k] = -1; }
2564
2565    Bool hasModification = false;
2566    for( Int k = 0; k < gem.m_numInterViewRefPics; k++ )
2567    {
2568      if( gem.m_interViewRefPosL1[k] > 0 )
2569      {
2570        for( Int l = 0; l < pcSlice->getSPS()->getNumberOfUsableInterViewRefs(); l++ )
2571        {
2572          if( gem.m_interViewRefs[k] == pcSlice->getSPS()->getUsableInterViewRef( l ) && (gem.m_interViewRefPosL1[k] - 1) != (numTemporalRefs + l) )
2573          {
2574            tempListEntryL1[gem.m_interViewRefPosL1[k]-1] = numTemporalRefs + l;
2575            hasModification = true;
2576          }
2577        }
2578      }
2579    }
2580
2581    if( hasModification )
2582    {
2583      Int temporalRefIdx = 0;
2584      for( Int i = 0; i < pcSlice->getNumRefIdx( REF_PIC_LIST_1 ); i++ )
2585      {
2586        if( tempListEntryL1[i] >= 0 ) 
2587        {
2588          refPicListModification->setRefPicSetIdxL1( i, tempListEntryL1[i] );
2589        }
2590        else
2591        {
2592          refPicListModification->setRefPicSetIdxL1( i, temporalRefIdx );
2593          temporalRefIdx++;
2594        }
2595      }
2596    } 
2597    else
2598    {
2599      refPicListModification->setRefPicListModificationFlagL1( false );
2600    }
2601  }
2602
2603  return;
2604}
2605//! \}
Note: See TracBrowser for help on using the repository browser.