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

Last change on this file since 851 was 849, checked in by sharp, 10 years ago

JCTVC-R0340 Resampling modifications (Macro:R0340_RESAMPLING_MODIFICATION)

Include generic phase (R0209), ref. region offset (R0013), move scaled ref offset to PPS (R0013), remove clip to scaled ref window (R0220) and ref offset signal change (R0220).

From: Tomoyuki Yamamoto <yamamoto.tomoyuki@…>

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