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

Last change on this file since 911 was 884, checked in by tech, 11 years ago

Merged HTM-10.1-dev0@883. (MV-HEVC 7 HLS)

  • Property svn:eol-style set to native
File size: 47.3 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              ); 
[738]699  m_cSPS.setSpsExtensionFlag              ( true ); 
700  m_cSPS.setSpsExtensionTypeFlag          ( PS_EX_T_MV ,true ); 
701#if H_3D
702  m_cSPS.setSpsExtensionTypeFlag          ( PS_EX_T_3D ,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  }
771  m_cSPS.setPCMBitDepthLuma (g_uiPCMBitDepthLuma);
772  m_cSPS.setPCMBitDepthChroma (g_uiPCMBitDepthChroma);
773  m_cSPS.setPCMFilterDisableFlag  ( m_bPCMFilterDisableFlag );
[42]774
[56]775  m_cSPS.setScalingListFlag ( (m_useScalingListId == 0) ? 0 : 1 );
776
[608]777  m_cSPS.setUseStrongIntraSmoothing( m_useStrongIntraSmoothing );
[210]778
[608]779  m_cSPS.setVuiParametersPresentFlag(getVuiParametersPresentFlag());
780  if (m_cSPS.getVuiParametersPresentFlag())
[56]781  {
[608]782    TComVUI* pcVUI = m_cSPS.getVuiParameters();
783    pcVUI->setAspectRatioInfoPresentFlag(getAspectRatioIdc() != -1);
784    pcVUI->setAspectRatioIdc(getAspectRatioIdc());
785    pcVUI->setSarWidth(getSarWidth());
786    pcVUI->setSarHeight(getSarHeight());
787    pcVUI->setOverscanInfoPresentFlag(getOverscanInfoPresentFlag());
788    pcVUI->setOverscanAppropriateFlag(getOverscanAppropriateFlag());
[773]789#if H_MV
[738]790    pcVUI->setVideoSignalTypePresentFlag(getVideoSignalTypePresentFlag() && getLayerId() == 0 );
791#else
[773]792   pcVUI->setVideoSignalTypePresentFlag(getVideoSignalTypePresentFlag());
[738]793#endif
[608]794    pcVUI->setVideoFormat(getVideoFormat());
795    pcVUI->setVideoFullRangeFlag(getVideoFullRangeFlag());
796    pcVUI->setColourDescriptionPresentFlag(getColourDescriptionPresentFlag());
797    pcVUI->setColourPrimaries(getColourPrimaries());
798    pcVUI->setTransferCharacteristics(getTransferCharacteristics());
799    pcVUI->setMatrixCoefficients(getMatrixCoefficients());
800    pcVUI->setChromaLocInfoPresentFlag(getChromaLocInfoPresentFlag());
801    pcVUI->setChromaSampleLocTypeTopField(getChromaSampleLocTypeTopField());
802    pcVUI->setChromaSampleLocTypeBottomField(getChromaSampleLocTypeBottomField());
803    pcVUI->setNeutralChromaIndicationFlag(getNeutralChromaIndicationFlag());
804    pcVUI->setDefaultDisplayWindow(getDefaultDisplayWindow());
805    pcVUI->setFrameFieldInfoPresentFlag(getFrameFieldInfoPresentFlag());
806    pcVUI->setFieldSeqFlag(false);
807    pcVUI->setHrdParametersPresentFlag(false);
808    pcVUI->getTimingInfo()->setPocProportionalToTimingFlag(getPocProportionalToTimingFlag());
809    pcVUI->getTimingInfo()->setNumTicksPocDiffOneMinus1   (getNumTicksPocDiffOneMinus1()   );
810    pcVUI->setBitstreamRestrictionFlag(getBitstreamRestrictionFlag());
811    pcVUI->setTilesFixedStructureFlag(getTilesFixedStructureFlag());
812    pcVUI->setMotionVectorsOverPicBoundariesFlag(getMotionVectorsOverPicBoundariesFlag());
813    pcVUI->setMinSpatialSegmentationIdc(getMinSpatialSegmentationIdc());
814    pcVUI->setMaxBytesPerPicDenom(getMaxBytesPerPicDenom());
815    pcVUI->setMaxBitsPerMinCuDenom(getMaxBitsPerMinCuDenom());
816    pcVUI->setLog2MaxMvLengthHorizontal(getLog2MaxMvLengthHorizontal());
817    pcVUI->setLog2MaxMvLengthVertical(getLog2MaxMvLengthVertical());
[2]818  }
[56]819}
[2]820
[56]821Void TEncTop::xInitPPS()
822{
[608]823#if H_MV
[622]824  m_cPPS.setLayerId( getLayerId() );
825  if( getVPS()->getNumDirectRefLayers( getLayerId() ) > 0 )
[608]826  {
827    m_cPPS.setListsModificationPresentFlag( true );
828  }
829  m_cPPS.setPPSId( getLayerIdInVps() );
830  m_cPPS.setSPSId( getLayerIdInVps() );
[872]831
832  m_cPPS.setPpsExtensionTypeFlag          ( PPS_EX_T_MV ,true ); 
833#if H_3D
834  m_cPPS.setPpsExtensionTypeFlag          ( PPS_EX_T_3D ,true ); 
[608]835#endif
[872]836#endif
[758]837
[773]838#if H_3D
[758]839  m_cPPS.setDLT( getDLT() );
840#endif
[56]841  m_cPPS.setConstrainedIntraPred( m_bUseConstrainedIntraPred );
842  Bool bUseDQP = (getMaxCuDQPDepth() > 0)? true : false;
[2]843
[56]844      if((getMaxDeltaQP() != 0 )|| getUseAdaptiveQP())
845      {
846        bUseDQP = true;
847      }
848
849  if(bUseDQP)
850  {
851    m_cPPS.setUseDQP(true);
852    m_cPPS.setMaxCuDQPDepth( m_iMaxCuDQPDepth );
853    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
854  }
855  else
856  {
857    m_cPPS.setUseDQP(false);
858    m_cPPS.setMaxCuDQPDepth( 0 );
859    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
860  }
[2]861
[608]862  if ( m_RCEnableRateControl )
863  {
864    m_cPPS.setUseDQP(true);
865    m_cPPS.setMaxCuDQPDepth( 0 );
866    m_cPPS.setMinCuDQPSize( m_cPPS.getSPS()->getMaxCUWidth() >> ( m_cPPS.getMaxCuDQPDepth()) );
[655]867  }
[2]868
[608]869  m_cPPS.setChromaCbQpOffset( m_chromaCbQpOffset );
870  m_cPPS.setChromaCrQpOffset( m_chromaCrQpOffset );
871
[56]872  m_cPPS.setNumSubstreams(m_iWaveFrontSubstreams);
[608]873  m_cPPS.setEntropyCodingSyncEnabledFlag( m_iWaveFrontSynchro > 0 );
874  m_cPPS.setTilesEnabledFlag( (m_iNumColumnsMinus1 > 0 || m_iNumRowsMinus1 > 0) );
875  m_cPPS.setUseWP( m_useWeightedPred );
876  m_cPPS.setWPBiPred( m_useWeightedBiPred );
[56]877  m_cPPS.setOutputFlagPresentFlag( false );
[608]878#if H_MV
[738]879  m_cPPS.setNumExtraSliceHeaderBits( 3 ); 
[608]880#endif
[56]881  m_cPPS.setSignHideFlag(getSignHideFlag());
[655]882  if ( getDeblockingFilterMetric() )
883  {
884    m_cPPS.setDeblockingFilterControlPresentFlag (true);
885    m_cPPS.setDeblockingFilterOverrideEnabledFlag(true);
886    m_cPPS.setPicDisableDeblockingFilterFlag(false);
887    m_cPPS.setDeblockingFilterBetaOffsetDiv2(0);
888    m_cPPS.setDeblockingFilterTcOffsetDiv2(0);
889  } 
890  else
891  {
892    m_cPPS.setDeblockingFilterControlPresentFlag (m_DeblockingFilterControlPresent );
893  }
[608]894  m_cPPS.setLog2ParallelMergeLevelMinus2   (m_log2ParallelMergeLevelMinus2 );
[56]895  m_cPPS.setCabacInitPresentFlag(CABAC_INIT_PRESENT_FLAG);
[608]896  m_cPPS.setLoopFilterAcrossSlicesEnabledFlag( m_bLFCrossSliceBoundaryFlag );
897  Int histogram[MAX_NUM_REF + 1];
898  for( Int i = 0; i <= MAX_NUM_REF; i++ )
899  {
900    histogram[i]=0;
901  }
902  for( Int i = 0; i < getGOPSize(); i++ )
903  {
904    assert(getGOPEntry(i).m_numRefPicsActive >= 0 && getGOPEntry(i).m_numRefPicsActive <= MAX_NUM_REF);
905    histogram[getGOPEntry(i).m_numRefPicsActive]++;
906  }
907  Int maxHist=-1;
908  Int bestPos=0;
909  for( Int i = 0; i <= MAX_NUM_REF; i++ )
910  {
911    if(histogram[i]>maxHist)
912    {
913      maxHist=histogram[i];
914      bestPos=i;
915    }
916  }
917  assert(bestPos <= 15);
918  m_cPPS.setNumRefIdxL0DefaultActive(bestPos);
919  m_cPPS.setNumRefIdxL1DefaultActive(bestPos);
920  m_cPPS.setTransquantBypassEnableFlag(getTransquantBypassEnableFlag());
921  m_cPPS.setUseTransformSkip( m_useTransformSkip );
922  if (m_sliceSegmentMode)
923  {
924    m_cPPS.setDependentSliceSegmentsEnabledFlag( true );
925  }
926  if( m_cPPS.getDependentSliceSegmentsEnabledFlag() )
927  {
928    Int NumCtx = m_cPPS.getEntropyCodingSyncEnabledFlag()?2:1;
929    m_cSliceEncoder.initCtxMem( NumCtx );
930    for ( UInt st = 0; st < NumCtx; st++ )
931    {
932      TEncSbac* ctx = NULL;
933      ctx = new TEncSbac;
934      ctx->init( &m_cBinCoderCABAC );
935      m_cSliceEncoder.setCtxMem( ctx, st );
936    }
937  }
[2]938}
939
[56]940//Function for initializing m_RPSList, a list of TComReferencePictureSet, based on the GOPEntry objects read from the config file.
[655]941Void TEncTop::xInitRPS(Bool isFieldCoding)
[2]942{
[56]943  TComReferencePictureSet*      rps;
944 
[655]945  m_cSPS.createRPSList(getGOPSize()+m_extraRPSs+1);
[608]946  TComRPSList* rpsList = m_cSPS.getRPSList();
947
[56]948  for( Int i = 0; i < getGOPSize()+m_extraRPSs; i++) 
949  {
[608]950    GOPEntry ge = getGOPEntry(i);
951    rps = rpsList->getReferencePictureSet(i);
[56]952    rps->setNumberOfPictures(ge.m_numRefPics);
953    rps->setNumRefIdc(ge.m_numRefIdc);
954    Int numNeg = 0;
955    Int numPos = 0;
956    for( Int j = 0; j < ge.m_numRefPics; j++)
[2]957    {
[56]958      rps->setDeltaPOC(j,ge.m_referencePics[j]);
959      rps->setUsed(j,ge.m_usedByCurrPic[j]);
960      if(ge.m_referencePics[j]>0)
961      {
962        numPos++;
963      }
964      else
965      {
966        numNeg++;
967      }
[2]968    }
[56]969    rps->setNumberOfNegativePictures(numNeg);
970    rps->setNumberOfPositivePictures(numPos);
[608]971
972    // handle inter RPS intialization from the config file.
973#if AUTO_INTER_RPS
974    rps->setInterRPSPrediction(ge.m_interRPSPrediction > 0);  // not very clean, converting anything > 0 to true.
975    rps->setDeltaRIdxMinus1(0);                               // index to the Reference RPS is always the previous one.
976    TComReferencePictureSet*     RPSRef = rpsList->getReferencePictureSet(i-1);  // get the reference RPS
977
978    if (ge.m_interRPSPrediction == 2)  // Automatic generation of the inter RPS idc based on the RIdx provided.
979    {
980      Int deltaRPS = getGOPEntry(i-1).m_POC - ge.m_POC;  // the ref POC - current POC
981      Int numRefDeltaPOC = RPSRef->getNumberOfPictures();
982
983      rps->setDeltaRPS(deltaRPS);           // set delta RPS
984      rps->setNumRefIdc(numRefDeltaPOC+1);  // set the numRefIdc to the number of pictures in the reference RPS + 1.
985      Int count=0;
986      for (Int j = 0; j <= numRefDeltaPOC; j++ ) // cycle through pics in reference RPS.
987      {
988        Int RefDeltaPOC = (j<numRefDeltaPOC)? RPSRef->getDeltaPOC(j): 0;  // if it is the last decoded picture, set RefDeltaPOC = 0
989        rps->setRefIdc(j, 0);
990        for (Int k = 0; k < rps->getNumberOfPictures(); k++ )  // cycle through pics in current RPS.
991        {
992          if (rps->getDeltaPOC(k) == ( RefDeltaPOC + deltaRPS))  // if the current RPS has a same picture as the reference RPS.
993          {
994              rps->setRefIdc(j, (rps->getUsed(k)?1:2));
995              count++;
996              break;
997          }
998        }
999      }
1000      if (count != rps->getNumberOfPictures())
1001      {
1002        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");
1003        rps->setInterRPSPrediction(0);
1004      }
1005    }
1006    else if (ge.m_interRPSPrediction == 1)  // inter RPS idc based on the RefIdc values provided in config file.
1007    {
1008      rps->setDeltaRPS(ge.m_deltaRPS);
1009      rps->setNumRefIdc(ge.m_numRefIdc);
1010      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1011      {
1012        rps->setRefIdc(j, ge.m_refIdc[j]);
1013      }
1014#if WRITE_BACK
1015      // the folowing code overwrite the deltaPOC and Used by current values read from the config file with the ones
1016      // computed from the RefIdc.  A warning is printed if they are not identical.
1017      numNeg = 0;
1018      numPos = 0;
1019      TComReferencePictureSet      RPSTemp;  // temporary variable
1020
1021      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1022      {
1023        if (ge.m_refIdc[j])
1024        {
1025          Int deltaPOC = ge.m_deltaRPS + ((j < RPSRef->getNumberOfPictures())? RPSRef->getDeltaPOC(j) : 0);
1026          RPSTemp.setDeltaPOC((numNeg+numPos),deltaPOC);
1027          RPSTemp.setUsed((numNeg+numPos),ge.m_refIdc[j]==1?1:0);
1028          if (deltaPOC<0)
1029          {
1030            numNeg++;
1031          }
1032          else
1033          {
1034            numPos++;
1035          }
1036        }
1037      }
1038      if (numNeg != rps->getNumberOfNegativePictures())
1039      {
1040        printf("Warning: number of negative pictures in RPS is different between intra and inter RPS specified in the config file.\n");
1041        rps->setNumberOfNegativePictures(numNeg);
[655]1042        rps->setNumberOfPictures(numNeg+numPos);
[608]1043      }
1044      if (numPos != rps->getNumberOfPositivePictures())
1045      {
1046        printf("Warning: number of positive pictures in RPS is different between intra and inter RPS specified in the config file.\n");
1047        rps->setNumberOfPositivePictures(numPos);
[655]1048        rps->setNumberOfPictures(numNeg+numPos);
[608]1049      }
1050      RPSTemp.setNumberOfPictures(numNeg+numPos);
1051      RPSTemp.setNumberOfNegativePictures(numNeg);
1052      RPSTemp.sortDeltaPOC();     // sort the created delta POC before comparing
1053      // check if Delta POC and Used are the same
1054      // print warning if they are not.
1055      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1056      {
1057        if (RPSTemp.getDeltaPOC(j) != rps->getDeltaPOC(j))
1058        {
1059          printf("Warning: delta POC is different between intra RPS and inter RPS specified in the config file.\n");
1060          rps->setDeltaPOC(j,RPSTemp.getDeltaPOC(j));
1061        }
1062        if (RPSTemp.getUsed(j) != rps->getUsed(j))
1063        {
1064          printf("Warning: Used by Current in RPS is different between intra and inter RPS specified in the config file.\n");
1065          rps->setUsed(j,RPSTemp.getUsed(j));
1066        }
1067      }
1068#endif
1069    }
1070#else
[56]1071    rps->setInterRPSPrediction(ge.m_interRPSPrediction);
1072    if (ge.m_interRPSPrediction)
[2]1073    {
[608]1074      rps->setDeltaRIdxMinus1(0);
[56]1075      rps->setDeltaRPS(ge.m_deltaRPS);
1076      rps->setNumRefIdc(ge.m_numRefIdc);
1077      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1078      {
1079        rps->setRefIdc(j, ge.m_refIdc[j]);
1080      }
1081#if WRITE_BACK
1082      // the folowing code overwrite the deltaPOC and Used by current values read from the config file with the ones
1083      // computed from the RefIdc.  This is not necessary if both are identical. Currently there is no check to see if they are identical.
1084      numNeg = 0;
1085      numPos = 0;
[608]1086      TComReferencePictureSet*     RPSRef = m_RPSList.getReferencePictureSet(i-1);
1087
[56]1088      for (Int j = 0; j < ge.m_numRefIdc; j++ )
1089      {
1090        if (ge.m_refIdc[j])
1091        {
1092          Int deltaPOC = ge.m_deltaRPS + ((j < RPSRef->getNumberOfPictures())? RPSRef->getDeltaPOC(j) : 0);
1093          rps->setDeltaPOC((numNeg+numPos),deltaPOC);
1094          rps->setUsed((numNeg+numPos),ge.m_refIdc[j]==1?1:0);
1095          if (deltaPOC<0)
1096          {
1097            numNeg++;
1098          }
1099          else
1100          {
1101            numPos++;
1102          }
1103        }
1104      }
1105      rps->setNumberOfNegativePictures(numNeg);
1106      rps->setNumberOfPositivePictures(numPos);
1107      rps->sortDeltaPOC();
1108#endif
[2]1109    }
[608]1110#endif //INTER_RPS_AUTO
[56]1111  }
[655]1112  //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.
1113  //The position = GOPSize + extraRPSs which is (a priori) unused is reserved for this field in the RPS.
1114  if (isFieldCoding) 
1115  {
1116    rps = rpsList->getReferencePictureSet(getGOPSize()+m_extraRPSs);
1117    rps->setNumberOfPictures(1);
1118    rps->setNumberOfNegativePictures(1);
1119    rps->setNumberOfPositivePictures(0);
1120    rps->setNumberOfLongtermPictures(0);
1121    rps->setDeltaPOC(0,-1);
1122    rps->setPOC(0,0);
1123    rps->setUsed(0,true);
1124    rps->setInterRPSPrediction(false);
1125    rps->setDeltaRIdxMinus1(0);
1126    rps->setDeltaRPS(0);
1127    rps->setNumRefIdc(0);
[56]1128}
[655]1129}
[2]1130
[56]1131   // This is a function that
1132   // determines what Reference Picture Set to use
1133   // for a specific slice (with POC = POCCurr)
[608]1134Void TEncTop::selectReferencePictureSet(TComSlice* slice, Int POCCurr, Int GOPid )
[56]1135{
[608]1136#if H_MV
1137  if( slice->getRapPicFlag() == true && getLayerId() > 0 && POCCurr == 0 )
[56]1138  {
1139    TComReferencePictureSet* rps = slice->getLocalRPS();
1140    rps->setNumberOfNegativePictures(0);
1141    rps->setNumberOfPositivePictures(0);
1142    rps->setNumberOfLongtermPictures(0);
1143    rps->setNumberOfPictures(0);
1144    slice->setRPS(rps);
1145  }
1146  else
1147  {
[608]1148#endif
1149  slice->setRPSidx(GOPid);
[2]1150
[608]1151  for(Int extraNum=m_iGOPSize; extraNum<m_extraRPSs+m_iGOPSize; extraNum++)
1152  {   
1153    if(m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0)
1154    {
1155      Int POCIndex = POCCurr%m_uiIntraPeriod;
1156      if(POCIndex == 0)
[56]1157      {
[608]1158        POCIndex = m_uiIntraPeriod;
[56]1159      }
[608]1160      if(POCIndex == m_GOPList[extraNum].m_POC)
[56]1161      {
[608]1162        slice->setRPSidx(extraNum);
[56]1163      }
1164    }
[608]1165    else
1166    {
1167      if(POCCurr==m_GOPList[extraNum].m_POC)
1168      {
1169        slice->setRPSidx(extraNum);
1170      }
1171    }
1172  }
[655]1173  if(POCCurr == 1 && slice->getPic()->isField())
1174  {
1175    slice->setRPSidx(m_iGOPSize+m_extraRPSs);
1176  }
[2]1177
[608]1178  slice->setRPS(getSPS()->getRPSList()->getReferencePictureSet(slice->getRPSidx()));
1179  slice->getRPS()->setNumberOfPictures(slice->getRPS()->getNumberOfNegativePictures()+slice->getRPS()->getNumberOfPositivePictures());
1180#if H_MV
[56]1181  }
[608]1182#endif
1183
[2]1184}
1185
[608]1186Int TEncTop::getReferencePictureSetIdxForSOP(TComSlice* slice, Int POCCurr, Int GOPid )
[2]1187{
[608]1188  int rpsIdx = GOPid;
[2]1189
[608]1190  for(Int extraNum=m_iGOPSize; extraNum<m_extraRPSs+m_iGOPSize; extraNum++)
1191  {   
1192    if(m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0)
[2]1193    {
[608]1194      Int POCIndex = POCCurr%m_uiIntraPeriod;
1195      if(POCIndex == 0)
[2]1196      {
[608]1197        POCIndex = m_uiIntraPeriod;
[2]1198      }
[608]1199      if(POCIndex == m_GOPList[extraNum].m_POC)
[2]1200      {
[608]1201        rpsIdx = extraNum;
[2]1202      }
1203    }
[608]1204    else
[56]1205    {
[608]1206      if(POCCurr==m_GOPList[extraNum].m_POC)
[56]1207      {
[608]1208        rpsIdx = extraNum;
[56]1209      }
1210    }
[2]1211  }
[56]1212
[608]1213  return rpsIdx;
[56]1214}
1215
1216Void  TEncTop::xInitPPSforTiles()
1217{
[608]1218  m_cPPS.setUniformSpacingFlag( m_iUniformSpacingIdr );
1219  m_cPPS.setNumColumnsMinus1( m_iNumColumnsMinus1 );
1220  m_cPPS.setNumRowsMinus1( m_iNumRowsMinus1 );
1221  if( m_iUniformSpacingIdr == 0 )
1222  {
1223    m_cPPS.setColumnWidth( m_puiColumnWidth );
1224    m_cPPS.setRowHeight( m_puiRowHeight );
1225  }
1226  m_cPPS.setLoopFilterAcrossTilesEnabledFlag( m_loopFilterAcrossTilesEnabledFlag );
[56]1227
[608]1228  // # substreams is "per tile" when tiles are independent.
1229  if (m_iWaveFrontSynchro
1230    )
1231  {
1232    m_cPPS.setNumSubstreams(m_iWaveFrontSubstreams * (m_iNumColumnsMinus1+1));
1233  }
[2]1234}
1235
[56]1236Void  TEncCfg::xCheckGSParameters()
[2]1237{
[56]1238  Int   iWidthInCU = ( m_iSourceWidth%g_uiMaxCUWidth ) ? m_iSourceWidth/g_uiMaxCUWidth + 1 : m_iSourceWidth/g_uiMaxCUWidth;
1239  Int   iHeightInCU = ( m_iSourceHeight%g_uiMaxCUHeight ) ? m_iSourceHeight/g_uiMaxCUHeight + 1 : m_iSourceHeight/g_uiMaxCUHeight;
1240  UInt  uiCummulativeColumnWidth = 0;
1241  UInt  uiCummulativeRowHeight = 0;
1242
1243  //check the column relative parameters
1244  if( m_iNumColumnsMinus1 >= (1<<(LOG2_MAX_NUM_COLUMNS_MINUS1+1)) )
[2]1245  {
[56]1246    printf( "The number of columns is larger than the maximum allowed number of columns.\n" );
1247    exit( EXIT_FAILURE );
[2]1248  }
[56]1249
1250  if( m_iNumColumnsMinus1 >= iWidthInCU )
[2]1251  {
[56]1252    printf( "The current picture can not have so many columns.\n" );
1253    exit( EXIT_FAILURE );
[2]1254  }
[56]1255
1256  if( m_iNumColumnsMinus1 && m_iUniformSpacingIdr==0 )
[2]1257  {
[56]1258    for(Int i=0; i<m_iNumColumnsMinus1; i++)
[608]1259    {
[56]1260      uiCummulativeColumnWidth += m_puiColumnWidth[i];
[608]1261    }
[56]1262
1263    if( uiCummulativeColumnWidth >= iWidthInCU )
1264    {
1265      printf( "The width of the column is too large.\n" );
1266      exit( EXIT_FAILURE );
1267    }
[2]1268  }
[56]1269
1270  //check the row relative parameters
1271  if( m_iNumRowsMinus1 >= (1<<(LOG2_MAX_NUM_ROWS_MINUS1+1)) )
[2]1272  {
[56]1273    printf( "The number of rows is larger than the maximum allowed number of rows.\n" );
1274    exit( EXIT_FAILURE );
[2]1275  }
[56]1276
1277  if( m_iNumRowsMinus1 >= iHeightInCU )
[2]1278  {
[56]1279    printf( "The current picture can not have so many rows.\n" );
1280    exit( EXIT_FAILURE );
[2]1281  }
1282
[56]1283  if( m_iNumRowsMinus1 && m_iUniformSpacingIdr==0 )
1284  {
1285    for(Int i=0; i<m_iNumRowsMinus1; i++)
1286      uiCummulativeRowHeight += m_puiRowHeight[i];
1287
1288    if( uiCummulativeRowHeight >= iHeightInCU )
1289    {
1290      printf( "The height of the row is too large.\n" );
1291      exit( EXIT_FAILURE );
1292    }
1293  }
[2]1294}
[608]1295#if H_MV
[655]1296Void TEncTop::printSummary( Int numAllPicCoded, Bool isField )
[56]1297{
[655]1298  assert ( !isField ); // Multiview and field coding need to be further unified
[608]1299  assert (numAllPicCoded == m_cAnalyzeAll.getNumPic());
[2]1300
[56]1301  //--CFG_KDY
1302  m_cAnalyzeAll.setFrmRate( getFrameRate() );
1303  m_cAnalyzeI.setFrmRate( getFrameRate() );
1304  m_cAnalyzeP.setFrmRate( getFrameRate() );
1305  m_cAnalyzeB.setFrmRate( getFrameRate() );
[2]1306
[56]1307  //-- all
[608]1308  printf( "\n\nSUMMARY ------------------------------------------- LayerId %2d\n", m_layerId );
1309
[56]1310  m_cAnalyzeAll.printOut('a');
[2]1311
[56]1312  printf( "\n\nI Slices--------------------------------------------------------\n" );
1313  m_cAnalyzeI.printOut('i');
1314
1315  printf( "\n\nP Slices--------------------------------------------------------\n" );
1316  m_cAnalyzeP.printOut('p');
1317
1318  printf( "\n\nB Slices--------------------------------------------------------\n" );
1319  m_cAnalyzeB.printOut('b');
1320
[608]1321#if _SUMMARY_OUT_
1322  m_cAnalyzeAll.printSummaryOut();
1323#endif
1324#if _SUMMARY_PIC_
1325  m_cAnalyzeI.printSummary('I');
1326  m_cAnalyzeP.printSummary('P');
1327  m_cAnalyzeB.printSummary('B');
1328#endif
[2]1329}
[56]1330
[608]1331Int TEncTop::getFrameId(Int iGOPid) 
1332{
1333  if(m_iPOCLast == 0)
1334  {
1335    return(0 );
1336  }
1337  else
1338  {
1339    return m_iPOCLast -m_iNumPicRcvd+ getGOPEntry(iGOPid).m_POC ;
1340  }
1341}
1342
1343TComPic* TEncTop::getPic( Int poc )
1344{
1345  TComList<TComPic*>* listPic = getListPic();
1346  TComPic* pcPic = NULL;
1347  for(TComList<TComPic*>::iterator it=listPic->begin(); it!=listPic->end(); it++)
1348  {
1349    if( (*it)->getPOC() == poc )
1350    {
1351      pcPic = *it ;
1352      break ;
1353    }
1354  }
1355  return pcPic;
1356}
1357#endif
1358
1359#if H_3D_VSO
1360Void TEncTop::setupRenModel( Int iPoc, Int iEncViewIdx, Int iEncContent, Int iHorOffset )
1361{
1362  TRenModel* rendererModel = m_cRdCost.getRenModel(); 
1363  rendererModel->setupPart( iHorOffset, std::min( (Int) g_uiMaxCUHeight, (Int) ( m_iSourceHeight - iHorOffset ) )) ; 
1364 
1365  Int iEncViewSIdx = m_cameraParameters->getBaseId2SortedId()[ iEncViewIdx ];
1366
1367  // setup base views
1368  Int iNumOfBV = m_renderModelParameters->getNumOfBaseViewsForView( iEncViewSIdx, iEncContent );
1369
1370  for (Int iCurView = 0; iCurView < iNumOfBV; iCurView++ )
1371  {
1372    Int iBaseViewSIdx;
1373    Int iVideoDistMode;
1374    Int iDepthDistMode;
1375
1376    m_renderModelParameters->getBaseViewData( iEncViewSIdx, iEncContent, iCurView, iBaseViewSIdx, iVideoDistMode, iDepthDistMode );
1377
1378    AOT( iVideoDistMode < 0 || iVideoDistMode > 2 );
1379
1380    Int iBaseViewIdx = m_cameraParameters->getBaseSortedId2Id()[ iBaseViewSIdx ];
1381
1382    TComPicYuv* pcPicYuvVideoRec  = m_ivPicLists->getPicYuv( iBaseViewIdx, false, iPoc, true  );
1383    TComPicYuv* pcPicYuvDepthRec  = m_ivPicLists->getPicYuv( iBaseViewIdx, true , iPoc, true  );
1384    TComPicYuv* pcPicYuvVideoOrg  = m_ivPicLists->getPicYuv( iBaseViewIdx, false, iPoc, false );
1385    TComPicYuv* pcPicYuvDepthOrg  = m_ivPicLists->getPicYuv( iBaseViewIdx, true , iPoc, false );   
1386
1387    TComPicYuv* pcPicYuvVideoRef  = ( iVideoDistMode == 2 ) ? pcPicYuvVideoOrg  : NULL;
1388    TComPicYuv* pcPicYuvDepthRef  = ( iDepthDistMode == 2 ) ? pcPicYuvDepthOrg  : NULL;
1389
1390    TComPicYuv* pcPicYuvVideoTest = ( iVideoDistMode == 0 ) ? pcPicYuvVideoOrg  : pcPicYuvVideoRec;
1391    TComPicYuv* pcPicYuvDepthTest = ( iDepthDistMode == 0 ) ? pcPicYuvDepthOrg  : pcPicYuvDepthRec;
1392
1393    AOT( (iVideoDistMode == 2) != (pcPicYuvVideoRef != NULL) );
1394    AOT( (iDepthDistMode == 2) != (pcPicYuvDepthRef != NULL) );
1395    AOT( pcPicYuvDepthTest == NULL );
1396    AOT( pcPicYuvVideoTest == NULL );
1397
1398    rendererModel->setBaseView( iBaseViewSIdx, pcPicYuvVideoTest, pcPicYuvDepthTest, pcPicYuvVideoRef, pcPicYuvDepthRef );
1399  }
1400
1401  rendererModel->setErrorMode( iEncViewSIdx, iEncContent, 0 );
1402  // setup virtual views
1403  Int iNumOfSV  = m_renderModelParameters->getNumOfModelsForView( iEncViewSIdx, iEncContent );
1404  for (Int iCurView = 0; iCurView < iNumOfSV; iCurView++ )
1405  {
1406    Int iOrgRefBaseViewSIdx;
1407    Int iLeftBaseViewSIdx;
1408    Int iRightBaseViewSIdx;
1409    Int iSynthViewRelNum;
1410    Int iModelNum;
1411    Int iBlendMode;
1412    m_renderModelParameters->getSingleModelData(iEncViewSIdx, iEncContent, iCurView, iModelNum, iBlendMode,iLeftBaseViewSIdx, iRightBaseViewSIdx, iOrgRefBaseViewSIdx, iSynthViewRelNum );
1413
1414    Int iLeftBaseViewIdx    = -1;
1415    Int iRightBaseViewIdx   = -1;
1416
1417    TComPicYuv* pcPicYuvOrgRef  = NULL;
1418    Int**      ppiShiftLUTLeft  = NULL;
1419    Int**      ppiShiftLUTRight = NULL;
1420    Int**      ppiBaseShiftLUTLeft  = NULL;
1421    Int**      ppiBaseShiftLUTRight = NULL;
1422
1423
1424    Int        iDistToLeft      = -1;
1425
1426    Int iSynthViewIdx = m_cameraParameters->synthRelNum2Idx( iSynthViewRelNum );
1427
1428    if ( iLeftBaseViewSIdx != -1 )
1429    {
1430      iLeftBaseViewIdx   = m_cameraParameters->getBaseSortedId2Id()   [ iLeftBaseViewSIdx ];
1431      ppiShiftLUTLeft    = m_cameraParameters->getSynthViewShiftLUTI()[ iLeftBaseViewIdx  ][ iSynthViewIdx  ];
1432    }
1433
1434    if ( iRightBaseViewSIdx != -1 )
1435    {
1436      iRightBaseViewIdx  = m_cameraParameters->getBaseSortedId2Id()   [iRightBaseViewSIdx ];
1437      ppiShiftLUTRight   = m_cameraParameters->getSynthViewShiftLUTI()[ iRightBaseViewIdx ][ iSynthViewIdx ];
1438    }
1439
1440    if ( iRightBaseViewSIdx != -1 && iLeftBaseViewSIdx != -1 )
1441    {
1442      iDistToLeft          = m_cameraParameters->getRelDistLeft(  iSynthViewIdx , iLeftBaseViewIdx, iRightBaseViewIdx);
1443      ppiBaseShiftLUTLeft  = m_cameraParameters->getBaseViewShiftLUTI() [ iLeftBaseViewIdx  ][ iRightBaseViewIdx ];
1444      ppiBaseShiftLUTRight = m_cameraParameters->getBaseViewShiftLUTI() [ iRightBaseViewIdx ][ iLeftBaseViewIdx  ];
1445
1446    }
1447
1448    if ( iOrgRefBaseViewSIdx != -1 )
1449    {
1450      pcPicYuvOrgRef = m_ivPicLists->getPicYuv(  m_cameraParameters->getBaseSortedId2Id()[ iOrgRefBaseViewSIdx ] , false, iPoc, false );
1451      AOF ( pcPicYuvOrgRef );
1452    }
1453
1454    rendererModel->setSingleModel( iModelNum, ppiShiftLUTLeft, ppiBaseShiftLUTLeft, ppiShiftLUTRight, ppiBaseShiftLUTRight, iDistToLeft, pcPicYuvOrgRef );
1455  }
1456}
1457#endif
[56]1458//! \}
Note: See TracBrowser for help on using the repository browser.