source: 3DVCSoftware/trunk/source/Lib/TLibEncoder/TEncTop.cpp @ 976

Last change on this file since 976 was 976, checked in by tech, 10 years ago
  • Merged 11.1-dev0@975. (Clean ups)
  • Added coding results.
  • Changed version number.
  • Property svn:eol-style set to native
File size: 47.7 KB
RevLine 
[5]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
[56]4 * granted under this license. 
[5]5 *
[872]6* Copyright (c) 2010-2014, ITU/ISO/IEC
[5]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.
[56]17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
[5]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 */
[2]33
34/** \file     TEncTop.cpp
35    \brief    encoder class
36*/
37
[56]38#include "TLibCommon/CommonDef.h"
[2]39#include "TEncTop.h"
[56]40#include "TEncPic.h"
41#if FAST_BIT_EST
42#include "TLibCommon/ContextModel.h"
43#endif
[608]44#if H_MV
45#include "../../App/TAppEncoder/TAppEncTop.h"
46#endif
[2]47
[56]48//! \ingroup TLibEncoder
49//! \{
50
[2]51// ====================================================================================================================
52// Constructor / destructor / create / destroy
53// ====================================================================================================================
54
55TEncTop::TEncTop()
56{
57  m_iPOCLast          = -1;
58  m_iNumPicRcvd       =  0;
59  m_uiNumAllPicCoded  =  0;
60  m_pppcRDSbacCoder   =  NULL;
61  m_pppcBinCoderCABAC =  NULL;
62  m_cRDGoOnSbacCoder.init( &m_cRDGoOnBinCoderCABAC );
63#if ENC_DEC_TRACE
64  g_hTrace = fopen( "TraceEnc.txt", "wb" );
65  g_bJustDoIt = g_bEncDecTraceDisable;
66  g_nSymbolCounter = 0;
67#endif
[56]68
69  m_iMaxRefPicNum     = 0;
70
71#if FAST_BIT_EST
72  ContextModel::buildNextStateTable();
73#endif
74
75  m_pcSbacCoders           = NULL;
76  m_pcBinCoderCABACs       = NULL;
77  m_ppppcRDSbacCoders      = NULL;
78  m_ppppcBinCodersCABAC    = NULL;
79  m_pcRDGoOnSbacCoders     = NULL;
80  m_pcRDGoOnBinCodersCABAC = NULL;
81  m_pcBitCounters          = NULL;
82  m_pcRdCosts              = NULL;
[608]83#if H_MV
84  m_ivPicLists = NULL;
85#endif
[2]86}
87
88TEncTop::~TEncTop()
89{
90#if ENC_DEC_TRACE
91  fclose( g_hTrace );
92#endif
93}
94
95Void TEncTop::create ()
96{
[608]97#if !H_MV
[2]98  // initialize global variables
[608]99  initROM();
100#endif
101 
[2]102  // create processing unit classes
[608]103  m_cGOPEncoder.        create();
[2]104  m_cSliceEncoder.      create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
105  m_cCuEncoder.         create( g_uiMaxCUDepth, g_uiMaxCUWidth, g_uiMaxCUHeight );
106  if (m_bUseSAO)
107  {
[872]108    m_cEncSAO.create( getSourceWidth(), getSourceHeight(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
109#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
110    m_cEncSAO.createEncData(getSaoLcuBoundary());
111#else
112    m_cEncSAO.createEncData();
113#endif
[2]114  }
[56]115#if ADAPTIVE_QP_SELECTION
116  if (m_bUseAdaptQpSelect)
117  {
118    m_cTrQuant.initSliceQpDelta();
119  }
[2]120#endif
121  m_cLoopFilter.        create( g_uiMaxCUDepth );
122
[608]123  if ( m_RCEnableRateControl )
[2]124  {
[655]125#if KWU_RC_MADPRED_E0227
[608]126    m_cRateCtrl.init( m_framesToBeEncoded, m_RCTargetBitrate, m_iFrameRate, m_iGOPSize, m_iSourceWidth, m_iSourceHeight,
[655]127      g_uiMaxCUWidth, g_uiMaxCUHeight, m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList, getLayerId() );
128#else
129    m_cRateCtrl.init( m_framesToBeEncoded, m_RCTargetBitrate, m_iFrameRate, m_iGOPSize, m_iSourceWidth, m_iSourceHeight,
[608]130                      g_uiMaxCUWidth, g_uiMaxCUHeight, m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList );
[655]131#endif
[2]132  }
[56]133    m_pppcRDSbacCoder = new TEncSbac** [g_uiMaxCUDepth+1];
134#if FAST_BIT_EST
135    m_pppcBinCoderCABAC = new TEncBinCABACCounter** [g_uiMaxCUDepth+1];
136#else
137    m_pppcBinCoderCABAC = new TEncBinCABAC** [g_uiMaxCUDepth+1];
138#endif
139   
140    for ( Int iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
[2]141    {
142      m_pppcRDSbacCoder[iDepth] = new TEncSbac* [CI_NUM];
[56]143#if FAST_BIT_EST
144      m_pppcBinCoderCABAC[iDepth] = new TEncBinCABACCounter* [CI_NUM];
145#else
[2]146      m_pppcBinCoderCABAC[iDepth] = new TEncBinCABAC* [CI_NUM];
[56]147#endif
148     
[2]149      for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
150      {
151        m_pppcRDSbacCoder[iDepth][iCIIdx] = new TEncSbac;
[56]152#if FAST_BIT_EST
153        m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABACCounter;
154#else
[2]155        m_pppcBinCoderCABAC [iDepth][iCIIdx] = new TEncBinCABAC;
[56]156#endif
[2]157        m_pppcRDSbacCoder   [iDepth][iCIIdx]->init( m_pppcBinCoderCABAC [iDepth][iCIIdx] );
158      }
159    }
160  }
161
[56]162/**
163 - Allocate coders required for wavefront for the nominated number of substreams.
164 .
165 \param iNumSubstreams Determines how much information to allocate.
166 */
167Void TEncTop::createWPPCoders(Int iNumSubstreams)
168{
169  if (m_pcSbacCoders != NULL)
[608]170  {
[56]171    return; // already generated.
[608]172  }
[56]173
174  m_iNumSubstreams         = iNumSubstreams;
175  m_pcSbacCoders           = new TEncSbac       [iNumSubstreams];
176  m_pcBinCoderCABACs       = new TEncBinCABAC   [iNumSubstreams];
177  m_pcRDGoOnSbacCoders     = new TEncSbac       [iNumSubstreams];
178  m_pcRDGoOnBinCodersCABAC = new TEncBinCABAC   [iNumSubstreams];
179  m_pcBitCounters          = new TComBitCounter [iNumSubstreams];
180  m_pcRdCosts              = new TComRdCost     [iNumSubstreams];
181
182  for ( UInt ui = 0 ; ui < iNumSubstreams; ui++ )
183  {
184    m_pcRDGoOnSbacCoders[ui].init( &m_pcRDGoOnBinCodersCABAC[ui] );
185    m_pcSbacCoders[ui].init( &m_pcBinCoderCABACs[ui] );
186  }
[872]187
[56]188    m_ppppcRDSbacCoders      = new TEncSbac***    [iNumSubstreams];
189    m_ppppcBinCodersCABAC    = new TEncBinCABAC***[iNumSubstreams];
190    for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ )
191    {
192      m_ppppcRDSbacCoders[ui]  = new TEncSbac** [g_uiMaxCUDepth+1];
193      m_ppppcBinCodersCABAC[ui]= new TEncBinCABAC** [g_uiMaxCUDepth+1];
194     
195      for ( Int iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
196      {
197        m_ppppcRDSbacCoders[ui][iDepth]  = new TEncSbac*     [CI_NUM];
198        m_ppppcBinCodersCABAC[ui][iDepth]= new TEncBinCABAC* [CI_NUM];
199
200        for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
201        {
202          m_ppppcRDSbacCoders  [ui][iDepth][iCIIdx] = new TEncSbac;
203          m_ppppcBinCodersCABAC[ui][iDepth][iCIIdx] = new TEncBinCABAC;
204          m_ppppcRDSbacCoders  [ui][iDepth][iCIIdx]->init( m_ppppcBinCodersCABAC[ui][iDepth][iCIIdx] );
205        }
206      }
207    }
208  }
209
[2]210Void TEncTop::destroy ()
211{
212  // destroy processing unit classes
[56]213  m_cGOPEncoder.        destroy();
[2]214  m_cSliceEncoder.      destroy();
215  m_cCuEncoder.         destroy();
216  if (m_cSPS.getUseSAO())
217  {
[872]218    m_cEncSAO.destroyEncData();
[2]219    m_cEncSAO.destroy();
220  }
221  m_cLoopFilter.        destroy();
[608]222  m_cRateCtrl.          destroy();
[872]223
[2]224    Int iDepth;
225    for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
226    {
227      for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
228      {
229        delete m_pppcRDSbacCoder[iDepth][iCIIdx];
230        delete m_pppcBinCoderCABAC[iDepth][iCIIdx];
231      }
232    }
[56]233   
[2]234    for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
235    {
236      delete [] m_pppcRDSbacCoder[iDepth];
237      delete [] m_pppcBinCoderCABAC[iDepth];
238    }
[56]239   
[2]240    delete [] m_pppcRDSbacCoder;
241    delete [] m_pppcBinCoderCABAC;
[56]242
243    for ( UInt ui = 0; ui < m_iNumSubstreams; ui++ )
244    {
245      for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
246      {
247        for (Int iCIIdx = 0; iCIIdx < CI_NUM; iCIIdx ++ )
248        {
249          delete m_ppppcRDSbacCoders  [ui][iDepth][iCIIdx];
250          delete m_ppppcBinCodersCABAC[ui][iDepth][iCIIdx];
251        }
252      }
253
254      for ( iDepth = 0; iDepth < g_uiMaxCUDepth+1; iDepth++ )
255      {
256        delete [] m_ppppcRDSbacCoders  [ui][iDepth];
257        delete [] m_ppppcBinCodersCABAC[ui][iDepth];
258      }
259      delete[] m_ppppcRDSbacCoders  [ui];
260      delete[] m_ppppcBinCodersCABAC[ui];
261    }
262    delete[] m_ppppcRDSbacCoders;
263    delete[] m_ppppcBinCodersCABAC;
264  delete[] m_pcSbacCoders;
265  delete[] m_pcBinCoderCABACs;
266  delete[] m_pcRDGoOnSbacCoders; 
267  delete[] m_pcRDGoOnBinCodersCABAC;
268  delete[] m_pcBitCounters;
269  delete[] m_pcRdCosts;
270 
[608]271#if !H_MV
272    // destroy ROM
[56]273  destroyROM();
[608]274#endif
275
[2]276  return;
277}
278
[655]279#if KWU_RC_MADPRED_E0227
280Void TEncTop::init(TAppEncTop* pcTAppEncTop, Bool isFieldCoding)
281#else
282Void TEncTop::init(Bool isFieldCoding)
283#endif
[2]284{
285  // initialize SPS
[773]286#if H_3D
[758]287  // Assuming that all PPS indirectly refer to the same VPS via different SPS
288  m_cSPS.setVPS(m_cVPS);
289#endif
[2]290  xInitSPS();
[56]291 
[608]292  /* set the VPS profile information */
293#if H_MV
294  // This seems to be incorrect, but irrelevant for the MV-HEVC
295  *(m_cVPS->getPTL()) = *m_cSPS.getPTL();
296  m_cVPS->getTimingInfo()->setTimingInfoPresentFlag       ( false );
297#else
298  *m_cVPS.getPTL() = *m_cSPS.getPTL();
299  m_cVPS.getTimingInfo()->setTimingInfoPresentFlag       ( false );
300#endif
[2]301  // initialize PPS
[56]302  m_cPPS.setSPS(&m_cSPS);
[2]303  xInitPPS();
[655]304  xInitRPS(isFieldCoding);
[2]305
[56]306  xInitPPSforTiles();
307
[2]308  // initialize processing unit classes
[56]309  m_cGOPEncoder.  init( this );
[2]310  m_cSliceEncoder.init( this );
311  m_cCuEncoder.   init( this );
[56]312 
[655]313#if KWU_RC_MADPRED_E0227
314  m_pcTAppEncTop = pcTAppEncTop;
315#endif
[2]316  // initialize transform & quantization class
317  m_pcCavlcCoder = getCavlcCoder();
[56]318 
[608]319  m_cTrQuant.init( 1 << m_uiQuadtreeTULog2MaxSize,
320                  m_useRDOQ, 
321                  m_useRDOQTS,
322                  true 
323                  ,m_useTransformSkipFast
[56]324#if ADAPTIVE_QP_SELECTION                 
325                  , m_bUseAdaptQpSelect
[2]326#endif
[56]327                  );
328 
[2]329  // initialize encoder search class
330  m_cSearch.init( this, &m_cTrQuant, m_iSearchRange, m_bipredSearchRange, m_iFastSearch, 0, &m_cEntropyCoder, &m_cRdCost, getRDSbacCoder(), getRDGoOnSbacCoder() );
[56]331
332  m_iMaxRefPicNum = 0;
[2]333}
334
335// ====================================================================================================================
336// Public member functions
337// ====================================================================================================================
338
[608]339#if H_MV
340Void TEncTop::initNewPic( TComPicYuv* pcPicYuvOrg )
[56]341{
342  TComPic* pcPicCurr = NULL;
343
344  // get original YUV
345  xGetNewPicBuffer( pcPicCurr );
346  pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() );
347
348  // compute image characteristics
349  if ( getUseAdaptiveQP() )
350  {
351    m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
352  }
[608]353#if H_MV
354  pcPicCurr->setLayerId( getLayerId()); 
355#endif
356#if H_3D
357  pcPicCurr->setScaleOffset( m_aaiCodedScale, m_aaiCodedOffset );
358#endif
[56]359}
[608]360#endif
[2]361Void TEncTop::deletePicBuffer()
362{
363  TComList<TComPic*>::iterator iterPic = m_cListPic.begin();
364  Int iSize = Int( m_cListPic.size() );
[56]365 
[2]366  for ( Int i = 0; i < iSize; i++ )
367  {
368    TComPic* pcPic = *(iterPic++);
[56]369   
[2]370    pcPic->destroy();
371    delete pcPic;
372    pcPic = NULL;
373  }
374}
375
376/**
377 - Application has picture buffer list with size of GOP + 1
378 - Picture buffer list acts like as ring buffer
379 - End of the list has the latest picture
380 .
[608]381 \param   flush               cause encoder to encode a partial GOP
[2]382 \param   pcPicYuvOrg         original YUV picture
383 \retval  rcListPicYuvRecOut  list of reconstruction YUV pictures
384 \retval  rcListBitstreamOut  list of output bitstreams
385 \retval  iNumEncoded         number of encoded pictures
386 */
[608]387#if H_MV
388Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded , Int gopId )
389{
390#else
391Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded )
392{
393#endif
394#if H_3D
395  TComPic* picLastCoded = getPic( getGOPEncoder()->getPocLastCoded() );
396  if( picLastCoded )
397  {
398    picLastCoded->compressMotion(1); 
399  }
400#endif
401#if H_MV
[56]402  if( gopId == 0)
[2]403  {
[56]404    m_cGOPEncoder.initGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut); 
[608]405#else
406  if (pcPicYuvOrg) {
407    // get original YUV
408    TComPic* pcPicCurr = NULL;
409    xGetNewPicBuffer( pcPicCurr );
410    pcPicYuvOrg->copyToPic( pcPicCurr->getPicYuvOrg() );
411
412    // compute image characteristics
413    if ( getUseAdaptiveQP() )
414    {
415      m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcPicCurr ) );
416    }
[2]417  }
[608]418 
419  if (!m_iNumPicRcvd || (!flush && m_iPOCLast != 0 && m_iNumPicRcvd != m_iGOPSize && m_iGOPSize))
[2]420  {
[608]421    iNumEncoded = 0;
422    return;
[2]423  }
[608]424#endif
[56]425 
[608]426  if ( m_RCEnableRateControl )
[2]427  {
[608]428    m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
[2]429  }
[608]430#if H_MV
431  }
[655]432  m_cGOPEncoder.compressPicInGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, gopId, false, false );
[2]433
[608]434  if( gopId + 1 == m_cGOPEncoder.getGOPSize() )
[2]435  {
[608]436#else
437  // compress GOP
[655]438  m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, false, false);
[5]439#endif
[2]440
[608]441  if ( m_RCEnableRateControl )
[2]442  {
[608]443    m_cRateCtrl.destroyRCGOP();
[2]444  }
[608]445 
446  iNumEncoded         = m_iNumPicRcvd;
447  m_iNumPicRcvd       = 0;
448  m_uiNumAllPicCoded += iNumEncoded;
449#if H_MV
[2]450}
[608]451#endif
452}
[655]453/**------------------------------------------------
454 Separate interlaced frame into two fields
455 -------------------------------------------------**/
456void separateFields(Pel* org, Pel* dstField, UInt stride, UInt width, UInt height, bool isTop)
457{
458  if (!isTop)
459  {
460    org += stride;
461  }
462  for (Int y = 0; y < height>>1; y++)
463  {
464    for (Int x = 0; x < width; x++)
465    {
466      dstField[x] = org[x];
467    }
468   
469    dstField += stride;
470    org += stride*2;
471  }
472 
473}
[2]474
[655]475#if H_MV
476Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, bool isTff, Int gopId )
477{
478  assert( 0 ); // Field coding and multiview need to be furhter harmonized.
479}
480#else
481Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, bool isTff)
482{
483  /* -- TOP FIELD -- */
484 
485  if (pcPicYuvOrg)
486  {
487   
488    /* -- Top field initialization -- */
489   
490    TComPic *pcTopField;
491    xGetNewPicBuffer( pcTopField );
492    pcTopField->setReconMark (false);
493   
494    pcTopField->getSlice(0)->setPOC( m_iPOCLast );
495    pcTopField->getPicYuvRec()->setBorderExtension(false);
496    pcTopField->setTopField(isTff);
497   
498    int nHeight = pcPicYuvOrg->getHeight();
499    int nWidth = pcPicYuvOrg->getWidth();
500    int nStride = pcPicYuvOrg->getStride();
501    int nPadLuma = pcPicYuvOrg->getLumaMargin();
502    int nPadChroma = pcPicYuvOrg->getChromaMargin();
503   
504    // Get pointers
505    Pel * PicBufY = pcPicYuvOrg->getBufY();
506    Pel * PicBufU = pcPicYuvOrg->getBufU();
507    Pel * PicBufV = pcPicYuvOrg->getBufV();
508   
509    Pel * pcTopFieldY =  pcTopField->getPicYuvOrg()->getLumaAddr();
510    Pel * pcTopFieldU =  pcTopField->getPicYuvOrg()->getCbAddr();
511    Pel * pcTopFieldV =  pcTopField->getPicYuvOrg()->getCrAddr();
512   
513    /* -- Defield -- */
514   
515    bool isTop = isTff;
516   
517    separateFields(PicBufY + nPadLuma + nStride*nPadLuma, pcTopFieldY, nStride, nWidth, nHeight, isTop);
518    separateFields(PicBufU + nPadChroma + (nStride >> 1)*nPadChroma, pcTopFieldU, nStride >> 1, nWidth >> 1, nHeight >> 1, isTop);
519    separateFields(PicBufV + nPadChroma + (nStride >> 1)*nPadChroma, pcTopFieldV, nStride >> 1, nWidth >> 1, nHeight >> 1, isTop);
520   
[872]521    // compute image characteristics
522    if ( getUseAdaptiveQP() )
523    {
524      m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcTopField ) );
525    }   
[655]526  }
527 
528  if (m_iPOCLast == 0) // compress field 0
529  {
530    m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, true, isTff);
531  }
532 
533  /* -- BOTTOM FIELD -- */
534 
535  if (pcPicYuvOrg)
536  {
537   
538    /* -- Bottom field initialization -- */
539   
540    TComPic* pcBottomField;
541    xGetNewPicBuffer( pcBottomField );
542    pcBottomField->setReconMark (false);
543   
[872]544    TComPicYuv* rpcPicYuvRec;
[655]545    if ( rcListPicYuvRecOut.size() == (UInt)m_iGOPSize )
546    {
547      rpcPicYuvRec = rcListPicYuvRecOut.popFront();
548    }
549    else
550    {
[872]551      rpcPicYuvRec = new TComPicYuv;
[655]552      rpcPicYuvRec->create( m_iSourceWidth, m_iSourceHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth );
553    }
554    rcListPicYuvRecOut.pushBack( rpcPicYuvRec );
555   
556    pcBottomField->getSlice(0)->setPOC( m_iPOCLast);
557    pcBottomField->getPicYuvRec()->setBorderExtension(false);
558    pcBottomField->setTopField(!isTff);
559   
560    int nHeight = pcPicYuvOrg->getHeight();
561    int nWidth = pcPicYuvOrg->getWidth();
562    int nStride = pcPicYuvOrg->getStride();
563    int nPadLuma = pcPicYuvOrg->getLumaMargin();
564    int nPadChroma = pcPicYuvOrg->getChromaMargin();
565   
566    // Get pointers
567    Pel * PicBufY = pcPicYuvOrg->getBufY();
568    Pel * PicBufU = pcPicYuvOrg->getBufU();
569    Pel * PicBufV = pcPicYuvOrg->getBufV();
570   
571    Pel * pcBottomFieldY =  pcBottomField->getPicYuvOrg()->getLumaAddr();
572    Pel * pcBottomFieldU =  pcBottomField->getPicYuvOrg()->getCbAddr();
573    Pel * pcBottomFieldV =  pcBottomField->getPicYuvOrg()->getCrAddr();
574   
575    /* -- Defield -- */
576   
577    bool isTop = !isTff;
578   
579    separateFields(PicBufY + nPadLuma + nStride*nPadLuma, pcBottomFieldY, nStride, nWidth, nHeight, isTop);
580    separateFields(PicBufU + nPadChroma + (nStride >> 1)*nPadChroma, pcBottomFieldU, nStride >> 1, nWidth >> 1, nHeight >> 1, isTop);
581    separateFields(PicBufV + nPadChroma + (nStride >> 1)*nPadChroma, pcBottomFieldV, nStride >> 1, nWidth >> 1, nHeight >> 1, isTop);
582   
[872]583    // Compute image characteristics
584    if ( getUseAdaptiveQP() )
585    {
586      m_cPreanalyzer.xPreanalyze( dynamic_cast<TEncPic*>( pcBottomField ) );
587    }   
[655]588  }
589 
590  if ( ( !(m_iNumPicRcvd) || (!flush && m_iPOCLast != 1 && m_iNumPicRcvd != m_iGOPSize && m_iGOPSize)) )
591  {
592    iNumEncoded = 0;
593    return;
594  }
595 
596  // compress GOP
597  m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, true, isTff);
598 
599  iNumEncoded = m_iNumPicRcvd;
600  m_iNumPicRcvd = 0;
601  m_uiNumAllPicCoded += iNumEncoded;
602}
603#endif
[2]604// ====================================================================================================================
605// Protected member functions
606// ====================================================================================================================
607
608/**
609 - Application has picture buffer list with size of GOP + 1
610 - Picture buffer list acts like as ring buffer
611 - End of the list has the latest picture
612 .
613 \retval rpcPic obtained picture buffer
614 */
615Void TEncTop::xGetNewPicBuffer ( TComPic*& rpcPic )
616{
617  TComSlice::sortPicList(m_cListPic);
[56]618 
619  if (m_cListPic.size() >= (UInt)(m_iGOPSize + getMaxDecPicBuffering(MAX_TLAYER-1) + 2) )
[2]620  {
[56]621    TComList<TComPic*>::iterator iterPic  = m_cListPic.begin();
622    Int iSize = Int( m_cListPic.size() );
623    for ( Int i = 0; i < iSize; i++ )
624    {
[608]625      rpcPic = *(iterPic++);
[56]626      if(rpcPic->getSlice(0)->isReferenced() == false)
[608]627      {
628        break;
629      }
[56]630    }
[2]631  }
632  else
633  {
[608]634    if ( getUseAdaptiveQP() )
635    {
636      TEncPic* pcEPic = new TEncPic;
637      pcEPic->create( m_iSourceWidth, m_iSourceHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, m_cPPS.getMaxCuDQPDepth()+1 ,
638                      m_conformanceWindow, m_defaultDisplayWindow, m_numReorderPics);
639      rpcPic = pcEPic;
640    }
641    else
642    {
643      rpcPic = new TComPic;
644
645      rpcPic->create( m_iSourceWidth, m_iSourceHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, 
646                      m_conformanceWindow, m_defaultDisplayWindow, m_numReorderPics);
647    }
[56]648    m_cListPic.pushBack( rpcPic );
[2]649  }
650  rpcPic->setReconMark (false);
[56]651 
[2]652  m_iPOCLast++;
653  m_iNumPicRcvd++;
[56]654 
[2]655  rpcPic->getSlice(0)->setPOC( m_iPOCLast );
656  // mark it should be extended
657  rpcPic->getPicYuvRec()->setBorderExtension(false);
[622]658
659#if H_MV
[608]660  rpcPic->getPicYuvOrg()->setBorderExtension(false);
[622]661#endif
[2]662}
663
664Void TEncTop::xInitSPS()
665{
[608]666#if H_MV
667  m_cSPS.setSPSId( getLayerIdInVps() );
668  m_cSPS.setLayerId( getLayerId() );
[872]669 // Code below needs to be moved to VPS
670#endif
[608]671  ProfileTierLevel& profileTierLevel = *m_cSPS.getPTL()->getGeneralPTL();
672  profileTierLevel.setLevelIdc(m_level);
673  profileTierLevel.setTierFlag(m_levelTier);
674  profileTierLevel.setProfileIdc(m_profile);
675  profileTierLevel.setProfileCompatibilityFlag(m_profile, 1);
676  profileTierLevel.setProgressiveSourceFlag(m_progressiveSourceFlag);
677  profileTierLevel.setInterlacedSourceFlag(m_interlacedSourceFlag);
678  profileTierLevel.setNonPackedConstraintFlag(m_nonPackedConstraintFlag);
679  profileTierLevel.setFrameOnlyConstraintFlag(m_frameOnlyConstraintFlag);
680 
681  if (m_profile == Profile::MAIN10 && g_bitDepthY == 8 && g_bitDepthC == 8)
682  {
683    /* The above constraint is equal to Profile::MAIN */
684    profileTierLevel.setProfileCompatibilityFlag(Profile::MAIN, 1);
685  }
686  if (m_profile == Profile::MAIN)
687  {
688    /* A Profile::MAIN10 decoder can always decode Profile::MAIN */
689    profileTierLevel.setProfileCompatibilityFlag(Profile::MAIN10, 1);
690  }
691  /* XXX: should Main be marked as compatible with still picture? */
692  /* XXX: may be a good idea to refactor the above into a function
693   * that chooses the actual compatibility based upon options */
694
[622]695#if H_MV 
[738]696  m_cSPS.setUpdateRepFormatFlag           ( false );   
[622]697  m_cSPS.setSpsInferScalingListFlag       ( m_layerId > 0 && m_cVPS->getInDirectDependencyFlag( getLayerIdInVps(), 0 ) ); 
698  m_cSPS.setSpsScalingListRefLayerId      ( 0              ); 
[964]699  m_cSPS.setSpsExtensionPresentFlag              ( true ); 
700  m_cSPS.setSpsMultilayerExtensionFlag    ( true ); 
[738]701#if H_3D
[964]702  m_cSPS.setSps3dExtensionFlag            ( true ); 
[622]703#endif
[738]704#endif
[56]705  m_cSPS.setPicWidthInLumaSamples         ( m_iSourceWidth      );
706  m_cSPS.setPicHeightInLumaSamples        ( m_iSourceHeight     );
[608]707  m_cSPS.setConformanceWindow             ( m_conformanceWindow );
[2]708  m_cSPS.setMaxCUWidth    ( g_uiMaxCUWidth      );
709  m_cSPS.setMaxCUHeight   ( g_uiMaxCUHeight     );
710  m_cSPS.setMaxCUDepth    ( g_uiMaxCUDepth      );
[608]711
712  Int minCUSize = m_cSPS.getMaxCUWidth() >> ( m_cSPS.getMaxCUDepth()-g_uiAddCUDepth );
713  Int log2MinCUSize = 0;
714  while(minCUSize > 1)
715  {
716    minCUSize >>= 1;
717    log2MinCUSize++;
718  }
719
720  m_cSPS.setLog2MinCodingBlockSize(log2MinCUSize);
721  m_cSPS.setLog2DiffMaxMinCodingBlockSize(m_cSPS.getMaxCUDepth()-g_uiAddCUDepth);
[56]722 
723  m_cSPS.setPCMLog2MinSize (m_uiPCMLog2MinSize);
724  m_cSPS.setUsePCM        ( m_usePCM           );
725  m_cSPS.setPCMLog2MaxSize( m_pcmLog2MaxSize  );
[2]726
727  m_cSPS.setQuadtreeTULog2MaxSize( m_uiQuadtreeTULog2MaxSize );
728  m_cSPS.setQuadtreeTULog2MinSize( m_uiQuadtreeTULog2MinSize );
729  m_cSPS.setQuadtreeTUMaxDepthInter( m_uiQuadtreeTUMaxDepthInter    );
730  m_cSPS.setQuadtreeTUMaxDepthIntra( m_uiQuadtreeTUMaxDepthIntra    );
[56]731 
[608]732  m_cSPS.setTMVPFlagsPresent(false);
733
[56]734  m_cSPS.setMaxTrSize   ( 1 << m_uiQuadtreeTULog2MaxSize );
735 
736  Int i;
737 
[608]738  for (i = 0; i < g_uiMaxCUDepth-g_uiAddCUDepth; i++ )
[56]739  {
740    m_cSPS.setAMPAcc( i, m_useAMP );
741    //m_cSPS.setAMPAcc( i, 1 );
742  }
[2]743
[56]744  m_cSPS.setUseAMP ( m_useAMP );
[2]745
[608]746#if H_3D_QTLPC
747  m_cSPS.setUseQTL( m_bUseQTL );
748  m_cSPS.setUsePC ( m_bUsePC  );
749#endif
750
751  for (i = g_uiMaxCUDepth-g_uiAddCUDepth; i < g_uiMaxCUDepth; i++ )
[56]752  {
753    m_cSPS.setAMPAcc(i, 0);
754  }
755
[608]756  m_cSPS.setBitDepthY( g_bitDepthY );
757  m_cSPS.setBitDepthC( g_bitDepthC );
[2]758
[608]759  m_cSPS.setQpBDOffsetY ( 6*(g_bitDepthY - 8) );
760  m_cSPS.setQpBDOffsetC ( 6*(g_bitDepthC - 8) );
761
[56]762  m_cSPS.setUseSAO( m_bUseSAO );
[2]763
[56]764  m_cSPS.setMaxTLayers( m_maxTempLayer );
[608]765  m_cSPS.setTemporalIdNestingFlag( ( m_maxTempLayer == 1 ) ? true : false );
[872]766  for ( i = 0; i < min(m_cSPS.getMaxTLayers(),(UInt) MAX_TLAYER); i++ )
[56]767  {
768    m_cSPS.setMaxDecPicBuffering(m_maxDecPicBuffering[i], i);
769    m_cSPS.setNumReorderPics(m_numReorderPics[i], i);
770  }
[976]771#if H_MV
[964]772  for ( Int ols = 0; ols < m_cVPS->getNumOutputLayerSets(); ols++)
773  {
774    // Check MaxDecPicBuffering
775    const std::vector<Int>& targetDecLayerIdList = m_cVPS->getTargetDecLayerIdList( m_cVPS->olsIdxToLsIdx( ols )); 
776    for( Int is = 0; is < targetDecLayerIdList.size(); is++  )
777    {
778      m_cSPS.inferSpsMaxDecPicBufferingMinus1( m_cVPS, ols, targetDecLayerIdList[is], true );       
779    }
780  }
781
782  m_cVPS->inferDbpSizeLayerSetZero( &m_cSPS, true ); 
783#endif
[56]784  m_cSPS.setPCMBitDepthLuma (g_uiPCMBitDepthLuma);
785  m_cSPS.setPCMBitDepthChroma (g_uiPCMBitDepthChroma);
786  m_cSPS.setPCMFilterDisableFlag  ( m_bPCMFilterDisableFlag );
[42]787
[56]788  m_cSPS.setScalingListFlag ( (m_useScalingListId == 0) ? 0 : 1 );
789
[608]790  m_cSPS.setUseStrongIntraSmoothing( m_useStrongIntraSmoothing );
[210]791
[608]792  m_cSPS.setVuiParametersPresentFlag(getVuiParametersPresentFlag());
793  if (m_cSPS.getVuiParametersPresentFlag())
[56]794  {
[608]795    TComVUI* pcVUI = m_cSPS.getVuiParameters();
796    pcVUI->setAspectRatioInfoPresentFlag(getAspectRatioIdc() != -1);
797    pcVUI->setAspectRatioIdc(getAspectRatioIdc());
798    pcVUI->setSarWidth(getSarWidth());
799    pcVUI->setSarHeight(getSarHeight());
800    pcVUI->setOverscanInfoPresentFlag(getOverscanInfoPresentFlag());
801    pcVUI->setOverscanAppropriateFlag(getOverscanAppropriateFlag());
[773]802#if H_MV
[738]803    pcVUI->setVideoSignalTypePresentFlag(getVideoSignalTypePresentFlag() && getLayerId() == 0 );
804#else
[773]805   pcVUI->setVideoSignalTypePresentFlag(getVideoSignalTypePresentFlag());
[738]806#endif
[608]807    pcVUI->setVideoFormat(getVideoFormat());
808    pcVUI->setVideoFullRangeFlag(getVideoFullRangeFlag());
809    pcVUI->setColourDescriptionPresentFlag(getColourDescriptionPresentFlag());
810    pcVUI->setColourPrimaries(getColourPrimaries());
811    pcVUI->setTransferCharacteristics(getTransferCharacteristics());
812    pcVUI->setMatrixCoefficients(getMatrixCoefficients());
813    pcVUI->setChromaLocInfoPresentFlag(getChromaLocInfoPresentFlag());
814    pcVUI->setChromaSampleLocTypeTopField(getChromaSampleLocTypeTopField());
815    pcVUI->setChromaSampleLocTypeBottomField(getChromaSampleLocTypeBottomField());
816    pcVUI->setNeutralChromaIndicationFlag(getNeutralChromaIndicationFlag());
817    pcVUI->setDefaultDisplayWindow(getDefaultDisplayWindow());
818    pcVUI->setFrameFieldInfoPresentFlag(getFrameFieldInfoPresentFlag());
819    pcVUI->setFieldSeqFlag(false);
820    pcVUI->setHrdParametersPresentFlag(false);
821    pcVUI->getTimingInfo()->setPocProportionalToTimingFlag(getPocProportionalToTimingFlag());
822    pcVUI->getTimingInfo()->setNumTicksPocDiffOneMinus1   (getNumTicksPocDiffOneMinus1()   );
823    pcVUI->setBitstreamRestrictionFlag(getBitstreamRestrictionFlag());
824    pcVUI->setTilesFixedStructureFlag(getTilesFixedStructureFlag());
825    pcVUI->setMotionVectorsOverPicBoundariesFlag(getMotionVectorsOverPicBoundariesFlag());
826    pcVUI->setMinSpatialSegmentationIdc(getMinSpatialSegmentationIdc());
827    pcVUI->setMaxBytesPerPicDenom(getMaxBytesPerPicDenom());
828    pcVUI->setMaxBitsPerMinCuDenom(getMaxBitsPerMinCuDenom());
829    pcVUI->setLog2MaxMvLengthHorizontal(getLog2MaxMvLengthHorizontal());
830    pcVUI->setLog2MaxMvLengthVertical(getLog2MaxMvLengthVertical());
[2]831  }
[56]832}
[2]833
[56]834Void TEncTop::xInitPPS()
835{
[608]836#if H_MV
[622]837  m_cPPS.setLayerId( getLayerId() );
838  if( getVPS()->getNumDirectRefLayers( getLayerId() ) > 0 )
[608]839  {
840    m_cPPS.setListsModificationPresentFlag( true );
841  }
842  m_cPPS.setPPSId( getLayerIdInVps() );
843  m_cPPS.setSPSId( getLayerIdInVps() );
[964]844  m_cPPS.setPpsMultilayerExtensionFlag    ( true ); 
845#if H_3D
846  m_cPPS.setPps3dExtensionFlag            ( true ); 
847#endif
[608]848#endif
[758]849
[773]850#if H_3D
[758]851  m_cPPS.setDLT( getDLT() );
852#endif
[56]853  m_cPPS.setConstrainedIntraPred( m_bUseConstrainedIntraPred );
854  Bool bUseDQP = (getMaxCuDQPDepth() > 0)? true : false;
[2]855
[56]856      if((getMaxDeltaQP() != 0 )|| getUseAdaptiveQP())
857      {
858        bUseDQP = true;
859      }
860
861  if(bUseDQP)
862  {
863    m_cPPS.setUseDQP(true);
864    m_cPPS.setMaxCuDQPDepth( m_iMaxCuDQPDepth );
865    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
866  }
867  else
868  {
869    m_cPPS.setUseDQP(false);
870    m_cPPS.setMaxCuDQPDepth( 0 );
871    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
872  }
[2]873
[608]874  if ( m_RCEnableRateControl )
875  {
876    m_cPPS.setUseDQP(true);
877    m_cPPS.setMaxCuDQPDepth( 0 );
878    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
[655]879  }
[2]880
[608]881  m_cPPS.setChromaCbQpOffset( m_chromaCbQpOffset );
882  m_cPPS.setChromaCrQpOffset( m_chromaCrQpOffset );
883
[56]884  m_cPPS.setNumSubstreams(m_iWaveFrontSubstreams);
[608]885  m_cPPS.setEntropyCodingSyncEnabledFlag( m_iWaveFrontSynchro > 0 );
886  m_cPPS.setTilesEnabledFlag( (m_iNumColumnsMinus1 > 0 || m_iNumRowsMinus1 > 0) );
887  m_cPPS.setUseWP( m_useWeightedPred );
888  m_cPPS.setWPBiPred( m_useWeightedBiPred );
[56]889  m_cPPS.setOutputFlagPresentFlag( false );
[608]890#if H_MV
[738]891  m_cPPS.setNumExtraSliceHeaderBits( 3 ); 
[608]892#endif
[56]893  m_cPPS.setSignHideFlag(getSignHideFlag());
[655]894  if ( getDeblockingFilterMetric() )
895  {
896    m_cPPS.setDeblockingFilterControlPresentFlag (true);
897    m_cPPS.setDeblockingFilterOverrideEnabledFlag(true);
898    m_cPPS.setPicDisableDeblockingFilterFlag(false);
899    m_cPPS.setDeblockingFilterBetaOffsetDiv2(0);
900    m_cPPS.setDeblockingFilterTcOffsetDiv2(0);
901  } 
902  else
903  {
904    m_cPPS.setDeblockingFilterControlPresentFlag (m_DeblockingFilterControlPresent );
905  }
[608]906  m_cPPS.setLog2ParallelMergeLevelMinus2   (m_log2ParallelMergeLevelMinus2 );
[56]907  m_cPPS.setCabacInitPresentFlag(CABAC_INIT_PRESENT_FLAG);
[608]908  m_cPPS.setLoopFilterAcrossSlicesEnabledFlag( m_bLFCrossSliceBoundaryFlag );
909  Int histogram[MAX_NUM_REF + 1];
910  for( Int i = 0; i <= MAX_NUM_REF; i++ )
911  {
912    histogram[i]=0;
913  }
914  for( Int i = 0; i < getGOPSize(); i++ )
915  {
916    assert(getGOPEntry(i).m_numRefPicsActive >= 0 && getGOPEntry(i).m_numRefPicsActive <= MAX_NUM_REF);
917    histogram[getGOPEntry(i).m_numRefPicsActive]++;
918  }
919  Int maxHist=-1;
920  Int bestPos=0;
921  for( Int i = 0; i <= MAX_NUM_REF; i++ )
922  {
923    if(histogram[i]>maxHist)
924    {
925      maxHist=histogram[i];
926      bestPos=i;
927    }
928  }
929  assert(bestPos <= 15);
930  m_cPPS.setNumRefIdxL0DefaultActive(bestPos);
931  m_cPPS.setNumRefIdxL1DefaultActive(bestPos);
932  m_cPPS.setTransquantBypassEnableFlag(getTransquantBypassEnableFlag());
933  m_cPPS.setUseTransformSkip( m_useTransformSkip );
934  if (m_sliceSegmentMode)
935  {
936    m_cPPS.setDependentSliceSegmentsEnabledFlag( true );
937  }
938  if( m_cPPS.getDependentSliceSegmentsEnabledFlag() )
939  {
940    Int NumCtx = m_cPPS.getEntropyCodingSyncEnabledFlag()?2:1;
941    m_cSliceEncoder.initCtxMem( NumCtx );
942    for ( UInt st = 0; st < NumCtx; st++ )
943    {
944      TEncSbac* ctx = NULL;
945      ctx = new TEncSbac;
946      ctx->init( &m_cBinCoderCABAC );
947      m_cSliceEncoder.setCtxMem( ctx, st );
948    }
949  }
[2]950}
951
[56]952//Function for initializing m_RPSList, a list of TComReferencePictureSet, based on the GOPEntry objects read from the config file.
[655]953Void TEncTop::xInitRPS(Bool isFieldCoding)
[2]954{
[56]955  TComReferencePictureSet*      rps;
956 
[655]957  m_cSPS.createRPSList(getGOPSize()+m_extraRPSs+1);
[608]958  TComRPSList* rpsList = m_cSPS.getRPSList();
959
[56]960  for( Int i = 0; i < getGOPSize()+m_extraRPSs; i++) 
961  {
[608]962    GOPEntry ge = getGOPEntry(i);
963    rps = rpsList->getReferencePictureSet(i);
[56]964    rps->setNumberOfPictures(ge.m_numRefPics);
965    rps->setNumRefIdc(ge.m_numRefIdc);
966    Int numNeg = 0;
967    Int numPos = 0;
968    for( Int j = 0; j < ge.m_numRefPics; j++)
[2]969    {
[56]970      rps->setDeltaPOC(j,ge.m_referencePics[j]);
971      rps->setUsed(j,ge.m_usedByCurrPic[j]);
972      if(ge.m_referencePics[j]>0)
973      {
974        numPos++;
975      }
976      else
977      {
978        numNeg++;
979      }
[2]980    }
[56]981    rps->setNumberOfNegativePictures(numNeg);
982    rps->setNumberOfPositivePictures(numPos);
[608]983
984    // handle inter RPS intialization from the config file.
985#if AUTO_INTER_RPS
986    rps->setInterRPSPrediction(ge.m_interRPSPrediction > 0);  // not very clean, converting anything > 0 to true.
987    rps->setDeltaRIdxMinus1(0);                               // index to the Reference RPS is always the previous one.
988    TComReferencePictureSet*     RPSRef = rpsList->getReferencePictureSet(i-1);  // get the reference RPS
989
990    if (ge.m_interRPSPrediction == 2)  // Automatic generation of the inter RPS idc based on the RIdx provided.
991    {
992      Int deltaRPS = getGOPEntry(i-1).m_POC - ge.m_POC;  // the ref POC - current POC
993      Int numRefDeltaPOC = RPSRef->getNumberOfPictures();
994
995      rps->setDeltaRPS(deltaRPS);           // set delta RPS
996      rps->setNumRefIdc(numRefDeltaPOC+1);  // set the numRefIdc to the number of pictures in the reference RPS + 1.
997      Int count=0;
998      for (Int j = 0; j <= numRefDeltaPOC; j++ ) // cycle through pics in reference RPS.
999      {
1000        Int RefDeltaPOC = (j<numRefDeltaPOC)? RPSRef->getDeltaPOC(j): 0;  // if it is the last decoded picture, set RefDeltaPOC = 0
1001        rps->setRefIdc(j, 0);
1002        for (Int k = 0; k < rps->getNumberOfPictures(); k++ )  // cycle through pics in current RPS.
1003        {
1004          if (rps->getDeltaPOC(k) == ( RefDeltaPOC + deltaRPS))  // if the current RPS has a same picture as the reference RPS.
1005          {
1006              rps->setRefIdc(j, (rps->getUsed(k)?1:2));
1007              count++;
1008              break;
1009          }
1010        }
1011      }
1012      if (count != rps->getNumberOfPictures())
1013      {
1014        printf("Warning: Unable fully predict all delta POCs using the reference RPS index given in the config file.  Setting Inter RPS to false for this RPS.\n");
1015        rps->setInterRPSPrediction(0);
1016      }
1017    }
1018    else if (ge.m_interRPSPrediction == 1)  // inter RPS idc based on the RefIdc values provided in config file.
1019    {
1020      rps->setDeltaRPS(ge.m_deltaRPS);
1021      rps->setNumRefIdc(ge.m_numRefIdc);
1022      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1023      {
1024        rps->setRefIdc(j, ge.m_refIdc[j]);
1025      }
1026#if WRITE_BACK
1027      // the folowing code overwrite the deltaPOC and Used by current values read from the config file with the ones
1028      // computed from the RefIdc.  A warning is printed if they are not identical.
1029      numNeg = 0;
1030      numPos = 0;
1031      TComReferencePictureSet      RPSTemp;  // temporary variable
1032
1033      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1034      {
1035        if (ge.m_refIdc[j])
1036        {
1037          Int deltaPOC = ge.m_deltaRPS + ((j < RPSRef->getNumberOfPictures())? RPSRef->getDeltaPOC(j) : 0);
1038          RPSTemp.setDeltaPOC((numNeg+numPos),deltaPOC);
1039          RPSTemp.setUsed((numNeg+numPos),ge.m_refIdc[j]==1?1:0);
1040          if (deltaPOC<0)
1041          {
1042            numNeg++;
1043          }
1044          else
1045          {
1046            numPos++;
1047          }
1048        }
1049      }
1050      if (numNeg != rps->getNumberOfNegativePictures())
1051      {
1052        printf("Warning: number of negative pictures in RPS is different between intra and inter RPS specified in the config file.\n");
1053        rps->setNumberOfNegativePictures(numNeg);
[655]1054        rps->setNumberOfPictures(numNeg+numPos);
[608]1055      }
1056      if (numPos != rps->getNumberOfPositivePictures())
1057      {
1058        printf("Warning: number of positive pictures in RPS is different between intra and inter RPS specified in the config file.\n");
1059        rps->setNumberOfPositivePictures(numPos);
[655]1060        rps->setNumberOfPictures(numNeg+numPos);
[608]1061      }
1062      RPSTemp.setNumberOfPictures(numNeg+numPos);
1063      RPSTemp.setNumberOfNegativePictures(numNeg);
1064      RPSTemp.sortDeltaPOC();     // sort the created delta POC before comparing
1065      // check if Delta POC and Used are the same
1066      // print warning if they are not.
1067      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1068      {
1069        if (RPSTemp.getDeltaPOC(j) != rps->getDeltaPOC(j))
1070        {
1071          printf("Warning: delta POC is different between intra RPS and inter RPS specified in the config file.\n");
1072          rps->setDeltaPOC(j,RPSTemp.getDeltaPOC(j));
1073        }
1074        if (RPSTemp.getUsed(j) != rps->getUsed(j))
1075        {
1076          printf("Warning: Used by Current in RPS is different between intra and inter RPS specified in the config file.\n");
1077          rps->setUsed(j,RPSTemp.getUsed(j));
1078        }
1079      }
1080#endif
1081    }
1082#else
[56]1083    rps->setInterRPSPrediction(ge.m_interRPSPrediction);
1084    if (ge.m_interRPSPrediction)
[2]1085    {
[608]1086      rps->setDeltaRIdxMinus1(0);
[56]1087      rps->setDeltaRPS(ge.m_deltaRPS);
1088      rps->setNumRefIdc(ge.m_numRefIdc);
1089      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1090      {
1091        rps->setRefIdc(j, ge.m_refIdc[j]);
1092      }
1093#if WRITE_BACK
1094      // the folowing code overwrite the deltaPOC and Used by current values read from the config file with the ones
1095      // computed from the RefIdc.  This is not necessary if both are identical. Currently there is no check to see if they are identical.
1096      numNeg = 0;
1097      numPos = 0;
[608]1098      TComReferencePictureSet*     RPSRef = m_RPSList.getReferencePictureSet(i-1);
1099
[56]1100      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1101      {
1102        if (ge.m_refIdc[j])
1103        {
1104          Int deltaPOC = ge.m_deltaRPS + ((j < RPSRef->getNumberOfPictures())? RPSRef->getDeltaPOC(j) : 0);
1105          rps->setDeltaPOC((numNeg+numPos),deltaPOC);
1106          rps->setUsed((numNeg+numPos),ge.m_refIdc[j]==1?1:0);
1107          if (deltaPOC<0)
1108          {
1109            numNeg++;
1110          }
1111          else
1112          {
1113            numPos++;
1114          }
1115        }
1116      }
1117      rps->setNumberOfNegativePictures(numNeg);
1118      rps->setNumberOfPositivePictures(numPos);
1119      rps->sortDeltaPOC();
1120#endif
[2]1121    }
[608]1122#endif //INTER_RPS_AUTO
[56]1123  }
[655]1124  //In case of field coding, we need to set special parameters for the first bottom field of the sequence, since it is not specified in the cfg file.
1125  //The position = GOPSize + extraRPSs which is (a priori) unused is reserved for this field in the RPS.
1126  if (isFieldCoding) 
1127  {
1128    rps = rpsList->getReferencePictureSet(getGOPSize()+m_extraRPSs);
1129    rps->setNumberOfPictures(1);
1130    rps->setNumberOfNegativePictures(1);
1131    rps->setNumberOfPositivePictures(0);
1132    rps->setNumberOfLongtermPictures(0);
1133    rps->setDeltaPOC(0,-1);
1134    rps->setPOC(0,0);
1135    rps->setUsed(0,true);
1136    rps->setInterRPSPrediction(false);
1137    rps->setDeltaRIdxMinus1(0);
1138    rps->setDeltaRPS(0);
1139    rps->setNumRefIdc(0);
[56]1140}
[655]1141}
[2]1142
[56]1143   // This is a function that
1144   // determines what Reference Picture Set to use
1145   // for a specific slice (with POC = POCCurr)
[608]1146Void TEncTop::selectReferencePictureSet(TComSlice* slice, Int POCCurr, Int GOPid )
[56]1147{
[608]1148#if H_MV
1149  if( slice->getRapPicFlag() == true && getLayerId() > 0 && POCCurr == 0 )
[56]1150  {
1151    TComReferencePictureSet* rps = slice->getLocalRPS();
1152    rps->setNumberOfNegativePictures(0);
1153    rps->setNumberOfPositivePictures(0);
1154    rps->setNumberOfLongtermPictures(0);
1155    rps->setNumberOfPictures(0);
1156    slice->setRPS(rps);
1157  }
1158  else
1159  {
[608]1160#endif
1161  slice->setRPSidx(GOPid);
[2]1162
[608]1163  for(Int extraNum=m_iGOPSize; extraNum<m_extraRPSs+m_iGOPSize; extraNum++)
1164  {   
1165    if(m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0)
1166    {
1167      Int POCIndex = POCCurr%m_uiIntraPeriod;
1168      if(POCIndex == 0)
[56]1169      {
[608]1170        POCIndex = m_uiIntraPeriod;
[56]1171      }
[608]1172      if(POCIndex == m_GOPList[extraNum].m_POC)
[56]1173      {
[608]1174        slice->setRPSidx(extraNum);
[56]1175      }
1176    }
[608]1177    else
1178    {
1179      if(POCCurr==m_GOPList[extraNum].m_POC)
1180      {
1181        slice->setRPSidx(extraNum);
1182      }
1183    }
1184  }
[655]1185  if(POCCurr == 1 && slice->getPic()->isField())
1186  {
1187    slice->setRPSidx(m_iGOPSize+m_extraRPSs);
1188  }
[2]1189
[608]1190  slice->setRPS(getSPS()->getRPSList()->getReferencePictureSet(slice->getRPSidx()));
1191  slice->getRPS()->setNumberOfPictures(slice->getRPS()->getNumberOfNegativePictures()+slice->getRPS()->getNumberOfPositivePictures());
1192#if H_MV
[56]1193  }
[608]1194#endif
1195
[2]1196}
1197
[608]1198Int TEncTop::getReferencePictureSetIdxForSOP(TComSlice* slice, Int POCCurr, Int GOPid )
[2]1199{
[608]1200  int rpsIdx = GOPid;
[2]1201
[608]1202  for(Int extraNum=m_iGOPSize; extraNum<m_extraRPSs+m_iGOPSize; extraNum++)
1203  {   
1204    if(m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0)
[2]1205    {
[608]1206      Int POCIndex = POCCurr%m_uiIntraPeriod;
1207      if(POCIndex == 0)
[2]1208      {
[608]1209        POCIndex = m_uiIntraPeriod;
[2]1210      }
[608]1211      if(POCIndex == m_GOPList[extraNum].m_POC)
[2]1212      {
[608]1213        rpsIdx = extraNum;
[2]1214      }
1215    }
[608]1216    else
[56]1217    {
[608]1218      if(POCCurr==m_GOPList[extraNum].m_POC)
[56]1219      {
[608]1220        rpsIdx = extraNum;
[56]1221      }
1222    }
[2]1223  }
[56]1224
[608]1225  return rpsIdx;
[56]1226}
1227
1228Void  TEncTop::xInitPPSforTiles()
1229{
[608]1230  m_cPPS.setUniformSpacingFlag( m_iUniformSpacingIdr );
1231  m_cPPS.setNumColumnsMinus1( m_iNumColumnsMinus1 );
1232  m_cPPS.setNumRowsMinus1( m_iNumRowsMinus1 );
1233  if( m_iUniformSpacingIdr == 0 )
1234  {
1235    m_cPPS.setColumnWidth( m_puiColumnWidth );
1236    m_cPPS.setRowHeight( m_puiRowHeight );
1237  }
1238  m_cPPS.setLoopFilterAcrossTilesEnabledFlag( m_loopFilterAcrossTilesEnabledFlag );
[56]1239
[608]1240  // # substreams is "per tile" when tiles are independent.
1241  if (m_iWaveFrontSynchro
1242    )
1243  {
1244    m_cPPS.setNumSubstreams(m_iWaveFrontSubstreams * (m_iNumColumnsMinus1+1));
1245  }
[2]1246}
1247
[56]1248Void  TEncCfg::xCheckGSParameters()
[2]1249{
[56]1250  Int   iWidthInCU = ( m_iSourceWidth%g_uiMaxCUWidth ) ? m_iSourceWidth/g_uiMaxCUWidth + 1 : m_iSourceWidth/g_uiMaxCUWidth;
1251  Int   iHeightInCU = ( m_iSourceHeight%g_uiMaxCUHeight ) ? m_iSourceHeight/g_uiMaxCUHeight + 1 : m_iSourceHeight/g_uiMaxCUHeight;
1252  UInt  uiCummulativeColumnWidth = 0;
1253  UInt  uiCummulativeRowHeight = 0;
1254
1255  //check the column relative parameters
1256  if( m_iNumColumnsMinus1 >= (1<<(LOG2_MAX_NUM_COLUMNS_MINUS1+1)) )
[2]1257  {
[56]1258    printf( "The number of columns is larger than the maximum allowed number of columns.\n" );
1259    exit( EXIT_FAILURE );
[2]1260  }
[56]1261
1262  if( m_iNumColumnsMinus1 >= iWidthInCU )
[2]1263  {
[56]1264    printf( "The current picture can not have so many columns.\n" );
1265    exit( EXIT_FAILURE );
[2]1266  }
[56]1267
1268  if( m_iNumColumnsMinus1 && m_iUniformSpacingIdr==0 )
[2]1269  {
[56]1270    for(Int i=0; i<m_iNumColumnsMinus1; i++)
[608]1271    {
[56]1272      uiCummulativeColumnWidth += m_puiColumnWidth[i];
[608]1273    }
[56]1274
1275    if( uiCummulativeColumnWidth >= iWidthInCU )
1276    {
1277      printf( "The width of the column is too large.\n" );
1278      exit( EXIT_FAILURE );
1279    }
[2]1280  }
[56]1281
1282  //check the row relative parameters
1283  if( m_iNumRowsMinus1 >= (1<<(LOG2_MAX_NUM_ROWS_MINUS1+1)) )
[2]1284  {
[56]1285    printf( "The number of rows is larger than the maximum allowed number of rows.\n" );
1286    exit( EXIT_FAILURE );
[2]1287  }
[56]1288
1289  if( m_iNumRowsMinus1 >= iHeightInCU )
[2]1290  {
[56]1291    printf( "The current picture can not have so many rows.\n" );
1292    exit( EXIT_FAILURE );
[2]1293  }
1294
[56]1295  if( m_iNumRowsMinus1 && m_iUniformSpacingIdr==0 )
1296  {
1297    for(Int i=0; i<m_iNumRowsMinus1; i++)
1298      uiCummulativeRowHeight += m_puiRowHeight[i];
1299
1300    if( uiCummulativeRowHeight >= iHeightInCU )
1301    {
1302      printf( "The height of the row is too large.\n" );
1303      exit( EXIT_FAILURE );
1304    }
1305  }
[2]1306}
[608]1307#if H_MV
[655]1308Void TEncTop::printSummary( Int numAllPicCoded, Bool isField )
[56]1309{
[655]1310  assert ( !isField ); // Multiview and field coding need to be further unified
[608]1311  assert (numAllPicCoded == m_cAnalyzeAll.getNumPic());
[2]1312
[56]1313  //--CFG_KDY
1314  m_cAnalyzeAll.setFrmRate( getFrameRate() );
1315  m_cAnalyzeI.setFrmRate( getFrameRate() );
1316  m_cAnalyzeP.setFrmRate( getFrameRate() );
1317  m_cAnalyzeB.setFrmRate( getFrameRate() );
[2]1318
[56]1319  //-- all
[608]1320  printf( "\n\nSUMMARY ------------------------------------------- LayerId %2d\n", m_layerId );
1321
[56]1322  m_cAnalyzeAll.printOut('a');
[2]1323
[56]1324  printf( "\n\nI Slices--------------------------------------------------------\n" );
1325  m_cAnalyzeI.printOut('i');
1326
1327  printf( "\n\nP Slices--------------------------------------------------------\n" );
1328  m_cAnalyzeP.printOut('p');
1329
1330  printf( "\n\nB Slices--------------------------------------------------------\n" );
1331  m_cAnalyzeB.printOut('b');
1332
[608]1333#if _SUMMARY_OUT_
1334  m_cAnalyzeAll.printSummaryOut();
1335#endif
1336#if _SUMMARY_PIC_
1337  m_cAnalyzeI.printSummary('I');
1338  m_cAnalyzeP.printSummary('P');
1339  m_cAnalyzeB.printSummary('B');
1340#endif
[2]1341}
[56]1342
[608]1343Int TEncTop::getFrameId(Int iGOPid) 
1344{
1345  if(m_iPOCLast == 0)
1346  {
1347    return(0 );
1348  }
1349  else
1350  {
1351    return m_iPOCLast -m_iNumPicRcvd+ getGOPEntry(iGOPid).m_POC ;
1352  }
1353}
1354
1355TComPic* TEncTop::getPic( Int poc )
1356{
1357  TComList<TComPic*>* listPic = getListPic();
1358  TComPic* pcPic = NULL;
1359  for(TComList<TComPic*>::iterator it=listPic->begin(); it!=listPic->end(); it++)
1360  {
1361    if( (*it)->getPOC() == poc )
1362    {
1363      pcPic = *it ;
1364      break ;
1365    }
1366  }
1367  return pcPic;
1368}
1369#endif
1370
1371#if H_3D_VSO
1372Void TEncTop::setupRenModel( Int iPoc, Int iEncViewIdx, Int iEncContent, Int iHorOffset )
1373{
1374  TRenModel* rendererModel = m_cRdCost.getRenModel(); 
1375  rendererModel->setupPart( iHorOffset, std::min( (Int) g_uiMaxCUHeight, (Int) ( m_iSourceHeight - iHorOffset ) )) ; 
1376 
1377  Int iEncViewSIdx = m_cameraParameters->getBaseId2SortedId()[ iEncViewIdx ];
1378
1379  // setup base views
1380  Int iNumOfBV = m_renderModelParameters->getNumOfBaseViewsForView( iEncViewSIdx, iEncContent );
1381
1382  for (Int iCurView = 0; iCurView < iNumOfBV; iCurView++ )
1383  {
1384    Int iBaseViewSIdx;
1385    Int iVideoDistMode;
1386    Int iDepthDistMode;
1387
1388    m_renderModelParameters->getBaseViewData( iEncViewSIdx, iEncContent, iCurView, iBaseViewSIdx, iVideoDistMode, iDepthDistMode );
1389
1390    AOT( iVideoDistMode < 0 || iVideoDistMode > 2 );
1391
1392    Int iBaseViewIdx = m_cameraParameters->getBaseSortedId2Id()[ iBaseViewSIdx ];
1393
1394    TComPicYuv* pcPicYuvVideoRec  = m_ivPicLists->getPicYuv( iBaseViewIdx, false, iPoc, true  );
1395    TComPicYuv* pcPicYuvDepthRec  = m_ivPicLists->getPicYuv( iBaseViewIdx, true , iPoc, true  );
1396    TComPicYuv* pcPicYuvVideoOrg  = m_ivPicLists->getPicYuv( iBaseViewIdx, false, iPoc, false );
1397    TComPicYuv* pcPicYuvDepthOrg  = m_ivPicLists->getPicYuv( iBaseViewIdx, true , iPoc, false );   
1398
1399    TComPicYuv* pcPicYuvVideoRef  = ( iVideoDistMode == 2 ) ? pcPicYuvVideoOrg  : NULL;
1400    TComPicYuv* pcPicYuvDepthRef  = ( iDepthDistMode == 2 ) ? pcPicYuvDepthOrg  : NULL;
1401
1402    TComPicYuv* pcPicYuvVideoTest = ( iVideoDistMode == 0 ) ? pcPicYuvVideoOrg  : pcPicYuvVideoRec;
1403    TComPicYuv* pcPicYuvDepthTest = ( iDepthDistMode == 0 ) ? pcPicYuvDepthOrg  : pcPicYuvDepthRec;
1404
1405    AOT( (iVideoDistMode == 2) != (pcPicYuvVideoRef != NULL) );
1406    AOT( (iDepthDistMode == 2) != (pcPicYuvDepthRef != NULL) );
1407    AOT( pcPicYuvDepthTest == NULL );
1408    AOT( pcPicYuvVideoTest == NULL );
1409
1410    rendererModel->setBaseView( iBaseViewSIdx, pcPicYuvVideoTest, pcPicYuvDepthTest, pcPicYuvVideoRef, pcPicYuvDepthRef );
1411  }
1412
1413  rendererModel->setErrorMode( iEncViewSIdx, iEncContent, 0 );
1414  // setup virtual views
1415  Int iNumOfSV  = m_renderModelParameters->getNumOfModelsForView( iEncViewSIdx, iEncContent );
1416  for (Int iCurView = 0; iCurView < iNumOfSV; iCurView++ )
1417  {
1418    Int iOrgRefBaseViewSIdx;
1419    Int iLeftBaseViewSIdx;
1420    Int iRightBaseViewSIdx;
1421    Int iSynthViewRelNum;
1422    Int iModelNum;
1423    Int iBlendMode;
1424    m_renderModelParameters->getSingleModelData(iEncViewSIdx, iEncContent, iCurView, iModelNum, iBlendMode,iLeftBaseViewSIdx, iRightBaseViewSIdx, iOrgRefBaseViewSIdx, iSynthViewRelNum );
1425
1426    Int iLeftBaseViewIdx    = -1;
1427    Int iRightBaseViewIdx   = -1;
1428
1429    TComPicYuv* pcPicYuvOrgRef  = NULL;
1430    Int**      ppiShiftLUTLeft  = NULL;
1431    Int**      ppiShiftLUTRight = NULL;
1432    Int**      ppiBaseShiftLUTLeft  = NULL;
1433    Int**      ppiBaseShiftLUTRight = NULL;
1434
1435
1436    Int        iDistToLeft      = -1;
1437
1438    Int iSynthViewIdx = m_cameraParameters->synthRelNum2Idx( iSynthViewRelNum );
1439
1440    if ( iLeftBaseViewSIdx != -1 )
1441    {
1442      iLeftBaseViewIdx   = m_cameraParameters->getBaseSortedId2Id()   [ iLeftBaseViewSIdx ];
1443      ppiShiftLUTLeft    = m_cameraParameters->getSynthViewShiftLUTI()[ iLeftBaseViewIdx  ][ iSynthViewIdx  ];
1444    }
1445
1446    if ( iRightBaseViewSIdx != -1 )
1447    {
1448      iRightBaseViewIdx  = m_cameraParameters->getBaseSortedId2Id()   [iRightBaseViewSIdx ];
1449      ppiShiftLUTRight   = m_cameraParameters->getSynthViewShiftLUTI()[ iRightBaseViewIdx ][ iSynthViewIdx ];
1450    }
1451
1452    if ( iRightBaseViewSIdx != -1 && iLeftBaseViewSIdx != -1 )
1453    {
1454      iDistToLeft          = m_cameraParameters->getRelDistLeft(  iSynthViewIdx , iLeftBaseViewIdx, iRightBaseViewIdx);
1455      ppiBaseShiftLUTLeft  = m_cameraParameters->getBaseViewShiftLUTI() [ iLeftBaseViewIdx  ][ iRightBaseViewIdx ];
1456      ppiBaseShiftLUTRight = m_cameraParameters->getBaseViewShiftLUTI() [ iRightBaseViewIdx ][ iLeftBaseViewIdx  ];
1457
1458    }
1459
1460    if ( iOrgRefBaseViewSIdx != -1 )
1461    {
1462      pcPicYuvOrgRef = m_ivPicLists->getPicYuv(  m_cameraParameters->getBaseSortedId2Id()[ iOrgRefBaseViewSIdx ] , false, iPoc, false );
1463      AOF ( pcPicYuvOrgRef );
1464    }
1465
1466    rendererModel->setSingleModel( iModelNum, ppiShiftLUTLeft, ppiBaseShiftLUTLeft, ppiShiftLUTRight, ppiBaseShiftLUTRight, iDistToLeft, pcPicYuvOrgRef );
1467  }
1468}
1469#endif
[56]1470//! \}
Note: See TracBrowser for help on using the repository browser.