source: SHVCSoftware/branches/SHM-2.0-dev/source/App/TAppEncoder/TAppEncLayerCfg.cpp @ 577

Last change on this file since 577 was 187, checked in by seregin, 12 years ago

enable zero number of direct references, fix for AVC base YUV input

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