source: SHVCSoftware/trunk/source/App/TAppEncoder/TAppEncLayerCfg.cpp @ 872

Last change on this file since 872 was 713, checked in by seregin, 11 years ago

merge with SHM-6-dev

  • Property svn:eol-style set to native
File size: 17.2 KB
RevLine 
[313]1/** \file     TAppEncLayerCfg.cpp
2\brief    Handle encoder configuration parameters
3*/
4
5#include <stdlib.h>
6#include <cassert>
7#include <cstring>
8#include <string>
9#include "TLibCommon/TComRom.h"
10#include "TAppEncCfg.h"
11#include "TAppEncLayerCfg.h"
12#include "TAppCommon/program_options_lite.h"
13
14#ifdef WIN32
15#define strdup _strdup
16#endif
17
18using namespace std;
19namespace po = df::program_options_lite;
20
21//! \ingroup TAppEncoder
22//! \{
23
24
[494]25#if AUXILIARY_PICTURES
26static inline ChromaFormat numberToChromaFormat(const Int val)
27{
28  switch (val)
29  {
30    case 400: return CHROMA_400; break;
31    case 420: return CHROMA_420; break;
32    case 422: return CHROMA_422; break;
33    case 444: return CHROMA_444; break;
34    default:  return NUM_CHROMA_FORMAT;
35  }
36}
37#endif
38
[313]39// ====================================================================================================================
40// Constructor / destructor / initialization / destroy
41// ====================================================================================================================
42#if SVC_EXTENSION
43TAppEncLayerCfg::TAppEncLayerCfg()
44  :m_cInputFile(string("")),
45  m_cReconFile(string("")),
46  m_conformanceMode( 0 ),
47  m_aidQP(NULL)
[442]48#if REPN_FORMAT_IN_VPS
49, m_repFormatIdx (-1)
50#endif
[313]51{
52  m_confLeft = m_confRight = m_confTop = m_confBottom = 0;
53  m_aiPad[1] = m_aiPad[0] = 0;
54  m_numScaledRefLayerOffsets = 0;
[540]55#if O0098_SCALED_REF_LAYER_ID
56  ::memset(m_scaledRefLayerId,           0, sizeof(m_scaledRefLayerId));
57#endif
[313]58  ::memset(m_scaledRefLayerLeftOffset,   0, sizeof(m_scaledRefLayerLeftOffset));
59  ::memset(m_scaledRefLayerTopOffset,    0, sizeof(m_scaledRefLayerTopOffset));
60  ::memset(m_scaledRefLayerRightOffset,  0, sizeof(m_scaledRefLayerRightOffset));
61  ::memset(m_scaledRefLayerBottomOffset, 0, sizeof(m_scaledRefLayerBottomOffset));
[644]62#if P0312_VERT_PHASE_ADJ
63  ::memset(m_vertPhasePositionEnableFlag, 0, sizeof(m_vertPhasePositionEnableFlag));
64#endif
[313]65}
66
67TAppEncLayerCfg::~TAppEncLayerCfg()
68{
69  if ( m_aidQP )
70  {
71    delete[] m_aidQP;
72  }
73}
74
75Void TAppEncLayerCfg::create()
76{
77}
78
79Void TAppEncLayerCfg::destroy()
80{
81}
82
83
84// ====================================================================================================================
85// Public member functions
86// ====================================================================================================================
87
88/** \param  argc        number of arguments
89\param  argv        array of arguments
90\retval             true when success
91*/
92bool TAppEncLayerCfg::parseCfg( const string& cfgFileName  )
93{
94  string cfg_InputFile;
95  string cfg_ReconFile;
96  string cfg_dQPFile;
[494]97#if AUXILIARY_PICTURES
98  Int tmpInputChromaFormat;
99  Int tmpChromaFormat;
100#endif
101
[313]102  po::Options opts;
103  opts.addOptions()
104    ("InputFile,i",           cfg_InputFile,  string(""), "original YUV input file name")
105#if AVC_BASE
106    ("InputBLFile,-ibl",      cfg_InputFile,  string(""), "original YUV input file name")
107#endif
108    ("ReconFile,o",           cfg_ReconFile,  string(""), "reconstructed YUV output file name")
109    ("SourceWidth,-wdt",      m_iSourceWidth,  0, "Source picture width")
110    ("SourceHeight,-hgt",     m_iSourceHeight, 0, "Source picture height")
111    ("CroppingMode",          m_conformanceMode,  0, "Cropping mode (0: no cropping, 1:automatic padding, 2: padding, 3:cropping")
[494]112#if AUXILIARY_PICTURES
113    ("InputChromaFormat",     tmpInputChromaFormat,  420, "InputChromaFormatIDC")
114    ("ChromaFormatIDC",       tmpChromaFormat,    420, "ChromaFormatIDC (400|420|422|444 or set 0 (default) for same as InputChromaFormat)")
115#endif
[313]116    ("CropLeft",              m_confLeft,      0, "Left cropping/padding for cropping mode 3")
117    ("CropRight",             m_confRight,     0, "Right cropping/padding for cropping mode 3")
118    ("CropTop",               m_confTop,       0, "Top cropping/padding for cropping mode 3")
119    ("CropBottom",            m_confBottom,    0, "Bottom cropping/padding for cropping mode 3")
120    ("HorizontalPadding,-pdx",m_aiPad[0],      0, "horizontal source padding for cropping mode 2")
121    ("VerticalPadding,-pdy",  m_aiPad[1],      0, "vertical source padding for cropping mode 2")
122    ("IntraPeriod,-ip",       m_iIntraPeriod,  -1, "intra period in frames, (-1: only first frame)")
123    ("FrameRate,-fr",         m_iFrameRate,    0, "Frame rate")
124    ("dQPFile,m",             cfg_dQPFile, string(""), "dQP file name")
125    ("QP,q",                  m_fQP,          30.0, "Qp value, if value is float, QP is switched once during encoding")
126    ;
127
128  po::setDefaults(opts);
129  po::parseConfigFile(opts, cfgFileName);
130
131  m_cInputFile = cfg_InputFile;
132  m_cReconFile = cfg_ReconFile;
133  m_pchdQPFile = cfg_dQPFile.empty() ? NULL : strdup(cfg_dQPFile.c_str());
[494]134#if AUXILIARY_PICTURES
135  m_InputChromaFormat = numberToChromaFormat(tmpInputChromaFormat);
136  m_chromaFormatIDC   = ((tmpChromaFormat == 0) ? (m_InputChromaFormat) : (numberToChromaFormat(tmpChromaFormat)));
137#endif
[313]138
139  // reading external dQP description from file
140  if ( m_pchdQPFile )
141  {
142    FILE* fpt=fopen( m_pchdQPFile, "r" );
143    if ( fpt )
144    {
145      Int iValue;
146      Int iPOC = 0;
147      while ( iPOC < m_cAppEncCfg->getNumFrameToBeEncoded() )
148      {
149        if ( fscanf(fpt, "%d", &iValue ) == EOF ) break;
150        m_aidQP[ iPOC ] = iValue;
151        iPOC++;
152      }
153      fclose(fpt);
154    }
155  }
156  return true;
157}
158
159#if AVC_SYNTAX
160Void TAppEncLayerCfg::xPrintParameter( UInt layerId )
161#else
162Void TAppEncLayerCfg::xPrintParameter()
163#endif
164{
165  printf("Input File                    : %s\n", m_cInputFile.c_str()  );
166  printf("Reconstruction File           : %s\n", m_cReconFile.c_str()  );
167#if AVC_SYNTAX
168  if( layerId == 0 )
169  {
170    printf("Base layer syntax file        : %s\n", m_cAppEncCfg->getBLSyntaxFile() );
171  }
172#endif
[713]173#if REPN_FORMAT_IN_VPS
174  printf("Real     Format               : %dx%d %dHz\n", m_iSourceWidth - ( m_confLeft + m_confRight ) * TComSPS::getWinUnitX( m_chromaFormatIDC ), m_iSourceHeight - ( m_confTop + m_confBottom ) * TComSPS::getWinUnitY( m_chromaFormatIDC ), m_iFrameRate );
175#else
[313]176  printf("Real     Format               : %dx%d %dHz\n", m_iSourceWidth - m_confLeft - m_confRight, m_iSourceHeight - m_confTop - m_confBottom, m_iFrameRate );
[713]177#endif
[313]178  printf("Internal Format               : %dx%d %dHz\n", m_iSourceWidth, m_iSourceHeight, m_iFrameRate );
[494]179#if O0194_DIFFERENT_BITDEPTH_EL_BL
180  printf("Input bit depth               : (Y:%d, C:%d)\n", m_inputBitDepthY   , m_inputBitDepthC    );
181  printf("Internal bit depth            : (Y:%d, C:%d)\n", m_internalBitDepthY, m_internalBitDepthC );
182  printf("PCM sample bit depth          : (Y:%d, C:%d)\n", m_cAppEncCfg->getPCMInputBitDepthFlag() ? m_inputBitDepthY : m_internalBitDepthY, m_cAppEncCfg->getPCMInputBitDepthFlag() ? m_inputBitDepthC : m_internalBitDepthC );
183#endif
184#if LAYER_CTB
185  printf("CU size / depth               : %d / %d\n", m_uiMaxCUWidth, m_uiMaxCUDepth );
186  printf("RQT trans. size (min / max)   : %d / %d\n", 1 << m_uiQuadtreeTULog2MinSize, 1 << m_uiQuadtreeTULog2MaxSize );
187  printf("Max RQT depth inter           : %d\n", m_uiQuadtreeTUMaxDepthInter);
188  printf("Max RQT depth intra           : %d\n", m_uiQuadtreeTUMaxDepthIntra);
189#endif
[313]190  printf("QP                            : %5.2f\n", m_fQP );
191  printf("Intra period                  : %d\n", m_iIntraPeriod );
192#if RC_SHVC_HARMONIZATION
193  printf("RateControl                   : %d\n", m_RCEnableRateControl );
194  if(m_RCEnableRateControl)
195  {
196    printf("TargetBitrate                 : %d\n", m_RCTargetBitrate );
197    printf("KeepHierarchicalBit           : %d\n", m_RCKeepHierarchicalBit );
198    printf("LCULevelRC                    : %d\n", m_RCLCULevelRC );
199    printf("UseLCUSeparateModel           : %d\n", m_RCUseLCUSeparateModel );
200    printf("InitialQP                     : %d\n", m_RCInitialQP );
201    printf("ForceIntraQP                  : %d\n", m_RCForceIntraQP );
202  }
203#endif
204  printf("WaveFrontSynchro:%d WaveFrontSubstreams:%d", m_cAppEncCfg->getWaveFrontSynchro(), m_iWaveFrontSubstreams);
[494]205#if LAYER_CTB
206  printf("PCM:%d ", (m_cAppEncCfg->getUsePCM() && (1<<m_cAppEncCfg->getPCMLog2MinSize()) <= m_uiMaxCUWidth)? 1 : 0);
207#endif
[313]208}
209
210Bool confirmPara(Bool bflag, const char* message);
211
[442]212Bool TAppEncLayerCfg::xCheckParameter( Bool isField )
[313]213{
214  switch (m_conformanceMode)
215  {
216  case 0:
217    {
218      // no cropping or padding
219      m_confLeft = m_confRight = m_confTop = m_confBottom = 0;
220      m_aiPad[1] = m_aiPad[0] = 0;
221      break;
222    }
223  case 1:
224    {
225      // automatic padding to minimum CU size
[494]226#if LAYER_CTB
227      Int minCuSize = m_uiMaxCUHeight >> (m_uiMaxCUDepth - 1);
228#else
[313]229      Int minCuSize = m_cAppEncCfg->getMaxCUHeight() >> (m_cAppEncCfg->getMaxCUDepth() - 1);
[494]230#endif
[313]231      if (m_iSourceWidth % minCuSize)
232      {
233        m_aiPad[0] = m_confRight  = ((m_iSourceWidth / minCuSize) + 1) * minCuSize - m_iSourceWidth;
234        m_iSourceWidth  += m_confRight;
[713]235#if REPN_FORMAT_IN_VPS
236        m_confRight /= TComSPS::getWinUnitX( m_chromaFormatIDC );
237#endif
[313]238      }
239      if (m_iSourceHeight % minCuSize)
240      {
241        m_aiPad[1] = m_confBottom = ((m_iSourceHeight / minCuSize) + 1) * minCuSize - m_iSourceHeight;
242        m_iSourceHeight += m_confBottom;
[442]243        if ( isField )
244        {
245          m_iSourceHeightOrg += m_confBottom << 1;
246          m_aiPad[1] = m_confBottom << 1;
247        }
[713]248#if REPN_FORMAT_IN_VPS
249        m_confBottom /= TComSPS::getWinUnitY( m_chromaFormatIDC );
250#endif
[313]251      }
252      break;
253    }
254  case 2:
255    {
256      //padding
257      m_iSourceWidth  += m_aiPad[0];
258      m_iSourceHeight += m_aiPad[1];
259      m_confRight  = m_aiPad[0];
260      m_confBottom = m_aiPad[1];
[713]261#if REPN_FORMAT_IN_VPS
262      m_confRight /= TComSPS::getWinUnitX( m_chromaFormatIDC );
263      m_confBottom /= TComSPS::getWinUnitY( m_chromaFormatIDC );
264#endif
[313]265      break;
266    }
267  case 3:
268    {
269      // conformance
270      if ((m_confLeft == 0) && (m_confRight == 0) && (m_confTop == 0) && (m_confBottom == 0))
271      {
272        fprintf(stderr, "Warning: Cropping enabled, but all cropping parameters set to zero\n");
273      }
274      if ((m_aiPad[1] != 0) || (m_aiPad[0]!=0))
275      {
276        fprintf(stderr, "Warning: Cropping enabled, padding parameters will be ignored\n");
277      }
278      m_aiPad[1] = m_aiPad[0] = 0;
279      break;
280    }
281  }
282
283  // allocate slice-based dQP values
284  Int iFrameToBeEncoded = m_cAppEncCfg->getNumFrameToBeEncoded();
285  Int iGOPSize = m_cAppEncCfg->getGOPSize();
286  if( m_aidQP == NULL )
287    m_aidQP = new Int[iFrameToBeEncoded + iGOPSize + 1 ];
288  ::memset( m_aidQP, 0, sizeof(Int)*( iFrameToBeEncoded + iGOPSize + 1 ) );
289
290  // handling of floating-point QP values
291  // if QP is not integer, sequence is split into two sections having QP and QP+1
292  m_iQP = (Int)( m_fQP );
293  if ( m_iQP < m_fQP )
294  {
295    Int iSwitchPOC = (Int)( iFrameToBeEncoded - (m_fQP - m_iQP)*iFrameToBeEncoded + 0.5 );
296
297
298    iSwitchPOC = (Int)( (Double)iSwitchPOC / iGOPSize + 0.5 )*iGOPSize;
299    for ( Int i=iSwitchPOC; i<iFrameToBeEncoded + iGOPSize + 1; i++ )
300    {
301      m_aidQP[i] = 1;
302    }
303  }
304
[494]305#if LAYER_CTB
306  UInt maxCUWidth = m_uiMaxCUWidth;
307  UInt maxCUHeight = m_uiMaxCUHeight;
308  UInt maxCUDepth = m_uiMaxCUDepth;
309#else
[313]310  UInt maxCUWidth = m_cAppEncCfg->getMaxCUWidth();
311  UInt maxCUHeight = m_cAppEncCfg->getMaxCUHeight();
312  UInt maxCUDepth = m_cAppEncCfg->getMaxCUDepth();
[494]313#endif
[313]314  bool check_failed = false; /* abort if there is a fatal configuration problem */
315#define xConfirmPara(a,b) check_failed |= confirmPara(a,b)
316  // check range of parameters
317  xConfirmPara( m_iFrameRate <= 0,                                                          "Frame rate must be more than 1" );
318  xConfirmPara( (m_iSourceWidth  % (maxCUWidth  >> (maxCUDepth-1)))!=0,             "Resulting coded frame width must be a multiple of the minimum CU size");
319  xConfirmPara( (m_iSourceHeight % (maxCUHeight >> (maxCUDepth-1)))!=0,             "Resulting coded frame height must be a multiple of the minimum CU size");
320  xConfirmPara( (m_iIntraPeriod > 0 && m_iIntraPeriod < iGOPSize) || m_iIntraPeriod == 0, "Intra period must be more than GOP size, or -1 , not 0" );
321  if (m_cAppEncCfg->getDecodingRefreshType() == 2)
322  {
323    xConfirmPara( m_iIntraPeriod > 0 && m_iIntraPeriod <= iGOPSize ,                      "Intra period must be larger than GOP size for periodic IDR pictures");
324  }
325
[494]326#if O0194_DIFFERENT_BITDEPTH_EL_BL
327  for(UInt layer = 0; layer < MAX_LAYERS; layer++)
328  {
329    xConfirmPara( m_iQP <  -6 * ((Int)m_cAppEncCfg->getInternalBitDepthY(layer) - 8) || m_iQP > 51,                "QP exceeds supported range (-QpBDOffsety to 51)" );
330  }
331#else
[313]332  xConfirmPara( m_iQP <  -6 * ((Int)m_cAppEncCfg->getInternalBitDepthY() - 8) || m_iQP > 51,                "QP exceeds supported range (-QpBDOffsety to 51)" );
[494]333#endif
[313]334
335
[494]336  m_iWaveFrontSubstreams = m_cAppEncCfg->getWaveFrontSynchro() ? (m_iSourceHeight + maxCUHeight - 1) / maxCUHeight : 1;
[313]337  xConfirmPara( m_iWaveFrontSubstreams <= 0, "WaveFrontSubstreams must be positive" );
338  xConfirmPara( m_iWaveFrontSubstreams > 1 && !m_cAppEncCfg->getWaveFrontSynchro(), "Must have WaveFrontSynchro > 0 in order to have WaveFrontSubstreams > 1" );
339
340  //chekc parameters
341  xConfirmPara( m_iSourceWidth  % TComSPS::getWinUnitX(CHROMA_420) != 0, "Picture width must be an integer multiple of the specified chroma subsampling");
342  xConfirmPara( m_iSourceHeight % TComSPS::getWinUnitY(CHROMA_420) != 0, "Picture height must be an integer multiple of the specified chroma subsampling");
343
344  xConfirmPara( m_aiPad[0] % TComSPS::getWinUnitX(CHROMA_420) != 0, "Horizontal padding must be an integer multiple of the specified chroma subsampling");
345  xConfirmPara( m_aiPad[1] % TComSPS::getWinUnitY(CHROMA_420) != 0, "Vertical padding must be an integer multiple of the specified chroma subsampling");
346
[713]347#if !REPN_FORMAT_IN_VPS
[313]348  xConfirmPara( m_confLeft   % TComSPS::getWinUnitX(CHROMA_420) != 0, "Left conformance window offset must be an integer multiple of the specified chroma subsampling");
349  xConfirmPara( m_confRight  % TComSPS::getWinUnitX(CHROMA_420) != 0, "Right conformance window offset must be an integer multiple of the specified chroma subsampling");
350  xConfirmPara( m_confTop    % TComSPS::getWinUnitY(CHROMA_420) != 0, "Top conformance window offset must be an integer multiple of the specified chroma subsampling");
351  xConfirmPara( m_confBottom % TComSPS::getWinUnitY(CHROMA_420) != 0, "Bottom conformance window offset must be an integer multiple of the specified chroma subsampling");
[713]352#endif
[494]353
354#if LAYER_CTB 
355  xConfirmPara( (m_uiMaxCUWidth  >> m_uiMaxCUDepth) < 4,                                    "Minimum partition width size should be larger than or equal to 8");
356  xConfirmPara( (m_uiMaxCUHeight >> m_uiMaxCUDepth) < 4,                                    "Minimum partition height size should be larger than or equal to 8");
357  xConfirmPara( m_uiMaxCUWidth < 16,                                                        "Maximum partition width size should be larger than or equal to 16");
358  xConfirmPara( m_uiMaxCUHeight < 16,                                                       "Maximum partition height size should be larger than or equal to 16");
359  xConfirmPara( m_uiQuadtreeTULog2MinSize < 2,                                        "QuadtreeTULog2MinSize must be 2 or greater.");
360  xConfirmPara( m_uiQuadtreeTULog2MaxSize > 5,                                        "QuadtreeTULog2MaxSize must be 5 or smaller.");
361  xConfirmPara( (1<<m_uiQuadtreeTULog2MaxSize) > m_uiMaxCUWidth,                                        "QuadtreeTULog2MaxSize must be log2(maxCUSize) or smaller.");
362  xConfirmPara( m_uiQuadtreeTULog2MaxSize < m_uiQuadtreeTULog2MinSize,                "QuadtreeTULog2MaxSize must be greater than or equal to m_uiQuadtreeTULog2MinSize.");
363  xConfirmPara( (1<<m_uiQuadtreeTULog2MinSize)>(m_uiMaxCUWidth >>(m_uiMaxCUDepth-1)), "QuadtreeTULog2MinSize must not be greater than minimum CU size" ); // HS
364  xConfirmPara( (1<<m_uiQuadtreeTULog2MinSize)>(m_uiMaxCUHeight>>(m_uiMaxCUDepth-1)), "QuadtreeTULog2MinSize must not be greater than minimum CU size" ); // HS
365  xConfirmPara( ( 1 << m_uiQuadtreeTULog2MinSize ) > ( m_uiMaxCUWidth  >> m_uiMaxCUDepth ), "Minimum CU width must be greater than minimum transform size." );
366  xConfirmPara( ( 1 << m_uiQuadtreeTULog2MinSize ) > ( m_uiMaxCUHeight >> m_uiMaxCUDepth ), "Minimum CU height must be greater than minimum transform size." );
367  xConfirmPara( m_uiQuadtreeTUMaxDepthInter < 1,                                                         "QuadtreeTUMaxDepthInter must be greater than or equal to 1" );
368  xConfirmPara( m_uiMaxCUWidth < ( 1 << (m_uiQuadtreeTULog2MinSize + m_uiQuadtreeTUMaxDepthInter - 1) ), "QuadtreeTUMaxDepthInter must be less than or equal to the difference between log2(maxCUSize) and QuadtreeTULog2MinSize plus 1" );
369  xConfirmPara( m_uiQuadtreeTUMaxDepthIntra < 1,                                                         "QuadtreeTUMaxDepthIntra must be greater than or equal to 1" );
370  xConfirmPara( m_uiMaxCUWidth < ( 1 << (m_uiQuadtreeTULog2MinSize + m_uiQuadtreeTUMaxDepthIntra - 1) ), "QuadtreeTUMaxDepthInter must be less than or equal to the difference between log2(maxCUSize) and QuadtreeTULog2MinSize plus 1" );
371
372  // max CU width and height should be power of 2
373  UInt ui = m_uiMaxCUWidth;
374  while(ui)
375  {
376    ui >>= 1;
377    if( (ui & 1) == 1)
378      xConfirmPara( ui != 1 , "Width should be 2^n");
379  }
380  ui = m_uiMaxCUHeight;
381  while(ui)
382  {
383    ui >>= 1;
384    if( (ui & 1) == 1)
385      xConfirmPara( ui != 1 , "Height should be 2^n");
386  }
387#endif
388
[313]389#undef xConfirmPara
390  return check_failed;
391}
392
[494]393#endif //SVC_EXTENSION
[313]394
395
396//! \}
Note: See TracBrowser for help on using the repository browser.