source: SHVCSoftware/branches/SHM-6-dev/source/App/TAppEncoder/TAppEncLayerCfg.cpp @ 918

Last change on this file since 918 was 705, checked in by seregin, 11 years ago

change the conformance input to be not multiplied by SubWidthC and SubHeightC, it should be a lossless change

  • 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
[705]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 );
[705]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;
[705]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        }
[705]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];
[705]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
[705]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");
[705]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.