source: SHVCSoftware/branches/SHM-3.0-dev/source/App/TAppEncoder/TAppEncLayerCfg.cpp @ 337

Last change on this file since 337 was 313, checked in by suehring, 11 years ago

set svn:eol-style=native property on all source files to do proper
automatic line break conversion on check-out and check-in

  • Property svn:eol-style set to native
File size: 10.8 KB
Line 
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
25// ====================================================================================================================
26// Constructor / destructor / initialization / destroy
27// ====================================================================================================================
28#if SVC_EXTENSION
29TAppEncLayerCfg::TAppEncLayerCfg()
30  :m_cInputFile(string("")),
31  m_cReconFile(string("")),
32  m_conformanceMode( 0 ),
33  m_aidQP(NULL)
34{
35  m_confLeft = m_confRight = m_confTop = m_confBottom = 0;
36  m_aiPad[1] = m_aiPad[0] = 0;
37#if SCALED_REF_LAYER_OFFSETS
38  m_numScaledRefLayerOffsets = 0;
39  ::memset(m_scaledRefLayerLeftOffset,   0, sizeof(m_scaledRefLayerLeftOffset));
40  ::memset(m_scaledRefLayerTopOffset,    0, sizeof(m_scaledRefLayerTopOffset));
41  ::memset(m_scaledRefLayerRightOffset,  0, sizeof(m_scaledRefLayerRightOffset));
42  ::memset(m_scaledRefLayerBottomOffset, 0, sizeof(m_scaledRefLayerBottomOffset));
43#endif
44}
45
46TAppEncLayerCfg::~TAppEncLayerCfg()
47{
48  if ( m_aidQP )
49  {
50    delete[] m_aidQP;
51  }
52}
53
54Void TAppEncLayerCfg::create()
55{
56}
57
58Void TAppEncLayerCfg::destroy()
59{
60}
61
62
63// ====================================================================================================================
64// Public member functions
65// ====================================================================================================================
66
67/** \param  argc        number of arguments
68\param  argv        array of arguments
69\retval             true when success
70*/
71bool TAppEncLayerCfg::parseCfg( const string& cfgFileName  )
72{
73  string cfg_InputFile;
74  string cfg_ReconFile;
75  string cfg_dQPFile;
76  po::Options opts;
77  opts.addOptions()
78    ("InputFile,i",           cfg_InputFile,  string(""), "original YUV input file name")
79#if AVC_BASE
80    ("InputBLFile,-ibl",      cfg_InputFile,  string(""), "original YUV input file name")
81#endif
82    ("ReconFile,o",           cfg_ReconFile,  string(""), "reconstructed YUV output file name")
83    ("SourceWidth,-wdt",      m_iSourceWidth,  0, "Source picture width")
84    ("SourceHeight,-hgt",     m_iSourceHeight, 0, "Source picture height")
85    ("CroppingMode",          m_conformanceMode,  0, "Cropping mode (0: no cropping, 1:automatic padding, 2: padding, 3:cropping")
86    ("CropLeft",              m_confLeft,      0, "Left cropping/padding for cropping mode 3")
87    ("CropRight",             m_confRight,     0, "Right cropping/padding for cropping mode 3")
88    ("CropTop",               m_confTop,       0, "Top cropping/padding for cropping mode 3")
89    ("CropBottom",            m_confBottom,    0, "Bottom cropping/padding for cropping mode 3")
90    ("HorizontalPadding,-pdx",m_aiPad[0],      0, "horizontal source padding for cropping mode 2")
91    ("VerticalPadding,-pdy",  m_aiPad[1],      0, "vertical source padding for cropping mode 2")
92    ("IntraPeriod,-ip",       m_iIntraPeriod,  -1, "intra period in frames, (-1: only first frame)")
93    ("FrameRate,-fr",         m_iFrameRate,    0, "Frame rate")
94    ("dQPFile,m",             cfg_dQPFile, string(""), "dQP file name")
95    ("QP,q",                  m_fQP,          30.0, "Qp value, if value is float, QP is switched once during encoding")
96    ;
97
98  po::setDefaults(opts);
99  po::parseConfigFile(opts, cfgFileName);
100
101  m_cInputFile = cfg_InputFile;
102  m_cReconFile = cfg_ReconFile;
103  m_pchdQPFile = cfg_dQPFile.empty() ? NULL : strdup(cfg_dQPFile.c_str());
104
105  // reading external dQP description from file
106  if ( m_pchdQPFile )
107  {
108    FILE* fpt=fopen( m_pchdQPFile, "r" );
109    if ( fpt )
110    {
111      Int iValue;
112      Int iPOC = 0;
113      while ( iPOC < m_cAppEncCfg->getNumFrameToBeEncoded() )
114      {
115        if ( fscanf(fpt, "%d", &iValue ) == EOF ) break;
116        m_aidQP[ iPOC ] = iValue;
117        iPOC++;
118      }
119      fclose(fpt);
120    }
121  }
122  return true;
123}
124
125#if AVC_SYNTAX
126Void TAppEncLayerCfg::xPrintParameter( UInt layerId )
127#else
128Void TAppEncLayerCfg::xPrintParameter()
129#endif
130{
131  printf("Input File                    : %s\n", m_cInputFile.c_str()  );
132  printf("Reconstruction File           : %s\n", m_cReconFile.c_str()  );
133#if AVC_SYNTAX
134  if( layerId == 0 )
135  {
136    printf("Base layer syntax file        : %s\n", m_cAppEncCfg->getBLSyntaxFile() );
137  }
138#endif
139  printf("Real     Format               : %dx%d %dHz\n", m_iSourceWidth - m_confLeft - m_confRight, m_iSourceHeight - m_confTop - m_confBottom, m_iFrameRate );
140  printf("Internal Format               : %dx%d %dHz\n", m_iSourceWidth, m_iSourceHeight, m_iFrameRate );
141  printf("QP                            : %5.2f\n", m_fQP );
142  printf("Intra period                  : %d\n", m_iIntraPeriod );
143#if RC_SHVC_HARMONIZATION
144  printf("RateControl                   : %d\n", m_RCEnableRateControl );
145  if(m_RCEnableRateControl)
146  {
147    printf("TargetBitrate                 : %d\n", m_RCTargetBitrate );
148    printf("KeepHierarchicalBit           : %d\n", m_RCKeepHierarchicalBit );
149    printf("LCULevelRC                    : %d\n", m_RCLCULevelRC );
150    printf("UseLCUSeparateModel           : %d\n", m_RCUseLCUSeparateModel );
151    printf("InitialQP                     : %d\n", m_RCInitialQP );
152    printf("ForceIntraQP                  : %d\n", m_RCForceIntraQP );
153  }
154#endif
155  printf("WaveFrontSynchro:%d WaveFrontSubstreams:%d", m_cAppEncCfg->getWaveFrontSynchro(), m_iWaveFrontSubstreams);
156}
157
158Bool confirmPara(Bool bflag, const char* message);
159
160Bool TAppEncLayerCfg::xCheckParameter()
161{
162  switch (m_conformanceMode)
163  {
164  case 0:
165    {
166      // no cropping or padding
167      m_confLeft = m_confRight = m_confTop = m_confBottom = 0;
168      m_aiPad[1] = m_aiPad[0] = 0;
169      break;
170    }
171  case 1:
172    {
173      // automatic padding to minimum CU size
174      Int minCuSize = m_cAppEncCfg->getMaxCUHeight() >> (m_cAppEncCfg->getMaxCUDepth() - 1);
175      if (m_iSourceWidth % minCuSize)
176      {
177        m_aiPad[0] = m_confRight  = ((m_iSourceWidth / minCuSize) + 1) * minCuSize - m_iSourceWidth;
178        m_iSourceWidth  += m_confRight;
179      }
180      if (m_iSourceHeight % minCuSize)
181      {
182        m_aiPad[1] = m_confBottom = ((m_iSourceHeight / minCuSize) + 1) * minCuSize - m_iSourceHeight;
183        m_iSourceHeight += m_confBottom;
184      }
185      break;
186    }
187  case 2:
188    {
189      //padding
190      m_iSourceWidth  += m_aiPad[0];
191      m_iSourceHeight += m_aiPad[1];
192      m_confRight  = m_aiPad[0];
193      m_confBottom = m_aiPad[1];
194      break;
195    }
196  case 3:
197    {
198      // conformance
199      if ((m_confLeft == 0) && (m_confRight == 0) && (m_confTop == 0) && (m_confBottom == 0))
200      {
201        fprintf(stderr, "Warning: Cropping enabled, but all cropping parameters set to zero\n");
202      }
203      if ((m_aiPad[1] != 0) || (m_aiPad[0]!=0))
204      {
205        fprintf(stderr, "Warning: Cropping enabled, padding parameters will be ignored\n");
206      }
207      m_aiPad[1] = m_aiPad[0] = 0;
208      break;
209    }
210  }
211
212  // allocate slice-based dQP values
213  Int iFrameToBeEncoded = m_cAppEncCfg->getNumFrameToBeEncoded();
214  Int iGOPSize = m_cAppEncCfg->getGOPSize();
215  if( m_aidQP == NULL )
216    m_aidQP = new Int[iFrameToBeEncoded + iGOPSize + 1 ];
217  ::memset( m_aidQP, 0, sizeof(Int)*( iFrameToBeEncoded + iGOPSize + 1 ) );
218
219  // handling of floating-point QP values
220  // if QP is not integer, sequence is split into two sections having QP and QP+1
221  m_iQP = (Int)( m_fQP );
222  if ( m_iQP < m_fQP )
223  {
224    Int iSwitchPOC = (Int)( iFrameToBeEncoded - (m_fQP - m_iQP)*iFrameToBeEncoded + 0.5 );
225
226
227    iSwitchPOC = (Int)( (Double)iSwitchPOC / iGOPSize + 0.5 )*iGOPSize;
228    for ( Int i=iSwitchPOC; i<iFrameToBeEncoded + iGOPSize + 1; i++ )
229    {
230      m_aidQP[i] = 1;
231    }
232  }
233
234  UInt maxCUWidth = m_cAppEncCfg->getMaxCUWidth();
235  UInt maxCUHeight = m_cAppEncCfg->getMaxCUHeight();
236  UInt maxCUDepth = m_cAppEncCfg->getMaxCUDepth();
237  bool check_failed = false; /* abort if there is a fatal configuration problem */
238#define xConfirmPara(a,b) check_failed |= confirmPara(a,b)
239  // check range of parameters
240  xConfirmPara( m_iFrameRate <= 0,                                                          "Frame rate must be more than 1" );
241  xConfirmPara( (m_iSourceWidth  % (maxCUWidth  >> (maxCUDepth-1)))!=0,             "Resulting coded frame width must be a multiple of the minimum CU size");
242  xConfirmPara( (m_iSourceHeight % (maxCUHeight >> (maxCUDepth-1)))!=0,             "Resulting coded frame height must be a multiple of the minimum CU size");
243  xConfirmPara( (m_iIntraPeriod > 0 && m_iIntraPeriod < iGOPSize) || m_iIntraPeriod == 0, "Intra period must be more than GOP size, or -1 , not 0" );
244  if (m_cAppEncCfg->getDecodingRefreshType() == 2)
245  {
246    xConfirmPara( m_iIntraPeriod > 0 && m_iIntraPeriod <= iGOPSize ,                      "Intra period must be larger than GOP size for periodic IDR pictures");
247  }
248
249  xConfirmPara( m_iQP <  -6 * ((Int)m_cAppEncCfg->getInternalBitDepthY() - 8) || m_iQP > 51,                "QP exceeds supported range (-QpBDOffsety to 51)" );
250
251
252  m_iWaveFrontSubstreams = m_cAppEncCfg->getWaveFrontSynchro() ? (m_iSourceHeight + m_cAppEncCfg->getMaxCUHeight() - 1) / m_cAppEncCfg->getMaxCUHeight() : 1;
253  xConfirmPara( m_iWaveFrontSubstreams <= 0, "WaveFrontSubstreams must be positive" );
254  xConfirmPara( m_iWaveFrontSubstreams > 1 && !m_cAppEncCfg->getWaveFrontSynchro(), "Must have WaveFrontSynchro > 0 in order to have WaveFrontSubstreams > 1" );
255
256  //chekc parameters
257  xConfirmPara( m_iSourceWidth  % TComSPS::getWinUnitX(CHROMA_420) != 0, "Picture width must be an integer multiple of the specified chroma subsampling");
258  xConfirmPara( m_iSourceHeight % TComSPS::getWinUnitY(CHROMA_420) != 0, "Picture height must be an integer multiple of the specified chroma subsampling");
259
260  xConfirmPara( m_aiPad[0] % TComSPS::getWinUnitX(CHROMA_420) != 0, "Horizontal padding must be an integer multiple of the specified chroma subsampling");
261  xConfirmPara( m_aiPad[1] % TComSPS::getWinUnitY(CHROMA_420) != 0, "Vertical padding must be an integer multiple of the specified chroma subsampling");
262
263  xConfirmPara( m_confLeft   % TComSPS::getWinUnitX(CHROMA_420) != 0, "Left conformance window offset must be an integer multiple of the specified chroma subsampling");
264  xConfirmPara( m_confRight  % TComSPS::getWinUnitX(CHROMA_420) != 0, "Right conformance window offset must be an integer multiple of the specified chroma subsampling");
265  xConfirmPara( m_confTop    % TComSPS::getWinUnitY(CHROMA_420) != 0, "Top conformance window offset must be an integer multiple of the specified chroma subsampling");
266  xConfirmPara( m_confBottom % TComSPS::getWinUnitY(CHROMA_420) != 0, "Bottom conformance window offset must be an integer multiple of the specified chroma subsampling");
267#undef xConfirmPara
268  return check_failed;
269}
270
271#endif
272
273
274//! \}
Note: See TracBrowser for help on using the repository browser.