Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvenc/source/Lib/vvenc/vvencCfg.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or
4
other Intellectual Property Rights other than the copyrights concerning
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
43
44
/** \file     vvencCfg.cpp
45
    \brief    encoder configuration class
46
*/
47
48
#include "vvenc/vvencCfg.h"
49
50
#include "CommonLib/CommonDef.h"
51
#include "CommonLib/Slice.h"
52
#include "CommonLib/ProfileLevelTier.h"
53
#include "Utilities/MsgLog.h"
54
#include "EncoderLib/GOPCfg.h"
55
56
#include <math.h>
57
#include <thread>
58
#include <iomanip>
59
60
#include "apputils/VVEncAppCfg.h"
61
62
63
VVENC_NAMESPACE_BEGIN
64
65
static bool checkCfgParameter( vvenc_config *cfg );
66
static void checkCfgPicPartitioningParameter( vvenc_config *c );
67
static void checkCfgInputArrays( vvenc_config *c, int &lastNonZeroCol, int &lastNonZeroRow, bool &cfgIsValid );
68
static void initMultithreading( vvenc_config *c );
69
static std::string vvenc_cfgString;
70
71
static int vvenc_getQpValsSize( int QpVals[] )
72
0
{
73
0
  int size=0;
74
0
  for ( int i = 0; i < VVENC_MAX_QP_VALS_CHROMA; i++ )
75
0
  {
76
0
    if( QpVals[i] > 0) size++;
77
0
    else break;
78
0
  }
79
80
0
  if( size == 0)
81
0
  {
82
0
    size = 1;  // at least first value must be set to 0
83
0
  }
84
85
0
  return size;
86
0
}
87
88
static std::vector<int> vvenc_getQpValsAsVec( int QpVals[] )
89
0
{
90
0
  std::vector<int> QpValsVec;
91
0
  for ( int i = 0; i < VVENC_MAX_QP_VALS_CHROMA; i++ )
92
0
  {
93
0
    if( QpVals[i] > 0) QpValsVec.push_back( QpVals[i] );
94
0
    else break;
95
0
  }
96
0
  if( QpValsVec.empty() )
97
0
  {
98
0
    QpValsVec = { 0 };
99
0
  }
100
0
  return QpValsVec;
101
0
}
102
103
104
static void vvenc_checkCharArrayStr( char array[], int size )
105
0
{
106
0
  bool resetArray = false;
107
0
  if ( 0 == strcmp(array, "empty") )
108
0
  {
109
0
    resetArray = true;
110
0
  }
111
0
  else if ( 0 == strcmp(array, "undef") )
112
0
  {
113
0
    resetArray = true;
114
0
  }
115
0
  else if ( 0 == strcmp(array, "''") )
116
0
  {
117
0
    resetArray = true;
118
0
  }
119
0
  else if ( 0 == strcmp(array, "\"\"") )
120
0
  {
121
0
    resetArray = true;
122
0
  }
123
0
  else if ( 0 == strcmp(array, "[]") )
124
0
  {
125
0
    resetArray = true;
126
0
  }
127
128
0
  if( resetArray )
129
0
  {
130
0
    for( int i = 0; i < size; i++ ) memset(&array[i],0, sizeof(char));
131
0
    array[0] = '\0';
132
0
  }
133
0
}
134
135
static inline std::string getProfileStr( int profile )
136
0
{
137
0
  std::string cT;
138
0
  switch( profile )
139
0
  {
140
0
    case VVENC_MAIN_10                              : cT = "main_10"; break;
141
0
    case VVENC_MAIN_10_STILL_PICTURE                : cT = "main_10_still_picture"; break;
142
0
    case VVENC_MAIN_10_444                          : cT = "main_10_444"; break;
143
0
    case VVENC_MAIN_10_444_STILL_PICTURE            : cT = "main_10_444_still_picture"; break;
144
0
    case VVENC_MULTILAYER_MAIN_10                   : cT = "multilayer_main_10"; break;
145
0
    case VVENC_MULTILAYER_MAIN_10_STILL_PICTURE     : cT = "multilayer_main_10_still_picture"; break;
146
0
    case VVENC_MULTILAYER_MAIN_10_444               : cT = "multilayer_main_10_444"; break;
147
0
    case VVENC_MULTILAYER_MAIN_10_444_STILL_PICTURE : cT = "multilayer_main_10_444_still_picture"; break;
148
0
    case VVENC_PROFILE_AUTO                         : cT = "auto"; break;
149
0
    default                                            : cT = "unknown"; break;
150
0
  }
151
0
  return cT;
152
0
}
153
154
static inline std::string getLevelStr( int level )
155
0
{
156
0
  std::string cT;
157
0
  switch( level )
158
0
  {
159
0
    case VVENC_LEVEL_AUTO: cT = "auto";    break;
160
0
    case VVENC_LEVEL1    : cT = "1";       break;
161
0
    case VVENC_LEVEL2    : cT = "2";       break;
162
0
    case VVENC_LEVEL2_1  : cT = "2.1";     break;
163
0
    case VVENC_LEVEL3    : cT = "3";       break;
164
0
    case VVENC_LEVEL3_1  : cT = "3.1";     break;
165
0
    case VVENC_LEVEL4    : cT = "4";       break;
166
0
    case VVENC_LEVEL4_1  : cT = "4.1";     break;
167
0
    case VVENC_LEVEL5    : cT = "5";       break;
168
0
    case VVENC_LEVEL5_1  : cT = "5.1";     break;
169
0
    case VVENC_LEVEL5_2  : cT = "5.2";     break;
170
0
    case VVENC_LEVEL6    : cT = "6";       break;
171
0
    case VVENC_LEVEL6_1  : cT = "6.1";     break;
172
0
    case VVENC_LEVEL6_2  : cT = "6.2";     break;
173
0
    case VVENC_LEVEL6_3  : cT = "6.3";     break;
174
0
    case VVENC_LEVEL15_5 : cT = "15.5";    break;
175
0
    default               : cT = "unknown"; break;
176
0
  }
177
0
  return cT;
178
0
}
179
180
static inline std::string getCostFunctionStr( int cost )
181
0
{
182
0
  std::string cT;
183
0
  switch( cost )
184
0
  {
185
0
    case VVENC_COST_STANDARD_LOSSY               : cT = "Lossy coding"; break;
186
0
    case VVENC_COST_SEQUENCE_LEVEL_LOSSLESS      : cT = "Sequence level lossless coding"; break;
187
0
    case VVENC_COST_LOSSLESS_CODING              : cT = "Lossless coding"; break;
188
0
    case VVENC_COST_MIXED_LOSSLESS_LOSSY_CODING  : cT = "Mixed lossless lossy coding"; break;
189
0
    default                                : cT = "Unknown"; break;
190
0
  }
191
0
  return cT;
192
0
}
193
194
static inline std::string getDynamicRangeStr( int dynamicRange )
195
0
{
196
0
  std::string cT;
197
0
  switch( dynamicRange )
198
0
  {
199
0
    case VVENC_HDR_OFF            : cT = "SDR"; break;
200
0
    case VVENC_HDR_PQ             : cT = "HDR10/PQ"; break;
201
0
    case VVENC_HDR_HLG            : cT = "HDR HLG"; break;
202
0
    case VVENC_HDR_PQ_BT2020      : cT = "HDR10/PQ BT.2020"; break;
203
0
    case VVENC_HDR_HLG_BT2020     : cT = "HDR HLG BT.2020"; break;
204
0
    case VVENC_HDR_USER_DEFINED   : cT = "HDR user defined"; break;
205
0
    case VVENC_SDR_BT709          : cT = "SDR BT.709"; break;
206
0
    case VVENC_SDR_BT2020         : cT = "SDR BT.2020"; break;
207
0
    case VVENC_SDR_BT470BG        : cT = "SDR BT.470 B/G"; break;
208
0
    default                       : cT = "unknown"; break;
209
0
  }
210
0
  return cT;
211
0
}
212
213
static inline bool isHDRMode( vvencHDRMode hdrMode )
214
0
{
215
0
  return ( hdrMode == VVENC_HDR_PQ || hdrMode == VVENC_HDR_PQ_BT2020 ||
216
0
           hdrMode == VVENC_HDR_HLG || hdrMode == VVENC_HDR_HLG_BT2020 ) ? true : false;
217
0
}
218
219
static inline std::string vvenc_getMasteringDisplayStr( unsigned int md[10]  )
220
0
{
221
0
  std::stringstream css;
222
223
0
  css << "G(" << md[0] << "," << md[1] << ")";
224
0
  css << "B(" << md[2] << "," << md[3] << ")";
225
0
  css << "R(" << md[4] << "," << md[5] << ")";
226
0
  css << "WP("<< md[6] << "," << md[7] << ")";
227
0
  css << "L(" << md[8] << "," << md[9] << ")";
228
229
0
  css << " (= nits: ";
230
0
  css << "G(" << md[0]/50000.0 << "," << md[1]/50000.0 << ")";
231
0
  css << "B(" << md[2]/50000.0 << "," << md[3]/50000.0 << ")";
232
0
  css << "R(" << md[4]/50000.0 << "," << md[5]/50000.0 << ")";
233
0
  css << "WP("<< md[6]/50000.0 << "," << md[7]/50000.0 << ")";
234
0
  css << "L(" << md[8]/10000.0 << "," << md[9]/10000.0 << ")";
235
0
  css << ")";
236
0
  return css.str();
237
0
}
238
239
static inline std::string vvenc_getContentLightLevelStr( unsigned int cll[2] )
240
0
{
241
0
  std::stringstream css;
242
243
0
  css << cll[0] << "," << cll[1] << " (cll,fall)";
244
0
  return css.str();
245
0
}
246
247
static inline std::string vvenc_getDecodingRefreshTypeStr(  int type, bool poc0idr )
248
0
{
249
0
  std::string cType( "CRA");
250
0
  switch( type )
251
0
  {
252
0
    case 0: cType = "none"; break;
253
0
    case 1: cType = "CRA"; break;
254
0
    case 2: cType = "IDR"; break;
255
0
    case 3: cType = "RecPointSEI"; break;
256
0
    case 4: cType = "IDR2 (deprecated)"; break; //deprecated
257
0
    case 5: cType = "CRA_CRE (CRA with constrained encoding for RASL pictures)"; break;
258
0
    case 6: cType = "IDR_NO_RADL"; break;
259
0
    default: cType = "unknown"; break;
260
0
  }
261
0
  if( poc0idr ) cType += " with POC 0 IDR";
262
0
  return cType;
263
0
}
264
265
static inline int getNumThreadsDefault( vvenc_config *c )
266
0
{
267
0
  const int minSize = std::min( c->m_SourceWidth, c->m_SourceHeight );
268
0
  if( minSize >= 2880 )
269
0
    return 12;
270
0
  else if( minSize >= 720 )
271
0
    return 8;
272
0
  return 4;
273
0
}
274
275
VVENC_DECL void vvenc_GOPEntry_default(vvencGOPEntry *GOPEntry )
276
0
{
277
0
  GOPEntry->m_POC                       = -1;
278
0
  GOPEntry->m_QPOffset                  = 0;
279
0
  GOPEntry->m_QPOffsetModelOffset       = 0.0;
280
0
  GOPEntry->m_QPOffsetModelScale        = 0.0;
281
0
  GOPEntry->m_CbQPoffset                = 0;
282
0
  GOPEntry->m_CrQPoffset                = 0;
283
0
  GOPEntry->m_QPFactor                  = 0.0;
284
0
  GOPEntry->m_tcOffsetDiv2              = 0;
285
0
  GOPEntry->m_betaOffsetDiv2            = 0;
286
0
  GOPEntry->m_cfgUnused1                = 0;
287
0
  GOPEntry->m_cfgUnused2                = 0;
288
0
  GOPEntry->m_cfgUnused3                = 0;
289
0
  GOPEntry->m_cfgUnused4                = 0;
290
0
  GOPEntry->m_temporalId                = 0;
291
0
  GOPEntry->m_sliceType                 = 'P';
292
0
  memset( GOPEntry->m_numRefPicsActive, 0, sizeof( GOPEntry->m_numRefPicsActive ) );
293
0
  memset( GOPEntry->m_numRefPics, 0, sizeof( GOPEntry->m_numRefPics ) );
294
0
  memset( GOPEntry->m_deltaRefPics, 0, sizeof( GOPEntry->m_deltaRefPics ) );
295
0
}
296
297
VVENC_DECL void vvenc_WCGChromaQPControl_default(vvencWCGChromaQPControl *WCGChromaQPControl )
298
0
{
299
0
  memset( WCGChromaQPControl, 0, sizeof( vvencWCGChromaQPControl ) );
300
0
}
301
302
VVENC_DECL void vvenc_ChromaQpMappingTableParams_default(vvencChromaQpMappingTableParams *p )
303
0
{
304
0
  p->m_numQpTables                                          = 0;
305
0
  p->m_qpBdOffset                                           = 12;
306
0
  p->m_sameCQPTableForAllChromaFlag                         = true;
307
308
0
  memset( p->m_qpTableStartMinus26, 0, sizeof( p->m_qpTableStartMinus26 ) );
309
0
  memset( p->m_numPtsInCQPTableMinus1, 0, sizeof( p->m_numPtsInCQPTableMinus1 ) );
310
0
  memset( p->m_deltaQpInValMinus1, 0, sizeof( p->m_deltaQpInValMinus1 ) );
311
0
  memset( p->m_deltaQpOutVal, 0, sizeof( p->m_deltaQpOutVal ) );
312
0
}
313
314
VVENC_DECL void vvenc_RPLEntry_default(vvencRPLEntry *RPLEntry )
315
0
{
316
0
  RPLEntry->m_POC                              = -1;
317
0
  RPLEntry->m_temporalId                       = 0;
318
0
  RPLEntry->m_refPic                           = false;
319
0
  RPLEntry->m_ltrp_in_slice_header_flag        = false;
320
0
  RPLEntry->m_numRefPicsActive                 = 0;
321
0
  RPLEntry->m_sliceType                        ='P';
322
0
  RPLEntry->m_numRefPics                       = 0;
323
324
0
  memset(&RPLEntry->m_deltaRefPics,0, sizeof(RPLEntry->m_deltaRefPics));
325
0
}
326
327
VVENC_DECL void vvenc_ReshapeCW_default(vvencReshapeCW *reshapeCW )
328
0
{
329
0
  memset( reshapeCW->binCW, 0, sizeof( reshapeCW->binCW ) );
330
0
  reshapeCW->updateCtrl = 0;
331
0
  reshapeCW->adpOption  = 0;
332
0
  reshapeCW->initialCW  = 0;
333
0
  reshapeCW->rspPicSize = 0;
334
0
  reshapeCW->rspFps     = 0;
335
0
  reshapeCW->rspTid     = 0;
336
0
  reshapeCW->rspFpsToIp = 0;
337
0
}
338
339
VVENC_DECL void vvenc_vvencMCTF_default(vvencMCTF *vvencMCTF )
340
0
{
341
0
  vvencMCTF->MCTF = 0;
342
0
  vvencMCTF->MCTFSpeed = 0;
343
0
  vvencMCTF->MCTFFutureReference = true;
344
0
  vvencMCTF->numFrames = 0;
345
0
  vvencMCTF->numStrength = 0;
346
0
  vvencMCTF->MCTFUnitSize = -1;
347
0
  memset( vvencMCTF->MCTFFrames, 0, sizeof( vvencMCTF->MCTFFrames ) );
348
0
  memset( vvencMCTF->MCTFStrengths, 0, sizeof( vvencMCTF->MCTFStrengths ) );
349
0
}
350
351
VVENC_DECL void vvenc_config_default(vvenc_config *c )
352
0
{
353
0
  int i = 0;
354
355
  // internal params
356
0
  c->m_configDone                              = false;         ///< state variable, Private context used for internal data ( do not change )
357
0
  c->m_confirmFailed                           = false;         ///< state variable, Private context used for internal data ( do not change )
358
0
  c->m_msgFnc                                  = nullptr;
359
0
  c->m_msgCtx                                  = nullptr;
360
361
  // core params
362
0
  c->m_SourceWidth                             = 0;             ///< source width in pixel
363
0
  c->m_SourceHeight                            = 0;             ///< source height in pixel (when interlaced = field height)
364
0
  c->m_FrameRate                               = 0;             ///< source frame-rates (Hz) Numerator
365
0
  c->m_FrameScale                              = 1;             ///< source frame-rates (Hz) Denominator
366
0
  c->m_TicksPerSecond                          = VVENC_TICKS_PER_SEC_DEF; ///< ticks per second for dts generation (default: 27000000, 1..27000000, -1: ticks per frame=1)
367
368
0
  c->m_framesToBeEncoded                       = 0;             ///< number of encoded frames
369
370
0
  c->m_inputBitDepth[0]                        = 8;             ///< bit-depth of input
371
0
  c->m_inputBitDepth[1]                        = 0;
372
373
0
  c->m_numThreads                              = 0;             ///< number of worker threads
374
375
0
  c->m_QP                                      = VVENC_DEFAULT_QP;
376
0
  c->m_RCTargetBitrate                         = VVENC_RC_OFF;
377
0
  c->m_RCMaxBitrate                            = 0;
378
0
  c->m_RCInitialQP                             = 0;
379
380
0
  c->m_verbosity                               = VVENC_INFO;    ///< encoder verbosity
381
382
  // basic params
383
0
  c->m_profile                                 = vvencProfile::VVENC_PROFILE_AUTO;
384
0
  c->m_levelTier                               = vvencTier::VVENC_TIER_MAIN ;
385
0
  c->m_level                                   = vvencLevel::VVENC_LEVEL_AUTO;
386
387
0
  c->m_IntraPeriod                             = 0;             ///< period of I-slice (random access period)
388
0
  c->m_IntraPeriodSec                          = 1;             ///< period of I-slice in seconds (random access period)
389
0
  c->m_DecodingRefreshType                     = VVENC_DRT_CRA;       ///< random access type
390
0
  c->m_GOPSize                                 = 32;            ///< GOP size
391
0
  c->m_poc0idr                                 = -1;
392
0
  c->m_picReordering                           = 1;
393
394
0
  c->m_usePerceptQPA                           = false;         ///< perceptually motivated input-adaptive QP modification, abbrev. perceptual QP adaptation (QPA)
395
0
  c->m_sliceTypeAdapt                          = -1;            ///< perceptually and objectively motivated slice type adaptation (STA)
396
0
  c->m_minIntraDist                            = -1;
397
398
0
  c->m_RCNumPasses                             = -1;
399
0
  c->m_RCPass                                  = -1;
400
0
  c->m_LookAhead                               = -1;
401
402
0
  c->m_SegmentMode                             = VVENC_SEG_OFF;
403
404
0
  c->m_internalBitDepth[0]                     =10;                                 ///< bit-depth codec operates at (input/output files will be converted)
405
0
  c->m_internalBitDepth[1]                     =0;
406
407
0
  c->m_HdrMode                                 = VVENC_HDR_OFF;
408
409
  // expert options
410
0
  c->m_conformanceWindowMode                   = 1;
411
0
  c->m_confWinLeft                             = 0;
412
0
  c->m_confWinRight                            = 0;
413
0
  c->m_confWinTop                              = 0;
414
0
  c->m_confWinBottom                           = 0;
415
416
0
  c->m_PadSourceWidth                          = 0;                                     ///< source width in pixel
417
0
  c->m_PadSourceHeight                         = 0;                                     ///< source height in pixel (when interlaced = field height)
418
419
0
  c->m_maxPicWidth                             = 0;
420
0
  c->m_maxPicHeight                            = 0;
421
422
0
  memset(&c->m_aiPad,0, sizeof(c->m_aiPad));                                    ///< number of padded pixels for width and height
423
0
  c->m_enablePictureHeaderInSliceHeader        = true;
424
0
  c->m_AccessUnitDelimiter                     = -1;                                    ///< add Access Unit Delimiter NAL units, default: auto (only enable if needed by dependent options)
425
426
0
  c->m_printMSEBasedSequencePSNR               = false;
427
0
  c->m_printHexPsnr                            = false;
428
0
  c->m_printFrameMSE                           = false;
429
0
  c->m_printSequenceMSE                        = false;
430
0
  c->m_cabacZeroWordPaddingEnabled             = true;
431
432
0
  c->m_subProfile                              = 0;
433
0
  c->m_bitDepthConstraintValue                 = 10;
434
0
  c->m_intraOnlyConstraintFlag                 = false;
435
436
0
  c->m_rewriteParamSets                        = true;                                 ///< Flag to enable rewriting of parameter sets at random access points
437
0
  c->m_idrRefParamList                         = false;                                 ///< indicates if reference picture list syntax elements are present in slice headers of IDR pictures
438
0
  for( i = 0; i < VVENC_MAX_GOP; i++ )
439
0
  {
440
0
    vvenc_GOPEntry_default( &c->m_GOPList[i]);                                          ///< the coding structure entries from the config file
441
0
  }
442
443
0
  c->m_useSameChromaQPTables                   = true;
444
445
0
  vvenc_ChromaQpMappingTableParams_default( &c->m_chromaQpMappingTableParams );
446
0
  c->m_intraQPOffset                           = 0;                                     ///< QP offset for intra slice (integer)
447
0
  c->m_lambdaFromQPEnable                      = false;                                 ///< enable flag for QP:lambda fix
448
449
0
  for( i = 0; i < VVENC_MAX_TLAYER; i++ )
450
0
  {
451
0
    c->m_adLambdaModifier[i] = 1.0;                                                     ///< Lambda modifier array for each temporal layer
452
0
    c->m_adIntraLambdaModifier[i] = 0.0;                                                ///< Lambda modifier for Intra pictures, one for each temporal layer. If size>temporalLayer, then use [temporalLayer], else if size>0, use [size()-1], else use m_adLambdaModifier.
453
0
  }
454
455
0
  c->m_dIntraQpFactor                          = -1.0;                                  ///< Intra Q Factor. If negative, use a default equation: 0.57*(1.0 - Clip3( 0.0, 0.5, 0.05*(double)(isField ? (GopSize-1)/2 : GopSize-1) ))
456
457
0
  memset(&c->m_qpInValsCb    ,0, sizeof(c->m_qpInValsCb));                      ///< qp input values used to derive the chroma QP mapping table
458
0
  memset(&c->m_qpInValsCr    ,0, sizeof(c->m_qpInValsCr));                      ///< qp input values used to derive the chroma QP mapping table
459
0
  memset(&c->m_qpInValsCbCr  ,0, sizeof(c->m_qpInValsCbCr));                      ///< qp input values used to derive the chroma QP mapping table
460
0
  memset(&c->m_qpOutValsCb   ,0, sizeof(c->m_qpOutValsCb));                      ///< qp output values used to derive the chroma QP mapping table
461
0
  memset(&c->m_qpOutValsCr   ,0, sizeof(c->m_qpOutValsCr));                      ///< qp output values used to derive the chroma QP mapping table
462
0
  memset(&c->m_qpOutValsCbCr ,0, sizeof(c->m_qpOutValsCbCr));                      ///< qp output values used to derive the chroma QP mapping table
463
464
0
  c->m_qpInValsCb[0] = 17;  c->m_qpInValsCb[1] = 22;  c->m_qpInValsCb[2] = 34;  c->m_qpInValsCb[3] = 42;
465
0
  c->m_qpOutValsCb[0] = 17; c->m_qpOutValsCb[1] = 23; c->m_qpOutValsCb[2] = 35; c->m_qpOutValsCb[3] = 39;
466
467
0
  c->m_cuQpDeltaSubdiv                         = -1;                                    ///< Maximum subdiv for CU luma Qp adjustment (0:default)
468
0
  c->m_cuChromaQpOffsetSubdiv                  = -1;                                    ///< If negative, then do not apply chroma qp offsets.
469
0
  c->m_chromaCbQpOffset                        = 0;                                     ///< Chroma Cb QP Offset (0:default)
470
0
  c->m_chromaCrQpOffset                        = 0;                                     ///< Chroma Cr QP Offset (0:default)
471
0
  c->m_chromaCbQpOffsetDualTree                = 0;                                     ///< Chroma Cb QP Offset for dual tree (overwrite m_chromaCbQpOffset for dual tree)
472
0
  c->m_chromaCrQpOffsetDualTree                = 0;                                     ///< Chroma Cr QP Offset for dual tree (overwrite m_chromaCrQpOffset for dual tree)
473
0
  c->m_chromaCbCrQpOffset                      = -1;                                    ///< QP Offset for joint Cb-Cr mode
474
0
  c->m_chromaCbCrQpOffsetDualTree              = 0;                                     ///< QP Offset for joint Cb-Cr mode (overwrite m_chromaCbCrQpOffset for dual tree)
475
0
  c->m_sliceChromaQpOffsetPeriodicity          = -1;                                    ///< Used in conjunction with Slice Cb/Cr QpOffsetIntraOrPeriodic. Use 0 (default) to disable periodic nature.
476
477
0
  memset(&c->m_sliceChromaQpOffsetIntraOrPeriodic,0, sizeof(c->m_sliceChromaQpOffsetIntraOrPeriodic));            ///< Chroma Cb QP Offset at slice level for I slice or for periodic inter slices as defined by SliceChromaQPOffsetPeriodicity. Replaces offset in the GOP table.
478
479
0
  c->m_usePerceptQPATempFiltISlice             = -1;                                    ///< Flag indicating if temporal high-pass filtering in visual activity calculation in QPA should (true) or shouldn't (false) be applied for I-slices
480
481
0
  c->m_lumaLevelToDeltaQPEnabled               = false;
482
0
  vvenc_WCGChromaQPControl_default( &c->m_cfgUnused24 );
483
484
0
  c->m_internChromaFormat                      = VVENC_NUM_CHROMA_FORMAT;
485
0
  c->m_useIdentityTableForNon420Chroma         = true;
486
0
  c->m_outputBitDepth[0]      = c->m_outputBitDepth[1]      = 0;                              ///< bit-depth of output file
487
0
  c->m_MSBExtendedBitDepth[0] = c->m_MSBExtendedBitDepth[1] = 0;                    ///< bit-depth of input samples after MSB extension
488
0
  c->m_costMode                                = VVENC_COST_STANDARD_LOSSY;                   ///< Cost mode to use
489
490
0
  c->m_decodedPictureHashSEIType               = VVENC_HASHTYPE_NONE;                         ///< Checksum mode for decoded picture hash SEI message
491
0
  c->m_bufferingPeriodSEIEnabled               = false;
492
0
  c->m_pictureTimingSEIEnabled                 = false;
493
0
  c->m_decodingUnitInfoSEIEnabled              = false;
494
495
0
  c->m_entropyCodingSyncEnabled                = -1;
496
0
  c->m_entryPointsPresent                      = true;
497
498
0
  c->m_CTUSize                                 = 128;
499
0
  c->m_MinQT[0] = c->m_MinQT[1] = 8;                                            ///< 0: I slice luma; 1: P/B slice; 2: I slice chroma
500
0
  c->m_MinQT[2] = 4;
501
0
  c->m_maxMTTDepth                             = 3;
502
0
  c->m_maxMTTDepthI                            = 3;
503
0
  c->m_maxMTTDepthIChroma                      = -1;
504
505
0
  c->m_maxBT[0]=32;  c->m_maxBT[1]=128;  c->m_maxBT[2]=64;
506
0
  c->m_maxTT[0]=32;  c->m_maxTT[1]=64;  c->m_maxTT[2]=32;
507
0
  c->m_dualITree                               = true;
508
0
  c->m_log2MaxTbSize                           = 6;
509
0
  c->m_log2MinCodingBlockSize                  = 2;
510
511
0
  c->m_bUseASR                                 = false;                                 ///< flag for using adaptive motion search range
512
0
  c->m_bUseHADME                               = true;                                  ///< flag for using HAD in sub-pel ME
513
0
  c->m_fastHad                                 = false;
514
0
  c->m_RDOQ                                    = 1;                                     ///< flag for using RD optimized quantization
515
0
  c->m_useRDOQTS                               = true;                                  ///< flag for using RD optimized quantization for transform skip
516
0
  c->m_useSelectiveRDOQ                        = false;                                 ///< flag for using selective RDOQ
517
518
0
  c->m_JointCbCrMode                           = false;
519
0
  c->m_cabacInitPresent                        = -1;
520
0
  c->m_useFastLCTU                             = false;
521
0
  c->m_usePbIntraFast                          = 0;
522
0
  c->m_useFastMrg                              = 0;
523
0
  c->m_useAMaxBT                               = -1;
524
0
  c->m_fastQtBtEnc                             = true;
525
0
  c->m_contentBasedFastQtbt                    = false;
526
0
  c->m_fastInterSearchMode                     = VVENC_FASTINTERSEARCH_MODE3;
527
0
  c->m_useEarlyCU                              = 0;
528
0
  c->m_useFastDecisionForMerge                 = true;
529
530
0
  c->m_bDisableIntraCUsInInterSlices           = false;
531
0
  c->m_bFastUDIUseMPMEnabled                   = true;
532
0
  c->m_bFastMEForGenBLowDelayEnabled           = true;
533
534
0
  c->m_MTSImplicit                             = false;
535
0
  c->m_TMVPModeId                              = 1;
536
0
  c->m_DepQuantEnabled                         = true;
537
0
  c->m_SignDataHidingEnabled                   = false;
538
539
0
  c->m_MIP                                     = false;
540
0
  c->m_useFastMIP                              = 0;
541
542
0
  c->m_maxNumMergeCand                         = 5;
543
0
  c->m_maxNumAffineMergeCand                   = 5;
544
0
  c->m_Geo                                     = 0;
545
0
  c->m_maxNumGeoCand                           = 5;
546
0
  c->m_FastIntraTools                          = 0;
547
0
  c->m_IntraEstDecBit                          = 1;
548
549
0
  c->m_motionEstimationSearchMethod            = VVENC_MESEARCH_DIAMOND;
550
0
  c->m_motionEstimationSearchMethodSCC         = 0;
551
0
  c->m_SearchRange                             = 96;
552
0
  c->m_bipredSearchRange                       = 4;
553
0
  c->m_minSearchWindow                         = 8;
554
0
  c->m_bClipForBiPredMeEnabled                 = false;
555
0
  c->m_bFastMEAssumingSmootherMVEnabled        = true;
556
0
  c->m_bIntegerET                              = false;
557
0
  c->m_fastSubPel                              = 0;
558
0
  c->m_meReduceTap                             = 0;
559
0
  c->m_SMVD                                    = 0;
560
0
  c->m_AMVRspeed                               = 0;
561
0
  c->m_LMChroma                                = false;
562
0
  c->m_horCollocatedChromaFlag                 = true;
563
0
  c->m_verCollocatedChromaFlag                 = false;
564
0
  c->m_MRL                                     = true;
565
0
  c->m_BDOF                                    = false;
566
0
  c->m_DMVR                                    = false;
567
0
  c->m_EDO                                     = 0;
568
0
  c->m_lumaReshapeEnable                       = 0;
569
0
  c->m_reshapeSignalType                       = 0;
570
0
  c->m_updateCtrl                              = 0;
571
0
  c->m_adpOption                               = 0;
572
0
  c->m_initialCW                               = 0;
573
0
  c->m_LMCSOffset                              = 0;
574
0
  vvenc_ReshapeCW_default( &c->m_reshapeCW );
575
0
  c->m_Affine                                  = 0;
576
0
  c->m_PROF                                    = false;
577
0
  c->m_AffineType                              = true;
578
0
  c->m_MMVD                                    = 0;
579
0
  c->m_MmvdDisNum                              = 6;
580
0
  c->m_allowDisFracMMVD                        = false;
581
0
  c->m_CIIP                                    = 0;
582
0
  c->m_SbTMVP                                  = false;
583
0
  c->m_SBT                                     = 0;
584
0
  c->m_LFNST                                   = 0;
585
0
  c->m_MTS                                     = 0;
586
0
  c->m_MTSIntraMaxCand                         = 3;
587
0
  c->m_ISP                                     = 0;
588
0
  c->m_TS                                      = 0;
589
0
  c->m_TSsize                                  = 3;
590
0
  c->m_useChromaTS                             = 0;
591
0
  c->m_useBDPCM                                = 0;
592
593
0
  c->m_rprEnabledFlag                          = -1;
594
0
  c->m_resChangeInClvsEnabled                  = false;
595
0
  c->m_craAPSreset                             = false;
596
0
  c->m_rprRASLtoolSwitch                       = false;
597
598
0
  c->m_IBCMode                                 = 0;
599
0
  c->m_IBCFastMethod                           = 1;
600
601
0
  c->m_BCW                                     = 0;
602
603
0
  c->m_FIMMode                                 = 0;
604
0
  c->m_FastInferMerge                          = 0;
605
606
0
  c->m_bLoopFilterDisable                      = false;
607
0
  c->m_loopFilterOffsetInPPS                   = true;
608
609
0
  memset(&c->m_loopFilterBetaOffsetDiv2,0, sizeof(c->m_loopFilterBetaOffsetDiv2));
610
0
  memset(&c->m_loopFilterTcOffsetDiv2,0, sizeof(c->m_loopFilterTcOffsetDiv2));
611
612
0
  c->m_bDisableLFCrossTileBoundaryFlag         = false;
613
0
  c->m_bDisableLFCrossSliceBoundaryFlag        = false;
614
615
0
  c->m_bUseSAO                                 = true;
616
0
  c->m_saoScc                                  = false;
617
0
  c->m_saoEncodingRate                         = -1.0;
618
0
  c->m_saoEncodingRateChroma                   = -1.0;
619
0
  c->m_log2SaoOffsetScale[0]=c->m_log2SaoOffsetScale[1] = 0;
620
0
  c->m_saoOffsetBitShift[0]=c->m_saoOffsetBitShift[1] = 0;
621
622
0
  c->m_decodingParameterSetEnabled             = false;
623
0
  c->m_vuiParametersPresent                    = -1;
624
0
  c->m_hrdParametersPresent                    = true;
625
0
  c->m_aspectRatioInfoPresent                  = false;
626
0
  c->m_aspectRatioIdc                          = 1;
627
0
  c->m_sarWidth                                = 0;
628
0
  c->m_sarHeight                               = 0;
629
0
  c->m_colourDescriptionPresent                = false;
630
0
  c->m_colourPrimaries                         = 2;
631
0
  c->m_transferCharacteristics                 = 2;
632
0
  c->m_matrixCoefficients                      = 2;
633
0
  c->m_chromaLocInfoPresent                    = -1;
634
0
  c->m_chromaSampleLocType                     = -1;
635
0
  c->m_overscanInfoPresent                     = false;
636
0
  c->m_overscanAppropriateFlag                 = false;
637
0
  c->m_videoFullRangeFlag                      = false;
638
639
0
  memset(&c->m_masteringDisplay,0, sizeof(c->m_masteringDisplay));
640
0
  memset(&c->m_contentLightLevel,0, sizeof(c->m_contentLightLevel));
641
0
  c->m_preferredTransferCharacteristics        = -1;
642
643
0
  c->m_alf                                     = false;
644
0
  c->m_alfSpeed                                = 0;
645
0
  c->m_useNonLinearAlfLuma                     = true;
646
0
  c->m_useNonLinearAlfChroma                   = true;
647
0
  c->m_maxNumAlfAlternativesChroma             = VVENC_MAX_NUM_ALF_ALTERNATIVES_CHROMA;
648
0
  c->m_ccalf                                   = false;
649
0
  c->m_alfTempPred                             = -1;
650
0
  c->m_alfUnitSize                             = -1;
651
652
0
  vvenc_vvencMCTF_default( &c->m_vvencMCTF );
653
654
0
  c->m_blockImportanceMapping                  = true;
655
656
0
  c->m_quantThresholdVal                       = -1;
657
0
  c->m_qtbttSpeedUp                            = 1;
658
0
  c->m_qtbttSpeedUpMode                        = 0;
659
0
  c->m_fastTTSplit                             = 0;
660
661
0
  c->m_fastLocalDualTreeMode                   = 0;
662
663
0
  c->m_maxParallelFrames                       = -1;
664
0
  c->m_ensureWppBitEqual                       = -1;
665
0
  c->m_tileParallelCtuEnc                      = true;
666
0
  c->m_ifpLines                                = -1;
667
0
  c->m_ifp                                     = -1;
668
0
  c->m_mtProfile                               =  0;
669
0
  c->m_numParallelGOPs                         =  0;
670
671
0
  c->m_picPartitionFlag                        = false;
672
0
  memset( c->m_tileColumnWidth, 0, sizeof(c->m_tileColumnWidth) );
673
0
  memset( c->m_tileRowHeight,   0, sizeof(c->m_tileRowHeight) );
674
0
  c->m_numExpTileCols                          = 1;
675
0
  c->m_numExpTileRows                          = 1;
676
0
  c->m_numTileCols                             = -1;
677
0
  c->m_numTileRows                             = -1;
678
0
  c->m_numSlicesInPic                          = 1;
679
680
0
  memset( c->m_summaryOutFilename    , '\0', sizeof(c->m_summaryOutFilename) );
681
0
  memset( c->m_summaryPicFilenameBase, '\0', sizeof(c->m_summaryPicFilenameBase) );
682
0
  c->m_summaryVerboseness                      = 0;
683
684
0
  c->m_listTracingChannels                     = false;
685
0
  memset( c->m_traceRule, '\0', sizeof(c->m_traceRule) );
686
0
  memset( c->m_traceFile, '\0', sizeof(c->m_traceFile) );
687
688
0
  c->m_numIntraModesFullRD                     = -1;
689
0
  c->m_reduceIntraChromaModesFullRD            = false;
690
691
0
  c->m_treatAsSubPic                           = false;
692
0
  c->m_explicitAPSid                           = 0;
693
694
0
  c->m_leadFrames                              = 0;
695
0
  c->m_trailFrames                             = 0;
696
697
0
  c->m_deblockLastTLayers                      = 0;
698
0
  c->m_addGOP32refPics                         = false;
699
0
  c->m_numRefPics                              = 0;
700
0
  c->m_numRefPicsSCC                           = -1;
701
702
0
  c->m_FirstPassMode                           = 0;
703
704
0
  c->m_forceScc                                = 0;
705
0
  c->m_GOPQPA                                  = -1;
706
707
0
  c->m_fga                                     = false;
708
709
0
  memset( c->m_reservedInt8, 0, sizeof(c->m_reservedInt8) );
710
0
  memset( c->m_reservedDouble, 0, sizeof(c->m_reservedDouble) );
711
712
  // init default preset
713
0
  vvenc_init_preset( c, vvencPresetMode::VVENC_MEDIUM );
714
0
}
715
716
static bool vvenc_confirmParameter ( vvenc_config *c, bool bflag, const char* message )
717
0
{
718
0
  if ( ! bflag )
719
0
    return false;
720
721
0
  vvenc::MsgLog msg(c->m_msgCtx,c->m_msgFnc);
722
0
  msg.log( VVENC_ERROR, "Parameter Check Error: %s\n", message );
723
724
0
  c->m_confirmFailed = true;
725
0
  return true;
726
0
}
727
728
VVENC_DECL bool vvenc_init_config_parameter( vvenc_config *c )
729
0
{
730
0
  c->m_confirmFailed = false;
731
732
  // check for valid base parameter
733
0
  vvenc_confirmParameter( c,  (c->m_SourceWidth <= 0 || c->m_SourceHeight <= 0), "Input resolution not set");
734
735
0
  vvenc_confirmParameter( c, c->m_inputBitDepth[0] < 8 || c->m_inputBitDepth[0] > 16,                    "InputBitDepth must be at least 8" );
736
0
  vvenc_confirmParameter( c, c->m_inputBitDepth[0] != 8 && c->m_inputBitDepth[0] != 10,                  "Input bitdepth must be 8 or 10 bit" );
737
0
  vvenc_confirmParameter( c, c->m_internalBitDepth[0] != 8 && c->m_internalBitDepth[0] != 10,            "Internal bitdepth must be 8 or 10 bit" );
738
739
0
  vvenc_confirmParameter( c, c->m_FrameRate <= 0,                                                        "Frame rate must be greater than 0" );
740
0
  vvenc_confirmParameter( c, c->m_FrameScale <= 0,                                                       "Frame scale must be greater than 0" );
741
0
  vvenc_confirmParameter( c, c->m_TicksPerSecond < -1 || c->m_TicksPerSecond == 0 || c->m_TicksPerSecond > 27000000, "TicksPerSecond must be in range from 1 to 27000000, or -1 for ticks per frame=1" );
742
743
0
  std::stringstream css;
744
0
  if ( c->m_FrameScale != 1  && c->m_FrameScale != 1001 && c->m_TicksPerSecond == VVENC_TICKS_PER_SEC_DEF )
745
0
  {
746
0
    double dFrameRate = c->m_FrameRate/(double)c->m_FrameScale;
747
0
    css << "Detected non-standard Frame Rate " << c->m_FrameRate << "/" << c->m_FrameScale;
748
0
    css << " (" << std::fixed << std:: setprecision(2) << dFrameRate <<  std::setprecision(-1) << " Hz).";
749
0
    css << " Default TicksPerSecond (" << VVENC_TICKS_PER_SEC_DEF << ") can not be used.";
750
751
0
    if ( c->m_FrameRate * c->m_FrameScale <= VVENC_TICKS_PER_SEC_DEF )
752
0
    {
753
0
      css << " possible TicksPerSecond: " << (c->m_FrameRate * c->m_FrameScale) << std::endl;
754
0
    }
755
0
    else
756
0
    {
757
0
      css << " cannot find a proper value for TicksPerSecond in the range (1-" << VVENC_TICKS_PER_SEC_DEF << ")" << std::endl;
758
0
    }
759
0
  }
760
0
  else
761
0
  {
762
0
    css << "TicksPerSecond must be a multiple of FrameRate/Framescale (" << c->m_FrameRate << "/" << c->m_FrameScale << "). Use 27000000 for NTSC content"  << std::endl;
763
0
  }
764
0
  vvenc_confirmParameter( c, ( c->m_TicksPerSecond > 0 && c->m_FrameRate > 0) && ((int64_t)c->m_TicksPerSecond*(int64_t)c->m_FrameScale)%c->m_FrameRate, css.str().c_str() );
765
766
767
0
  vvenc_confirmParameter( c, c->m_numThreads < -1 || c->m_numThreads > 256,                              "Number of threads out of range (-1 <= t <= 256)");
768
769
0
  vvenc_confirmParameter( c, c->m_IntraPeriod < -1,                                                      "IDR period (in frames) must be >= -1");
770
0
  vvenc_confirmParameter( c, c->m_IntraPeriodSec < 0,                                                    "IDR period (in seconds) must be >= 0");
771
772
0
  vvenc_confirmParameter( c, c->m_GOPSize < 1 || c->m_GOPSize > VVENC_MAX_GOP,                           "GOP Size must be between 1 and 64" );
773
0
  vvenc_confirmParameter( c, c->m_leadFrames < 0 || c->m_leadFrames > VVENC_MAX_GOP,                     "Lead frames exceeds supported range (0 to 64)" );
774
0
  vvenc_confirmParameter( c, c->m_trailFrames < 0 || c->m_trailFrames > VVENC_MCTF_RANGE,                "Trail frames exceeds supported range (0 to 6)" );
775
0
  vvenc_confirmParameter( c, c->m_sliceTypeAdapt < -1 || c->m_sliceTypeAdapt > 2,                        "Slice type adaptation (STA) invalid parameter given, range is (-1 .. 2)" );
776
0
  vvenc_confirmParameter( c, c->m_minIntraDist < -1,                                                     "Minimum intra distance cannot be smaller than -1" );
777
778
0
  if( VVENC_RC_OFF == c->m_RCTargetBitrate )
779
0
  {
780
0
    vvenc_confirmParameter( c, c->m_bufferingPeriodSEIEnabled, "Enabling bufferingPeriod SEI requires rate control" );
781
0
    vvenc_confirmParameter( c, c->m_pictureTimingSEIEnabled,   "Enabling pictureTiming SEI requires rate control" );
782
0
    vvenc_confirmParameter( c, c->m_RCMaxBitrate > 0 && c->m_RCMaxBitrate != INT32_MAX && !c->m_usePerceptQPA, "Enabling capped CQF requires PerceptQPA to be enabled" );
783
0
    vvenc_confirmParameter( c, c->m_RCMaxBitrate > 0 && c->m_RCInitialQP > 0, "Specifying an RCInitialQP value requires rate control" );
784
0
    vvenc_confirmParameter( c, c->m_RCMaxBitrate < 0, "Cannot specify a relative max rate when using CQF, please specify an absolute value" );
785
0
  }
786
0
  if( c->m_RCMaxBitrate == 0 )
787
0
  {
788
0
    c->m_RCMaxBitrate = INT32_MAX;
789
0
  }
790
0
  else if( c->m_RCMaxBitrate < 0 )
791
0
  {
792
0
    c->m_RCMaxBitrate = (int)(( -(int64_t)c->m_RCMaxBitrate * (int64_t)c->m_RCTargetBitrate + 8 ) >> 4);
793
0
  }
794
795
0
  vvenc_confirmParameter( c, c->m_HdrMode < VVENC_HDR_OFF || c->m_HdrMode > VVENC_SDR_BT470BG,  "Sdr/Hdr Mode must be in the range 0 - 8" );
796
797
0
  vvenc_confirmParameter( c, c->m_verbosity < VVENC_SILENT || c->m_verbosity > VVENC_DETAILS, "verbosity is out of range[0..6]" );
798
799
0
  vvenc_confirmParameter( c,  (c->m_numIntraModesFullRD < -1 || c->m_numIntraModesFullRD == 0 || c->m_numIntraModesFullRD > 3), "NumIntraModesFullRD must be -1 or between 1 and 3");
800
801
0
#if ! ENABLE_TRACING
802
0
  vvenc_confirmParameter( c, c->m_traceFile[0] != '\0', "trace file option '--tracefile' set, but encoder lib not compiled with tracing support, use make ... enable-tracing=1 or set ENABLE_TRACING" );
803
0
  vvenc_confirmParameter( c, c->m_traceRule[0] != '\0', "trace rule option '--tracerule' set, but encoder lib not compiled with tracing support, use make ... enable-tracing=1 or set ENABLE_TRACING" );
804
0
  vvenc_confirmParameter( c, c->m_listTracingChannels, "list trace channels option '--tracechannellist' set, but encoder lib not compiled with tracing support, use make ... enable-tracing=1 or set ENABLE_TRACING" );
805
0
#endif
806
807
0
  if ( c->m_confirmFailed )
808
0
  {
809
0
    return c->m_confirmFailed;
810
0
  }
811
812
  //
813
  // set a lot of dependent parameters
814
  //
815
816
0
  vvenc::MsgLog msg(c->m_msgCtx, c->m_msgFnc);
817
818
0
  if( c->m_FirstPassMode > 2 && c->m_RCTargetBitrate != 0 )
819
0
  {
820
    // lookahead will only be set to 0 later
821
0
    if( c->m_LookAhead > 0 || c->m_RCNumPasses == 1 || std::min( c->m_SourceWidth, c->m_SourceHeight ) < 720 ) 
822
0
    {
823
0
      c->m_FirstPassMode -= 2;  
824
      //msg.log( VVENC_NOTICE, "First pass spatial downsampling (FirstPassMode=3/4) cannot be used for single pass encoding and videos with resolution lower than 720p, changing FirstPassMode to %d!\n", c->m_FirstPassMode );
825
0
    }
826
0
  }
827
828
0
  const double d = (c->m_RCTargetBitrate != VVENC_RC_OFF ? 1.0 : 2.25) * (3840.0 * 2160.0) / double (c->m_SourceWidth * c->m_SourceHeight);
829
0
  const double f = 38183.5 * sqrt (0.5 + c->m_GOPSize / double (c->m_IntraPeriod < 0 ? INT32_MAX : c->m_GOPSize + std::max (c->m_GOPSize, (c->m_IntraPeriod == 0 && c->m_IntraPeriodSec > 0 ? (c->m_IntraPeriodSec * c->m_FrameRate) / c->m_FrameScale : c->m_IntraPeriod))));
830
0
  const int rcQP = (c->m_RCInitialQP > 0 ? std::min (vvenc::MAX_QP, c->m_RCInitialQP) : std::max (0, vvenc::MAX_QP_INIT_QPA - (c->m_FirstPassMode > 2 ? 4 : 2) - int (0.5 + sqrt ((d * std::max (0, c->m_RCTargetBitrate)) / 500000.0))));
831
832
  // TODO 2.0: make this an error
833
  //vvenc_confirmParameter( c, c->m_RCTargetBitrate != VVENC_RC_OFF && c->m_QP != VVENC_AUTO_QP && c->m_QP != VVENC_DEFAULT_QP, "Rate-control and QP based encoding are mutually exclusive!" );
834
835
0
  if( c->m_RCTargetBitrate != VVENC_RC_OFF && c->m_QP != VVENC_AUTO_QP && c->m_QP != rcQP )
836
0
  {
837
0
    if( c->m_QP != VVENC_DEFAULT_QP )
838
0
      msg.log( VVENC_WARNING, "Configuration warning: Rate control is enabled since a target bitrate is specified, ignoring QP value\n\n" );
839
0
    c->m_QP = VVENC_AUTO_QP;
840
0
  }
841
842
0
  if( c->m_QP == VVENC_AUTO_QP ) c->m_QP = ( c->m_RCTargetBitrate != VVENC_RC_OFF ? rcQP : VVENC_DEFAULT_QP );
843
844
0
  vvenc_confirmParameter( c, c->m_RCTargetBitrate == VVENC_RC_OFF && ( c->m_QP < 0 || c->m_QP > vvenc::MAX_QP ), "QP exceeds supported range (0 to 63)" );
845
846
0
  vvenc_confirmParameter( c, c->m_RCTargetBitrate != VVENC_RC_OFF && ( c->m_RCTargetBitrate < 0 || c->m_RCTargetBitrate > 800000000 ),  "TargetBitrate must be between 0 and 800000000" );
847
0
  vvenc_confirmParameter( c, c->m_RCTargetBitrate != VVENC_RC_OFF && (int64_t) c->m_RCMaxBitrate * 2 < (int64_t) c->m_RCTargetBitrate * 3, "MaxBitrate must be at least 1.5*TargetBitrate" );
848
0
  vvenc_confirmParameter( c, c->m_RCTargetBitrate != VVENC_RC_OFF && ( c->m_FirstPassMode < 0 || c->m_FirstPassMode > 4 ), "FirstPassMode must be 0, 1, 2, 3, or 4" );
849
850
0
  if( c->m_RCTargetBitrate == VVENC_RC_OFF && c->m_RCMaxBitrate > 0 )
851
0
  {
852
0
    bool mbrLowErr = ( (double)c->m_RCMaxBitrate < f * sqrt(c->m_FrameRate / (c->m_FrameScale * d)) );
853
0
    vvenc_confirmParameter( c, mbrLowErr, "Capped CQF is used and MaxBitrate is too low for specified Intra period and frame rate/scale" );
854
0
    if( ! mbrLowErr && c->m_RCMaxBitrate * std::max (3.0, d) < 18000.0 * pow (2.0, 15.323 - c->m_QP / 4.516) ) // one fifth of ICIP24 paper function
855
0
    {
856
0
      msg.log( VVENC_WARNING, "Configuration warning: Capped CQF is used and MaxBitrate is very low for specified QP! Increase MaxBitrate to improve visual quality.\n\n" );
857
0
    }
858
0
  }
859
860
0
  if ( c->m_internChromaFormat < 0 || c->m_internChromaFormat >= VVENC_NUM_CHROMA_FORMAT )
861
0
  {
862
0
    c->m_internChromaFormat = VVENC_CHROMA_420;
863
0
  }
864
865
0
  if( c->m_profile == vvencProfile::VVENC_PROFILE_AUTO )
866
0
  {
867
0
    const int maxBitDepth= std::max(c->m_internalBitDepth[0], c->m_internalBitDepth[c->m_internChromaFormat==vvencChromaFormat::VVENC_CHROMA_400 ? 0 : 1]);
868
869
0
    if (c->m_internChromaFormat==vvencChromaFormat::VVENC_CHROMA_400 || c->m_internChromaFormat==vvencChromaFormat::VVENC_CHROMA_420)
870
0
    {
871
0
      if (maxBitDepth<=10)
872
0
      {
873
0
        c->m_profile=vvencProfile::VVENC_MAIN_10;
874
0
      }
875
0
    }
876
0
    else if (c->m_internChromaFormat==vvencChromaFormat::VVENC_CHROMA_422 || c->m_internChromaFormat==vvencChromaFormat::VVENC_CHROMA_444)
877
0
    {
878
0
      if (maxBitDepth<=10)
879
0
      {
880
0
        c->m_profile=vvencProfile::VVENC_MAIN_10_444;
881
0
      }
882
0
    }
883
884
0
    if( c->m_framesToBeEncoded == 1 )
885
0
    {
886
0
      if( c->m_profile == vvencProfile::VVENC_MAIN_10     ) c->m_profile = vvencProfile::VVENC_MAIN_10_STILL_PICTURE;
887
0
      if( c->m_profile == vvencProfile::VVENC_MAIN_10_444 ) c->m_profile = vvencProfile::VVENC_MAIN_10_444_STILL_PICTURE;
888
0
    }
889
890
0
    vvenc_confirmParameter( c, c->m_profile == vvencProfile::VVENC_PROFILE_AUTO, "Unable to infer profile from input!" );
891
0
  }
892
893
0
  const vvencLevel maxLevel = vvenc::LevelTierFeatures::getMaxLevel( c->m_profile );
894
0
  if( c->m_level == vvencLevel::VVENC_LEVEL_AUTO )
895
0
  {
896
0
    c->m_level = vvenc::LevelTierFeatures::getLevelForInput( c->m_SourceWidth, c->m_SourceHeight, c->m_levelTier, c->m_FrameRate, c->m_FrameScale, c->m_RCTargetBitrate );
897
0
    vvenc_confirmParameter( c, c->m_level == vvencLevel::VVENC_LEVEL_AUTO || c->m_level == vvencLevel::VVENC_NUMBER_OF_LEVELS, "Unable to infer level from input!" );
898
0
    if( c->m_level > maxLevel )
899
0
    {
900
0
      msg.log( VVENC_WARNING, "The video dimensions (size/rate) exceed the allowed maximum throughput for the used profile!\n" );
901
0
      c->m_level = maxLevel;
902
0
    }
903
0
  }
904
0
  else
905
0
  {
906
0
    const vvencLevel inferedLevel = vvenc::LevelTierFeatures::getLevelForInput( c->m_SourceWidth, c->m_SourceHeight, c->m_levelTier, c->m_FrameRate, c->m_FrameScale, c->m_RCTargetBitrate );
907
0
    if( c->m_level < inferedLevel )
908
0
    {
909
0
      if( c->m_level == maxLevel )
910
0
        msg.log( VVENC_WARNING, "The level set is too low given the input dimensions (size/rate)!\n" );
911
0
      else
912
0
        vvenc_confirmParameter( c, c->m_level < inferedLevel, "The level set is too low given the input dimensions (size/rate)!" );
913
0
    }
914
0
  }
915
916
0
  {
917
0
    const vvenc::ProfileFeatures *profileFeatures = vvenc::ProfileFeatures::getProfileFeatures( c->m_profile );
918
0
    vvenc_confirmParameter( c, !profileFeatures, "Invalid profile!" );
919
0
    vvenc_confirmParameter( c, c->m_level == vvencLevel::VVENC_LEVEL15_5 && !profileFeatures->canUseLevel15p5, "The video dimensions (size/rate) exceed the allowed maximum throughput for the level/profile combination!" );
920
0
  }
921
922
0
  c->m_maxBT[0] = std::min( c->m_CTUSize, c->m_maxBT[0] );
923
0
  c->m_maxBT[1] = std::min( c->m_CTUSize, c->m_maxBT[1] );
924
0
  c->m_maxBT[2] = std::min( c->m_CTUSize, c->m_maxBT[2] );
925
926
0
  c->m_maxTT[0] = std::min( c->m_CTUSize, c->m_maxTT[0] );
927
0
  c->m_maxTT[1] = std::min( c->m_CTUSize, c->m_maxTT[1] );
928
0
  c->m_maxTT[2] = std::min( c->m_CTUSize, c->m_maxTT[2] );
929
930
0
  if( c->m_maxMTTDepthIChroma < 0 )
931
0
  {
932
0
    c->m_maxMTTDepthIChroma = c->m_maxMTTDepthI;
933
0
  }
934
935
  // rate control
936
0
  if( c->m_RCNumPasses < 0 )
937
0
  {
938
0
    c->m_RCNumPasses = ( c->m_RCPass > 0 ? 2 : 1 ); // single pass by default (SDK usage)
939
0
  }
940
0
  if ( c->m_LookAhead < 0 )
941
0
  {
942
0
    c->m_LookAhead = c->m_RCTargetBitrate > 0 && c->m_RCNumPasses == 1 ? 1 : 0;
943
0
  }
944
945
  // threading
946
0
  if( c->m_numThreads < 0 )
947
0
  {
948
0
    const int numCores = std::thread::hardware_concurrency();
949
0
    c->m_numThreads = getNumThreadsDefault( c );
950
0
    c->m_numThreads = std::min( c->m_numThreads, numCores );
951
0
  }
952
953
0
  initMultithreading( c );
954
955
0
  if( c->m_ensureWppBitEqual < 0 )       c->m_ensureWppBitEqual     = c->m_numThreads ?      1   : 0   ;
956
0
  if( c->m_useAMaxBT < 0 )               c->m_useAMaxBT             = c->m_numThreads ?      0   : 1   ;
957
0
  if( c->m_cabacInitPresent < 0 )        c->m_cabacInitPresent      = c->m_numThreads ?      0   : 1   ;
958
0
  if( c->m_alfTempPred < 0 )             c->m_alfTempPred           = c->m_ifp        ?      0   : 1   ;
959
0
  if( c->m_saoEncodingRate < 0.0 )       c->m_saoEncodingRate       = c->m_numThreads ?      0.0 : 0.75;
960
0
  if( c->m_saoEncodingRateChroma < 0.0 ) c->m_saoEncodingRateChroma = c->m_numThreads ?      0.0 : 0.5 ;
961
0
  if( c->m_maxParallelFrames < 0 )
962
0
  {
963
0
    c->m_maxParallelFrames = std::min( c->m_numThreads, 4 );
964
0
  }
965
966
0
  if( c->m_ifpLines > 0 && !c->m_ifp )
967
0
  {
968
0
    msg.log( VVENC_WARNING, "Given IFPLines=%d, but IFP is not enabled, reseting IFPLines to 0.\n", c->m_ifpLines );
969
0
  }
970
0
  c->m_ifpLines = !c->m_ifp ? 0: (c->m_ifpLines == -1 ? 2: c->m_ifpLines);
971
972
0
  if( c->m_alfUnitSize < 0 )
973
0
    c->m_alfUnitSize = c->m_CTUSize;
974
975
0
  if( c->m_ifp && c->m_alfUnitSize != c->m_CTUSize )
976
0
  {
977
0
    msg.log( VVENC_WARNING, "IFP is enabled. For better performance, AlfUnitSize is adjusted to the CTUSize.\n" );
978
0
    c->m_alfUnitSize = c->m_CTUSize;
979
0
  }
980
981
  // quantization threshold
982
0
  if( c->m_quantThresholdVal < 0 )
983
0
  {
984
0
    c->m_quantThresholdVal = 8;
985
0
  }
986
987
  /* rules for input, output and internal bitdepths as per help text */
988
0
  if (c->m_MSBExtendedBitDepth[0] == 0)
989
0
    c->m_MSBExtendedBitDepth  [0] = c->m_inputBitDepth      [0];
990
0
  if (c->m_MSBExtendedBitDepth[1] == 0)
991
0
    c->m_MSBExtendedBitDepth  [1] = c->m_MSBExtendedBitDepth[0];
992
0
  if (c->m_internalBitDepth   [0] == 0)
993
0
    c->m_internalBitDepth     [0] = c->m_MSBExtendedBitDepth[0];
994
0
  if (c->m_internalBitDepth   [1] == 0)
995
0
    c->m_internalBitDepth     [1] = c->m_internalBitDepth   [0];
996
0
  if (c->m_inputBitDepth      [1] == 0)
997
0
    c->m_inputBitDepth        [1] = c->m_inputBitDepth      [0];
998
0
  if (c->m_outputBitDepth     [0] == 0)
999
0
    c->m_outputBitDepth       [0] = c->m_internalBitDepth   [0];
1000
0
  if (c->m_outputBitDepth     [1] == 0)
1001
0
    c->m_outputBitDepth       [1] = c->m_outputBitDepth     [0];
1002
1003
0
  if( c->m_HdrMode == VVENC_HDR_OFF &&
1004
0
     (( c->m_masteringDisplay[0] != 0 && c->m_masteringDisplay[1] != 0 && c->m_masteringDisplay[8] != 0 && c->m_masteringDisplay[9] != 0 ) ||
1005
0
     ( c->m_contentLightLevel[0] != 0 && c->m_contentLightLevel[1] != 0 ) ) )
1006
0
  {
1007
    // enable hdr pq bt2020/bt709 mode (depending on set colour primaries)
1008
0
    c->m_HdrMode = c->m_colourPrimaries==9 ? VVENC_HDR_PQ_BT2020 : VVENC_HDR_PQ;
1009
0
  }
1010
1011
0
  if ( c->m_HdrMode != VVENC_HDR_OFF && c->m_HdrMode != VVENC_HDR_USER_DEFINED )
1012
0
  {
1013
    // VUI and SEI options
1014
0
    c->m_colourDescriptionPresent = true;                                // enable colour_primaries, transfer_characteristics and matrix_coefficients in vui
1015
0
    if( c->m_vuiParametersPresent < 0 )
1016
0
    {
1017
0
      c->m_vuiParametersPresent  = 1;                                    // enable vui only if not explicitly disabled
1018
0
    }
1019
0
  }
1020
1021
0
  if( c->m_HdrMode == VVENC_HDR_PQ || c->m_HdrMode == VVENC_HDR_PQ_BT2020 )
1022
0
  {
1023
0
    c->m_reshapeSignalType       = vvenc::RESHAPE_SIGNAL_PQ;
1024
0
    c->m_LMCSOffset              = 1;
1025
0
    c->m_useSameChromaQPTables   = false;
1026
0
    c->m_verCollocatedChromaFlag = true;
1027
1028
0
    vvenc_config cBaseCfg;
1029
0
    vvenc_config_default(&cBaseCfg);
1030
    // if qpInVal/qpOutVal are set to default value and not overwritten by user defined values, overwrite them with PQ/HLG specifc qp values
1031
0
    if( memcmp( c->m_qpInValsCb, cBaseCfg.m_qpInValsCb, sizeof( c->m_qpInValsCb ) ) == 0 )
1032
0
    {
1033
0
      memset(&c->m_qpInValsCb,0, sizeof(c->m_qpInValsCb));
1034
0
      std::vector<int>  qpInVals = { 13,20,36,38,43,54 };
1035
0
      std::copy(qpInVals.begin(), qpInVals.end(), c->m_qpInValsCb);
1036
0
    }
1037
0
    if( memcmp( c->m_qpOutValsCb, cBaseCfg.m_qpOutValsCb, sizeof( c->m_qpOutValsCb ) ) == 0 )
1038
0
    {
1039
0
      memset(&c->m_qpOutValsCb,0, sizeof(c->m_qpOutValsCb));
1040
0
      std::vector<int>  qpInVals = { 13,21,29,29,32,37 };
1041
0
      std::copy(qpInVals.begin(), qpInVals.end(), c->m_qpOutValsCb);
1042
0
    }
1043
0
    if( memcmp( c->m_qpInValsCr, cBaseCfg.m_qpInValsCr, sizeof( c->m_qpInValsCr ) ) == 0 )
1044
0
    {
1045
0
      memset(&c->m_qpInValsCr,0, sizeof(c->m_qpInValsCr));
1046
0
      std::vector<int>  qpInVals = { 13,20,37,41,44,54 };
1047
0
      std::copy(qpInVals.begin(), qpInVals.end(), c->m_qpInValsCr);
1048
0
    }
1049
0
    if( memcmp( c->m_qpOutValsCr, cBaseCfg.m_qpOutValsCr, sizeof( c->m_qpOutValsCr ) ) == 0 )
1050
0
    {
1051
0
      memset(&c->m_qpOutValsCr,0, sizeof(c->m_qpOutValsCr));
1052
0
      std::vector<int>  qpInVals = { 13,21,27,29,32,37 };
1053
0
      std::copy(qpInVals.begin(), qpInVals.end(), c->m_qpOutValsCr);
1054
0
    }
1055
0
    if( memcmp( c->m_qpInValsCbCr, cBaseCfg.m_qpInValsCbCr, sizeof( c->m_qpInValsCbCr ) ) == 0 )
1056
0
    {
1057
0
      memset(&c->m_qpInValsCbCr,0, sizeof(c->m_qpInValsCbCr));
1058
0
      std::vector<int>  qpInVals = { 12,21,41,43,54 };
1059
0
      std::copy(qpInVals.begin(), qpInVals.end(), c->m_qpInValsCbCr);
1060
0
    }
1061
0
    if( memcmp( c->m_qpOutValsCbCr, cBaseCfg.m_qpOutValsCbCr, sizeof( c->m_qpOutValsCbCr ) ) == 0 )
1062
0
    {
1063
0
      memset(&c->m_qpOutValsCbCr,0, sizeof(c->m_qpOutValsCbCr));
1064
0
      std::vector<int>  qpInVals = { 12,22,30,32,37 };
1065
0
      std::copy(qpInVals.begin(), qpInVals.end(), c->m_qpOutValsCbCr);
1066
0
    }
1067
1068
0
    c->m_transferCharacteristics = 16; // smpte2084 - HDR10
1069
0
    if( c->m_colourPrimaries == 2 )
1070
0
    {
1071
0
      c->m_colourPrimaries = c->m_HdrMode == VVENC_HDR_PQ_BT2020 ? 9 : 1; //  bt2020(9) : bt709 (1)
1072
0
    }
1073
0
    if( c->m_matrixCoefficients == 2 )
1074
0
    {
1075
0
      c->m_matrixCoefficients = c->m_HdrMode == VVENC_HDR_PQ_BT2020 ? 9 : 1; // bt2020nc : bt709
1076
0
    }
1077
0
  }
1078
0
  else if( c->m_HdrMode == VVENC_HDR_HLG || c->m_HdrMode == VVENC_HDR_HLG_BT2020 )
1079
0
  {
1080
0
    c->m_reshapeSignalType       = vvenc::RESHAPE_SIGNAL_HLG;
1081
0
    c->m_LMCSOffset              = 0;
1082
0
    c->m_useSameChromaQPTables   = true;
1083
0
    c->m_verCollocatedChromaFlag = true;
1084
1085
0
    vvenc_config cBaseCfg;
1086
0
    vvenc_config_default(&cBaseCfg);
1087
    // if qpInVal/qpOutVal are set to default value and not overwritten by user defined values, overwrite them with PQ/HLG specifc qp values
1088
0
    if( memcmp( c->m_qpInValsCb, cBaseCfg.m_qpInValsCb, sizeof( c->m_qpInValsCb ) ) == 0 )
1089
0
    {
1090
0
      std::vector<int>  qpVals = { 9, 23, 33, 42 };
1091
0
      std::copy(qpVals.begin(), qpVals.end(), c->m_qpInValsCb);
1092
0
    }
1093
0
    if( memcmp( c->m_qpOutValsCb, cBaseCfg.m_qpOutValsCb, sizeof( c->m_qpOutValsCb ) ) == 0 )
1094
0
    {
1095
0
      std::vector<int>  qpVals = { 9, 24, 33, 37 };
1096
0
      std::copy(qpVals.begin(), qpVals.end(), c->m_qpOutValsCb);
1097
0
    }
1098
1099
0
    if( c->m_colourPrimaries == 2 )
1100
0
    {
1101
0
      c->m_colourPrimaries = c->m_HdrMode == VVENC_HDR_HLG_BT2020 ? 9 : 1; //  bt2020(9) : bt709 (1)
1102
0
    }
1103
1104
0
    if( c->m_matrixCoefficients == 2 )
1105
0
    {
1106
0
      c->m_matrixCoefficients = c->m_HdrMode == VVENC_HDR_HLG_BT2020 ? 9 : 1; // bt2020nc : bt709
1107
0
    }
1108
1109
0
    if( c->m_transferCharacteristics == 2 )
1110
0
    {
1111
0
      c->m_transferCharacteristics = c->m_HdrMode == VVENC_HDR_HLG_BT2020 ? 14 : 1; // bt2020-10 : bt709
1112
0
    }
1113
1114
0
    if( c->m_preferredTransferCharacteristics < 0 )
1115
0
    {
1116
0
      c->m_preferredTransferCharacteristics = 18; // ARIB STD-B67 (HLG)
1117
0
    }
1118
0
  }
1119
0
  else if( c->m_HdrMode == VVENC_SDR_BT709 )
1120
0
  {
1121
0
    c->m_transferCharacteristics = 1;  // bt709
1122
0
    c->m_colourPrimaries         = 1;  // bt709
1123
0
    c->m_matrixCoefficients      = 1;  // bt709
1124
0
  }
1125
0
  else if( c->m_HdrMode == VVENC_SDR_BT2020 )
1126
0
  {
1127
0
    c->m_transferCharacteristics = 14; // bt2020-10
1128
0
    c->m_colourPrimaries         = 9;  // bt2020nc
1129
0
    c->m_matrixCoefficients      = 9;  // bt2020nc
1130
0
    c->m_verCollocatedChromaFlag = true; 
1131
0
  }
1132
0
  else if( c->m_HdrMode == VVENC_SDR_BT470BG )
1133
0
  {
1134
0
    c->m_transferCharacteristics = 5;  // bt470bg
1135
0
    c->m_colourPrimaries         = 5;  // bt470bg
1136
0
    c->m_matrixCoefficients      = 5;  // bt470bg
1137
0
  }
1138
1139
0
  if( c->m_preferredTransferCharacteristics < 0 )
1140
0
  {
1141
0
    c->m_preferredTransferCharacteristics = 0;
1142
0
  }
1143
1144
0
  if( c->m_AccessUnitDelimiter < 0 )
1145
0
  {
1146
0
    c->m_AccessUnitDelimiter = 0;
1147
0
  }
1148
1149
0
  if ( c->m_vuiParametersPresent < 0 )
1150
0
  {
1151
0
    c->m_vuiParametersPresent = 0;
1152
0
  }
1153
1154
0
  if( !c->m_aspectRatioInfoPresent && ( c->m_aspectRatioIdc > 0 || (c->m_sarWidth > 0 && c->m_sarHeight > 0 )))
1155
0
  {
1156
0
    c->m_aspectRatioInfoPresent = true;
1157
0
  }
1158
1159
0
  if ( c->m_vuiParametersPresent == 0 )
1160
0
  {
1161
0
    if( c->m_aspectRatioIdc > 1 ) c->m_vuiParametersPresent = 1;
1162
0
    if( c->m_colourPrimaries != 2 || c->m_matrixCoefficients != 2 || c->m_matrixCoefficients != 2 )
1163
0
    {
1164
0
      c->m_vuiParametersPresent = 1;
1165
0
      c->m_colourDescriptionPresent = true;
1166
0
    }
1167
0
  }
1168
1169
1170
0
  if( !c->m_overscanInfoPresent && c->m_overscanAppropriateFlag)
1171
0
  {
1172
0
    c->m_overscanInfoPresent = true;
1173
0
    c->m_vuiParametersPresent = 1;
1174
0
  }
1175
1176
0
  if( c->m_chromaSampleLocType < 0 )
1177
0
  {
1178
0
    if( c->m_horCollocatedChromaFlag )
1179
0
    {
1180
0
      if ( c->m_verCollocatedChromaFlag)
1181
0
        c->m_chromaSampleLocType = 2;
1182
0
      else
1183
0
        c->m_chromaSampleLocType = 0;
1184
0
    }
1185
0
    else
1186
0
    {
1187
0
      if ( c->m_verCollocatedChromaFlag)
1188
0
        c->m_chromaSampleLocType = 3;
1189
0
      else
1190
0
        c->m_chromaSampleLocType = 1;
1191
0
    }
1192
0
  }
1193
1194
0
  if ( c->m_chromaLocInfoPresent < 0 )
1195
0
  {
1196
0
    c->m_chromaLocInfoPresent = c->m_verCollocatedChromaFlag ? 1 : 0;
1197
0
  }
1198
1199
0
  switch ( c->m_conformanceWindowMode)
1200
0
  {
1201
0
  case 0:
1202
0
    {
1203
      // no conformance or padding
1204
0
      c->m_confWinLeft = c->m_confWinRight = c->m_confWinTop = c->m_confWinBottom = 0;
1205
0
      c->m_aiPad[1] = c->m_aiPad[0] = 0;
1206
0
      break;
1207
0
    }
1208
0
  case 1:
1209
0
    {
1210
      // automatic padding to minimum CU size
1211
0
      const int minCuSize = std::max( 1 << ( vvenc::MIN_CU_LOG2 + 1 ), 1 << c->m_log2MinCodingBlockSize );
1212
0
      if (c->m_SourceWidth % minCuSize)
1213
0
      {
1214
0
        c->m_aiPad[0] = c->m_confWinRight  = ((c->m_SourceWidth / minCuSize) + 1) * minCuSize - c->m_SourceWidth;
1215
0
      }
1216
0
      if (c->m_SourceHeight % minCuSize)
1217
0
      {
1218
0
        c->m_aiPad[1] =c->m_confWinBottom = ((c->m_SourceHeight / minCuSize) + 1) * minCuSize - c->m_SourceHeight;
1219
0
      }
1220
0
      break;
1221
0
    }
1222
0
  case 2:
1223
0
    {
1224
      //padding
1225
0
      c->m_confWinRight  = c->m_aiPad[0];
1226
0
      c->m_confWinBottom = c->m_aiPad[1];
1227
0
      break;
1228
0
    }
1229
0
  case 3:
1230
0
    {
1231
      // conformance
1232
0
      if( ( c->m_confWinLeft == 0 ) && ( c->m_confWinRight == 0 ) && ( c->m_confWinTop == 0 ) && ( c->m_confWinBottom == 0 ) )
1233
0
      {
1234
0
        msg.log( VVENC_WARNING, "Configuration warning: conformance window enabled, but all conformance window parameters set to zero\n\n" );
1235
0
      }
1236
0
      if( ( c->m_aiPad[1] != 0 ) || ( c->m_aiPad[0] != 0 ) )
1237
0
      {
1238
0
        msg.log( VVENC_WARNING, "Configuration warning: conformance window enabled, padding parameters will be ignored\n" );
1239
0
      }
1240
0
      c->m_aiPad[1] = c->m_aiPad[0] = 0;
1241
0
      break;
1242
0
    }
1243
0
  }
1244
0
  c->m_PadSourceWidth  = c->m_SourceWidth  + c->m_aiPad[0];
1245
0
  c->m_PadSourceHeight = c->m_SourceHeight + c->m_aiPad[1];
1246
1247
0
  for(uint32_t ch=0; ch < 2; ch++ )
1248
0
  {
1249
0
    if (c->m_saoOffsetBitShift[ch]<0)
1250
0
    {
1251
0
      if (c->m_internalBitDepth[ch]>10)
1252
0
      {
1253
0
        c->m_log2SaoOffsetScale[ch]=uint32_t(vvenc::Clip3<int>(0, c->m_internalBitDepth[ch]-10, int(c->m_internalBitDepth[ch]-10 + 0.165*c->m_QP - 3.22 + 0.5) ) );
1254
0
      }
1255
0
      else
1256
0
      {
1257
0
        c->m_log2SaoOffsetScale[ch]=0;
1258
0
      }
1259
0
    }
1260
0
    else
1261
0
    {
1262
0
      c->m_log2SaoOffsetScale[ch]=uint32_t(c->m_saoOffsetBitShift[ch]);
1263
0
    }
1264
0
  }
1265
1266
0
  c->m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag = c->m_useSameChromaQPTables;
1267
1268
0
  if (c->m_useIdentityTableForNon420Chroma && c->m_internChromaFormat != VVENC_CHROMA_420)
1269
0
  {
1270
0
    c->m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag = true;
1271
0
    memset(&c->m_qpInValsCb   ,0, sizeof(c->m_qpInValsCb));
1272
0
    memset(&c->m_qpInValsCr   ,0, sizeof(c->m_qpInValsCr));
1273
0
    memset(&c->m_qpInValsCbCr ,0, sizeof(c->m_qpInValsCbCr));
1274
0
    memset(&c->m_qpOutValsCb  ,0, sizeof(c->m_qpOutValsCb));
1275
0
    memset(&c->m_qpOutValsCr  ,0, sizeof(c->m_qpOutValsCr));
1276
0
    memset(&c->m_qpOutValsCbCr,0, sizeof(c->m_qpOutValsCbCr));
1277
0
  }
1278
1279
0
  std::vector<int> qpInValsCb  = vvenc_getQpValsAsVec( c->m_qpInValsCb );
1280
0
  std::vector<int> qpInValsCr = vvenc_getQpValsAsVec( c->m_qpInValsCr );
1281
0
  std::vector<int> qpInValsCbCr= vvenc_getQpValsAsVec( c->m_qpInValsCbCr );
1282
0
  std::vector<int> qpOutValsCb= vvenc_getQpValsAsVec( c->m_qpOutValsCb );
1283
0
  std::vector<int> qpOutValsCr= vvenc_getQpValsAsVec( c->m_qpOutValsCr );
1284
0
  std::vector<int> qpOutValsCbCr= vvenc_getQpValsAsVec( c->m_qpOutValsCbCr );
1285
1286
0
  c->m_chromaQpMappingTableParams.m_numQpTables = c->m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag? 1 : (c->m_JointCbCrMode ? 3 : 2);
1287
0
  c->m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[0] = (qpOutValsCb.size() > 1) ? (int)qpOutValsCb.size() - 2 : 0;
1288
0
  c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] = (qpOutValsCb.size() > 1) ? -26 + qpInValsCb[0] : 0;
1289
0
  for ( size_t i = 0; i < qpInValsCb.size() - 1; i++)
1290
0
  {
1291
0
    c->m_chromaQpMappingTableParams.m_deltaQpInValMinus1[0][i] = qpInValsCb[i + 1] - qpInValsCb[i] - 1;
1292
0
    c->m_chromaQpMappingTableParams.m_deltaQpOutVal[0][i] = qpOutValsCb[i + 1] - qpOutValsCb[i];
1293
0
  }
1294
0
  if (!c->m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag)
1295
0
  {
1296
0
    c->m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[1] = (qpOutValsCr.size() > 1) ? (int)qpOutValsCr.size() - 2 : 0;
1297
0
    c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] = (qpOutValsCr.size() > 1) ? -26 + qpInValsCr[0] : 0;
1298
0
    for (size_t i = 0; i < qpInValsCr.size() - 1; i++)
1299
0
    {
1300
0
      c->m_chromaQpMappingTableParams.m_deltaQpInValMinus1[1][i] = qpInValsCr[i + 1] - qpInValsCr[i] - 1;
1301
0
      c->m_chromaQpMappingTableParams.m_deltaQpOutVal[1][i] = qpOutValsCr[i + 1] - qpOutValsCr[i];
1302
0
    }
1303
0
    c->m_chromaQpMappingTableParams.m_numPtsInCQPTableMinus1[2] = (qpOutValsCbCr.size() > 1) ? (int)qpOutValsCbCr.size() - 2 : 0;
1304
0
    c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] = (qpOutValsCbCr.size() > 1) ? -26 + qpInValsCbCr[0] : 0;
1305
0
    for (size_t i = 0; i < qpInValsCbCr.size() - 1; i++)
1306
0
    {
1307
0
      c->m_chromaQpMappingTableParams.m_deltaQpInValMinus1[2][i] = qpInValsCbCr[i + 1] - qpInValsCbCr[i] - 1;
1308
0
      c->m_chromaQpMappingTableParams.m_deltaQpOutVal[2][i] = qpInValsCbCr[i + 1] - qpInValsCbCr[i];
1309
0
    }
1310
0
  }
1311
1312
0
  int fps = c->m_FrameRate/c->m_FrameScale;
1313
1314
0
  c->m_reshapeCW.rspFps     = fps;
1315
0
  c->m_reshapeCW.rspPicSize = c->m_PadSourceWidth*c->m_PadSourceHeight;
1316
0
  c->m_reshapeCW.rspFpsToIp = std::max(16, 16 * (int)(round((double)c->m_reshapeCW.rspFps/16.0)));
1317
0
  c->m_reshapeCW.updateCtrl = c->m_updateCtrl;
1318
0
  c->m_reshapeCW.adpOption  = c->m_adpOption;
1319
0
  c->m_reshapeCW.initialCW  = c->m_initialCW;
1320
1321
0
  if( c->m_DecodingRefreshType == VVENC_DRT_IDR_NO_RADL && c->m_poc0idr < 0 )
1322
0
  {
1323
0
    c->m_poc0idr = 1;
1324
0
  }
1325
1326
0
  if( c->m_DecodingRefreshType == VVENC_DRT_IDR2 )
1327
0
  {
1328
0
    msg.log( VVENC_WARNING, "Configuration warning: DecodingRefreshType IDR2 is deprecated\n\n" );
1329
0
    if( c->m_poc0idr < 0 )
1330
0
    {
1331
0
      c->m_poc0idr = 0;
1332
0
    }
1333
0
    vvenc_confirmParameter( c, c->m_poc0idr, "for using deprecated IDR2, POC0IDR has to be disabled" );
1334
0
    c->m_DecodingRefreshType = VVENC_DRT_IDR;
1335
0
  }
1336
1337
0
  if( c->m_rprEnabledFlag == -1 )
1338
0
  {
1339
0
    c->m_rprEnabledFlag = c->m_DecodingRefreshType == VVENC_DRT_CRA_CRE ? 2 : 0;
1340
0
  }
1341
1342
0
  vvenc_confirmParameter( c, c->m_rprEnabledFlag < -1 || c->m_rprEnabledFlag > 2, "RPR must be either -1, 0, 1 or 2" );
1343
0
  vvenc_confirmParameter( c, c->m_rprEnabledFlag == 2 && !( c->m_DecodingRefreshType == VVENC_DRT_CRA_CRE || c->m_DecodingRefreshType == VVENC_DRT_IDR_NO_RADL ), "for using RPR=2 constrained rasl encoding, DecodingRefreshType has to be set to VVENC_DRT_CRA_CRE or VVENC_DRT_IDR_NO_RADL" );
1344
1345
0
  if( c->m_rprEnabledFlag == 2 )
1346
0
  {
1347
0
    c->m_resChangeInClvsEnabled = true;
1348
0
    c->m_craAPSreset            = true;
1349
0
    c->m_rprRASLtoolSwitch      = true;
1350
0
  }
1351
1352
0
  if( c->m_maxPicWidth > 0 && c->m_maxPicHeight > 0 )
1353
0
  {
1354
0
    vvenc_confirmParameter( c, !c->m_rprEnabledFlag || !c->m_resChangeInClvsEnabled, "if max picture size is set, both RPR and resChangeInClvsEnabled have to be enabled" );
1355
0
  }
1356
1357
0
  if( c->m_IntraPeriod == 0 && c->m_IntraPeriodSec > 0 )
1358
0
  {
1359
0
    int idrPeriod = fps * c->m_IntraPeriodSec;
1360
0
    if( idrPeriod % c->m_GOPSize != 0 )
1361
0
    {
1362
0
      const int minGopSize = std::min( (fps * c->m_IntraPeriodSec), std::min( c->m_GOPSize, 8 ));   
1363
0
      if( idrPeriod < c->m_GOPSize )
1364
0
      {
1365
0
        if( (idrPeriod % minGopSize) != 0)
1366
0
        {
1367
0
          idrPeriod = (fps > minGopSize ) ? (idrPeriod - (minGopSize>>1)) : minGopSize;
1368
0
          while ( idrPeriod % minGopSize != 0 )
1369
0
          {
1370
0
            idrPeriod++;
1371
0
          }
1372
0
        }
1373
0
      }
1374
0
      else
1375
0
      {
1376
0
        int diff = idrPeriod % minGopSize;
1377
0
        if( diff < minGopSize >> 1 )
1378
0
        {
1379
0
          idrPeriod -= diff;
1380
0
        }
1381
0
        else
1382
0
        {
1383
0
          idrPeriod += (minGopSize - diff);
1384
0
        }
1385
0
      }
1386
0
    }
1387
0
    c->m_IntraPeriod = idrPeriod;
1388
0
  }
1389
1390
0
  if( c->m_IntraPeriod == 1 && c->m_poc0idr < 0 )
1391
0
  {
1392
0
    c->m_poc0idr = 1;
1393
0
  }
1394
1395
0
  if( c->m_IntraPeriod == 1 && c->m_GOPSize != 1 )
1396
0
  {
1397
    // TODO 2.0: make this an error
1398
0
    msg.log( VVENC_WARNING, "Configuration warning: IntraPeriod is 1, thus GOPSize is set to 1 too and given gop structures are resetted\n\n" );
1399
0
    c->m_GOPSize = 1;
1400
0
    for( int i = 0; i < VVENC_MAX_GOP; i++ )
1401
0
    {
1402
0
      vvenc_GOPEntry_default( &c->m_GOPList[i] );
1403
0
    }
1404
0
  }
1405
0
  vvenc_confirmParameter( c, c->m_IntraPeriod == 0, "intra period must not be equal 0" );
1406
1407
0
  if( c->m_IntraPeriod >= 16 && c->m_GOPSize >= 16 && c->m_IntraPeriod % c->m_GOPSize >= 1 && c->m_IntraPeriod % c->m_GOPSize <= 4 )
1408
0
  {
1409
0
    msg.log( VVENC_WARNING, "Configuration warning: setting IntraPeriod in the range of ( N * GOPSize + 1 ) .. ( N * GOPSize + 4 ), i.e. only a small distance above a multiple of the GOPSize, will lead to degraded results.\n" );
1410
0
    msg.log( VVENC_WARNING, "                       consider changing the IntraPeriod for better results. For optimal results, set the IntraPeriod to a multiple of GOPSize.\n\n" );
1411
0
  }
1412
1413
0
  if( c->m_GOPSize > 1 && c->m_GOPList[ 0 ].m_POC != -1  )
1414
0
  {
1415
0
    bool bPicReordering = false;
1416
0
    for( int i = 1; i < c->m_GOPSize; i++ )
1417
0
    {
1418
0
      if( c->m_GOPList[ i - 1 ].m_POC > c->m_GOPList[ i ].m_POC )
1419
0
      {
1420
0
        bPicReordering = true;
1421
0
        break;
1422
0
      }
1423
0
    }
1424
0
    vvenc_confirmParameter( c, ! c->m_picReordering && bPicReordering, "PicReordering disabled, but given GOP configuration uses picture reordering" );
1425
0
    if( c->m_picReordering && ! bPicReordering )
1426
0
    {
1427
0
      msg.log( VVENC_WARNING, "Configuration warning: PicReordering enabled, but not used in given GOP configuration, disabling PicReordering\n\n" );
1428
0
      c->m_picReordering = false;
1429
0
    }
1430
0
  }
1431
0
  if( !c->m_picReordering && c->m_poc0idr < 0 )
1432
0
  {
1433
0
    c->m_poc0idr = 1;
1434
0
  }
1435
0
  vvenc_confirmParameter( c, c->m_poc0idr != 1 && ( c->m_IntraPeriod == 1 || !c->m_picReordering ), "when POC 0 is not an IDR frame it is only possible for random access, for all intra and low delay encoding POC0IDR must be set!" );
1436
1437
  // slice type adaptation (STA)
1438
0
  if( c->m_sliceTypeAdapt < 0 )
1439
0
  {
1440
0
    c->m_sliceTypeAdapt = c->m_GOPSize > 8 ? 1 : 0;
1441
0
  }
1442
0
  vvenc_confirmParameter( c, c->m_GOPSize <= 8 && c->m_sliceTypeAdapt > 0, "Slice type adaptation for GOPSize <= 8 not supported" );
1443
1444
0
  if( c->m_minIntraDist < 0 )
1445
0
  {
1446
0
    if( c->m_sliceTypeAdapt > 0 )
1447
0
    {
1448
0
      c->m_minIntraDist = std::min( c->m_GOPSize, c->m_IntraPeriod );
1449
0
    }
1450
0
    else
1451
0
    {
1452
0
      c->m_minIntraDist = 0;
1453
0
    }
1454
0
  }
1455
0
  vvenc_confirmParameter( c, c->m_minIntraDist > 0 && c->m_sliceTypeAdapt == 0,               "STA: Setting a minimal intra distance only works with slice type adaptation enabled" );
1456
0
  vvenc_confirmParameter( c, c->m_minIntraDist > c->m_IntraPeriod && c->m_sliceTypeAdapt > 0, "STA: Minimal intra distance can not be larger than intra period" );
1457
0
  vvenc_confirmParameter( c, c->m_SegmentMode != VVENC_SEG_OFF && c->m_RCTargetBitrate > 0,   "Segment concatenation not available, when rate control is enabled" );
1458
0
  vvenc_confirmParameter( c, c->m_SegmentMode != VVENC_SEG_OFF && !c->m_RCTargetBitrate && c->m_RCMaxBitrate != INT32_MAX, "Segment concatenation not available, when capped CQF is enabled" );
1459
1460
  // set number of lead / trail frames in segment mode
1461
0
  const int keyFrameDist = c->m_IntraPeriod < 1                      ? c->m_GOPSize     : std::min( c->m_GOPSize, c->m_IntraPeriod );
1462
0
  const int staFrames    = c->m_sliceTypeAdapt                       ? keyFrameDist     : 0;
1463
0
  const int mctfFrames   = c->m_vvencMCTF.MCTF || c->m_usePerceptQPA ? VVENC_MCTF_RANGE : 0;
1464
0
  switch( c->m_SegmentMode )
1465
0
  {
1466
0
    case VVENC_SEG_FIRST:
1467
0
      c->m_leadFrames  = 0;
1468
0
      c->m_trailFrames = mctfFrames;
1469
0
      break;
1470
0
    case VVENC_SEG_MID:
1471
0
      c->m_leadFrames  = std::max( staFrames, mctfFrames );
1472
0
      c->m_trailFrames = mctfFrames;
1473
0
      c->m_poc0idr     = c->m_poc0idr < 0 ? 1 : c->m_poc0idr;
1474
0
      break;
1475
0
    case VVENC_SEG_LAST:
1476
0
      c->m_leadFrames  = std::max( staFrames, mctfFrames );
1477
0
      c->m_trailFrames = 0;
1478
0
      c->m_poc0idr     = c->m_poc0idr < 0 ? 1 : c->m_poc0idr;
1479
0
      break;
1480
0
    default:
1481
      // do nothing
1482
0
      break;
1483
0
  }
1484
0
  vvenc_confirmParameter( c, c->m_poc0idr <= 0 && (c->m_SegmentMode == VVENC_SEG_MID || c->m_SegmentMode == VVENC_SEG_LAST), "poc0idr needs to be enabled for segment modes 'mid' & 'last'" );
1485
1486
0
  vvenc_confirmParameter( c, c->m_trailFrames > 0 && c->m_framesToBeEncoded <= 0, "If number of trailing frames is given, the total number of frames to be encoded has to be set" );
1487
1488
0
  if( c->m_poc0idr < 0 )  // if poc0idr is still undefined, default to false
1489
0
  {
1490
0
    c->m_poc0idr = 0;
1491
0
  }
1492
0
  vvenc_confirmParameter( c, c->m_poc0idr != 0 && c->m_poc0idr != 1 , "poc0idr must be either 0 or 1" );
1493
1494
  //
1495
  // do some check and set of parameters next
1496
  //
1497
1498
0
  if ( c->m_lumaReshapeEnable )
1499
0
  {
1500
0
    if ( c->m_updateCtrl > 0 && c->m_adpOption > 2 ) { c->m_adpOption -= 2; }
1501
0
  }
1502
1503
0
  if ( c->m_JointCbCrMode && ( c->m_internChromaFormat == VVENC_CHROMA_400 ) )
1504
0
  {
1505
0
    c->m_JointCbCrMode = false;
1506
0
  }
1507
1508
0
  if( c->m_vvencMCTF.MCTFUnitSize == -1 )
1509
0
  {
1510
0
    c->m_vvencMCTF.MCTFUnitSize = std::min( c->m_SourceWidth, c->m_SourceHeight ) < 720 ? 8 : 16;
1511
0
  }
1512
1513
0
  if ( c->m_vvencMCTF.MCTF && c->m_vvencMCTF.numFrames == 0 && c->m_vvencMCTF.numStrength == 0 )
1514
0
  {
1515
0
    const int log2GopSize = std::min<int>( 6, vvenc::floorLog2( c->m_GOPSize ) );
1516
1517
0
    c->m_vvencMCTF.numFrames = c->m_vvencMCTF.numStrength = std::max( 1, log2GopSize - ( ( c->m_QP - ( c->m_RCTargetBitrate > 0 ? 1 : 0 ) ) >> 4 ) );
1518
1519
0
    for ( int i = 0; i < c->m_vvencMCTF.numFrames; i++ )
1520
0
    {
1521
0
      c->m_vvencMCTF.MCTFFrames[i] = c->m_GOPSize >> ( c->m_vvencMCTF.numFrames - i - 1 );
1522
0
      c->m_vvencMCTF.MCTFStrengths[i] = vvenc::Clip3( 0.0, 2.0, ( c->m_QP - 4.0 ) / 8.0 ) / double ( c->m_vvencMCTF.numFrames - i );
1523
0
    }
1524
0
    c->m_vvencMCTF.MCTFStrengths[c->m_vvencMCTF.numFrames - 1] = vvenc::Clip3( 0.0, 1.5, ( c->m_QP - 4.0 ) * 3.0 / 32.0 );
1525
0
  }
1526
1527
0
  vvenc_confirmParameter( c, c->m_blockImportanceMapping && !c->m_vvencMCTF.MCTF, "BIM (block importance mapping) cannot be enabled when MCTF is disabled!" );
1528
0
  vvenc_confirmParameter( c, c->m_blockImportanceMapping && c->m_vvencMCTF.MCTFUnitSize > c->m_CTUSize, "MCTFUnitSize cannot exceed CTUSize if BIM is enabled!" );
1529
1530
0
  bool disableF2O = c->m_usePerceptQPATempFiltISlice < -1;
1531
0
  if ( c->m_usePerceptQPATempFiltISlice < 0 )
1532
0
  {
1533
0
    c->m_usePerceptQPATempFiltISlice = 0;
1534
0
    if ( c->m_usePerceptQPA ) // automatic mode for temporal filtering depending on RC
1535
0
    {
1536
0
      c->m_usePerceptQPATempFiltISlice = ( c->m_RCTargetBitrate > 0 && c->m_RCNumPasses == 2 ? 2 : 1 );
1537
0
    }
1538
0
  }
1539
0
  if ( c->m_usePerceptQPATempFiltISlice == 2
1540
0
      && ( c->m_QP <= 27 || c->m_QP > vvenc::MAX_QP_INIT_QPA || c->m_GOPSize <= 8 || c->m_IntraPeriod < 2 * c->m_GOPSize ) )
1541
0
  {
1542
0
    c->m_usePerceptQPATempFiltISlice = 1; // disable temporal pumping reduction aspect
1543
0
  }
1544
0
  if ( c->m_usePerceptQPATempFiltISlice > 0
1545
0
      && ( c->m_vvencMCTF.MCTF == 0 || ! c->m_usePerceptQPA ) )
1546
0
  {
1547
0
    c->m_usePerceptQPATempFiltISlice = 0; // fully disable temporal filtering features
1548
0
  }
1549
0
  if( disableF2O && c->m_usePerceptQPATempFiltISlice > 0 )
1550
0
  {
1551
0
    c->m_usePerceptQPATempFiltISlice += 2;
1552
0
  }
1553
1554
0
  if ( c->m_cuQpDeltaSubdiv < 0)
1555
0
  {
1556
0
    c->m_cuQpDeltaSubdiv = 0;
1557
0
    if ( c->m_usePerceptQPA
1558
0
        && c->m_QP <= vvenc::MAX_QP_INIT_QPA
1559
0
        && ( c->m_CTUSize == 128 || ( c->m_CTUSize == 64 && std::min( c->m_SourceWidth, c->m_SourceHeight ) < 720 ) )
1560
0
        && std::min( c->m_SourceWidth, c->m_SourceHeight ) <= 1280 )
1561
0
    {
1562
0
      c->m_cuQpDeltaSubdiv = 2;
1563
0
    }
1564
0
  }
1565
0
  vvenc_confirmParameter( c, c->m_sliceChromaQpOffsetPeriodicity < -1 || c->m_sliceChromaQpOffsetPeriodicity > 1, "Only values {-1, 0, 1} supported for SliceChromaQPOffsetPeriodicity" );
1566
0
  if ( c->m_sliceChromaQpOffsetPeriodicity < 0)
1567
0
  {
1568
0
    c->m_sliceChromaQpOffsetPeriodicity = 0;
1569
0
    if ( c->m_usePerceptQPA && c->m_internChromaFormat != VVENC_CHROMA_400 )
1570
0
    {
1571
0
      c->m_sliceChromaQpOffsetPeriodicity = 1;
1572
0
    }
1573
0
  }
1574
0
  if ( c->m_GOPQPA < 0 )
1575
0
  {
1576
0
    c->m_GOPQPA = c->m_usePerceptQPA ? 0 : 1;
1577
0
  }
1578
1579
0
  if( c->m_treatAsSubPic )
1580
0
  {
1581
0
    if( c->m_sliceTypeAdapt )    msg.log( VVENC_WARNING, "Configuration warning: combination of TreatAsSubPic and STA may not work with VTM subPicMerge tool, consider disabling STA\n\n" );
1582
0
    if( c->m_alfTempPred )       msg.log( VVENC_WARNING, "Configuration warning: disable ALF temporal prediction, when generation of subpicture streams is enabled (TreatAsSubPic)\n\n" );
1583
0
    if( c->m_JointCbCrMode )     msg.log( VVENC_WARNING, "Configuration warning: disable joint coding of chroma residuals, when generation of subpicture streams is enabled (TreatAsSubPic)\n\n" );
1584
0
    if( c->m_lumaReshapeEnable ) msg.log( VVENC_WARNING, "Configuration warning: disable LMCS luma mapping with chroma scaling, when generation of subpicture streams is enabled (TreatAsSubPic)\n\n" );
1585
0
    c->m_alfTempPred       = 0;
1586
0
    c->m_JointCbCrMode     = false;
1587
0
    c->m_lumaReshapeEnable = 0;
1588
0
    c->m_reshapeSignalType = 0;
1589
0
    c->m_updateCtrl        = 0;
1590
0
    c->m_adpOption         = 0;
1591
0
    c->m_initialCW         = 0;
1592
0
    c->m_LMCSOffset        = 0;
1593
0
    c->m_useAMaxBT         = 0;
1594
0
    vvenc_ReshapeCW_default( &c->m_reshapeCW );
1595
0
  }
1596
1597
0
  const bool autoGop = c->m_GOPList[0].m_POC;
1598
1599
0
  if( c->m_numRefPicsSCC < 0 )
1600
0
  {
1601
0
    c->m_numRefPicsSCC = c->m_numRefPics;
1602
0
  }
1603
1604
0
  if( c->m_GOPList[ 0 ].m_POC == -1 || ( c->m_addGOP32refPics && c->m_GOPSize == 32 ) )
1605
0
  {
1606
0
    if( c->m_IntraPeriod == 1 || c->m_GOPSize == 1 )
1607
0
    {
1608
0
      vvenc_confirmParameter( c, c->m_GOPSize != 1,     "gop auto configuration for all intra supports only gop size 1" );
1609
0
      vvenc_confirmParameter( c, c->m_IntraPeriod != 1, "gop auto configuration for gop size 1 supports only all intra" );
1610
      //                                    m_sliceType                m_QPOffsetModelOffset       m_temporalId   m_numRefPicsActive[ 0 ]            m_numRefPicsActive[ 1 ]
1611
      //                                     |      m_POC               |      m_QPOffsetModelScale |              |   m_deltaRefPics[ 0 ]            |   m_deltaRefPics[ 1 ]
1612
      //                                     |       |    m_QPOffset    |        |    m_QPFactor    |              |    |                             |    |
1613
0
      c->m_GOPList[  0 ] = vvenc::GOPEntry( 'I',     1,    0,           0.0,     0.0,  0.0,         0,             0,   { },                          0,   { } );
1614
0
    }
1615
0
    else if( c->m_GOPSize == 8 )
1616
0
    {
1617
0
      vvenc_confirmParameter( c, c->m_picReordering, "gop auto configuration for gop size 8 only without picture reordering supported" );
1618
      //                                    m_sliceType                m_QPOffsetModelOffset       m_temporalId   m_numRefPicsActive[ 0 ]            m_numRefPicsActive[ 1 ]
1619
      //                                     |      m_POC               |      m_QPOffsetModelScale |              |   m_deltaRefPics[ 0 ]            |   m_deltaRefPics[ 1 ]
1620
      //                                     |       |    m_QPOffset    |        |    m_QPFactor    |              |    |                             |    |
1621
0
      c->m_GOPList[  0 ] = vvenc::GOPEntry( 'B',     1,    5,         -6.5,   0.2590,  1.0,         0,             4,   { 1, 9, 17, 25 },             4,   { 1, 9, 17, 25 } );
1622
0
      c->m_GOPList[  1 ] = vvenc::GOPEntry( 'B',     2,    4,         -6.5,   0.2590,  1.0,         0,             4,   { 1, 2, 10, 18 },             4,   { 1, 2, 10, 18 } );
1623
0
      c->m_GOPList[  2 ] = vvenc::GOPEntry( 'B',     3,    5,         -6.5,   0.2590,  1.0,         0,             4,   { 1, 3, 11, 19 },             4,   { 1, 3, 11, 19 } );
1624
0
      c->m_GOPList[  3 ] = vvenc::GOPEntry( 'B',     4,    4,         -6.5,   0.2590,  1.0,         0,             4,   { 1, 4, 12, 20 },             4,   { 1, 4, 12, 20 } );
1625
0
      c->m_GOPList[  4 ] = vvenc::GOPEntry( 'B',     5,    5,         -6.5,   0.2590,  1.0,         0,             4,   { 1, 5, 13, 21 },             4,   { 1, 5, 13, 21 } );
1626
0
      c->m_GOPList[  5 ] = vvenc::GOPEntry( 'B',     6,    4,         -6.5,   0.2590,  1.0,         0,             4,   { 1, 6, 14, 22 },             4,   { 1, 6, 14, 22 } );
1627
0
      c->m_GOPList[  6 ] = vvenc::GOPEntry( 'B',     7,    5,         -6.5,   0.2590,  1.0,         0,             4,   { 1, 7, 15, 23 },             4,   { 1, 7, 15, 23 } );
1628
0
      c->m_GOPList[  7 ] = vvenc::GOPEntry( 'B',     8,    1,          0.0,      0.0,  1.0,         0,             4,   { 1, 8, 16, 24 },             4,   { 1, 8, 16, 24 } );
1629
0
    }
1630
0
    else if( c->m_GOPSize == 16 )
1631
0
    {
1632
      //                                    m_sliceType                m_QPOffsetModelOffset       m_temporalId   m_numRefPicsActive[ 0 ]            m_numRefPicsActive[ 1 ]
1633
      //                                     |      m_POC               |      m_QPOffsetModelScale |              |   m_deltaRefPics[ 0 ]            |   m_deltaRefPics[ 1 ]
1634
      //                                     |       |    m_QPOffset    |        |    m_QPFactor    |              |    |                             |    |
1635
0
      c->m_GOPList[  0 ] = vvenc::GOPEntry( 'B',    16,    1,           0.0,     0.0,  1.0,         0,             2,   { 16, 32, 24     },           2,   { 16,  32           } );
1636
0
      c->m_GOPList[  1 ] = vvenc::GOPEntry( 'B',     8,    1,       -4.8848,  0.2061,  1.0,         1,             2,   {  8, 16         },           2,   { -8,   8           } );
1637
0
      c->m_GOPList[  2 ] = vvenc::GOPEntry( 'B',     4,    4,       -5.7476,  0.2286,  1.0,         2,             2,   {  4, 12         },           2,   { -4, -12           } );
1638
0
      c->m_GOPList[  3 ] = vvenc::GOPEntry( 'B',     2,    5,         -5.90,  0.2333,  1.0,         3,             2,   {  2, 10         },           2,   { -2,  -6, -14      } );
1639
0
      c->m_GOPList[  4 ] = vvenc::GOPEntry( 'B',     1,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1, -1         },           2,   { -1,  -3,  -7, -15 } );
1640
0
      c->m_GOPList[  5 ] = vvenc::GOPEntry( 'B',     3,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1,  3         },           2,   { -1,  -5, -13      } );
1641
0
      c->m_GOPList[  6 ] = vvenc::GOPEntry( 'B',     6,    5,         -5.90,  0.2333,  1.0,         3,             2,   {  2,  6         },           2,   { -2, -10           } );
1642
0
      c->m_GOPList[  7 ] = vvenc::GOPEntry( 'B',     5,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1,  5         },           2,   { -1,  -3, -11      } );
1643
0
      c->m_GOPList[  8 ] = vvenc::GOPEntry( 'B',     7,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1,  3,  7     },           2,   { -1,  -9           } );
1644
0
      c->m_GOPList[  9 ] = vvenc::GOPEntry( 'B',    12,    4,       -5.7476,  0.2286,  1.0,         2,             2,   {  4, 12         },           2,   { -4,   4           } );
1645
0
      c->m_GOPList[ 10 ] = vvenc::GOPEntry( 'B',    10,    5,         -5.90,  0.2333,  1.0,         3,             2,   {  2, 10         },           2,   { -2,  -6           } );
1646
0
      c->m_GOPList[ 11 ] = vvenc::GOPEntry( 'B',     9,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1,  9         },           2,   { -1,  -3,  -7      } );
1647
0
      c->m_GOPList[ 12 ] = vvenc::GOPEntry( 'B',    11,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1,  3, 11     },           2,   { -1,  -5           } );
1648
0
      c->m_GOPList[ 13 ] = vvenc::GOPEntry( 'B',    14,    5,         -5.90,  0.2333,  1.0,         3,             2,   {  2,  6, 14     },           2,   { -2,   2           } );
1649
0
      c->m_GOPList[ 14 ] = vvenc::GOPEntry( 'B',    13,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1,  5, 13     },           2,   { -1,  -3           } );
1650
0
      c->m_GOPList[ 15 ] = vvenc::GOPEntry( 'B',    15,    6,       -7.1444,     0.3,  1.0,         4,             2,   {  1,  3,  7, 15 },           2,   { -1,   1           } );
1651
0
    }
1652
0
    else if( c->m_GOPSize == 32 )
1653
0
    {
1654
0
      if( !c->m_addGOP32refPics )
1655
0
      {
1656
        //                                    m_sliceType                m_QPOffsetModelOffset       m_temporalId   m_numRefPicsActive[ 0 ]            m_numRefPicsActive[ 1 ]
1657
        //                                     |      m_POC               |      m_QPOffsetModelScale |              |   m_deltaRefPics[ 0 ]            |   m_deltaRefPics[ 1 ]
1658
        //                                     |       |    m_QPOffset    |        |    m_QPFactor    |              |    |                             |    |
1659
0
        c->m_GOPList[  0 ] = vvenc::GOPEntry( 'B',    32,   -1,           0.0,     0.0,  1.0,         0,             2,   { 32, 64, 48     },           2,   {  32,  64                } );
1660
0
        c->m_GOPList[  1 ] = vvenc::GOPEntry( 'B',    16,    0,       -4.9309,  0.2265,  1.0,         1,             2,   { 16, 32         },           2,   { -16,  16                } );
1661
0
        c->m_GOPList[  2 ] = vvenc::GOPEntry( 'B',     8,    0,       -3.0625,  0.1875,  1.0,         2,             2,   {  8, 24         },           2,   {  -8, -24                } );
1662
0
        c->m_GOPList[  3 ] = vvenc::GOPEntry( 'B',     4,    3,       -5.4095,  0.2571,  1.0,         3,             2,   {  4, 20         },           2,   {  -4, -12, -28           } );
1663
0
        c->m_GOPList[  4 ] = vvenc::GOPEntry( 'B',     2,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2, 18         },           2,   {  -2,  -6, -14, -30      } );
1664
0
        c->m_GOPList[  5 ] = vvenc::GOPEntry( 'B',     1,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1, -1         },           2,   {  -1,  -3,  -7, -15, -31 } );
1665
0
        c->m_GOPList[  6 ] = vvenc::GOPEntry( 'B',     3,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3         },           2,   {  -1,  -5, -13, -29      } );
1666
0
        c->m_GOPList[  7 ] = vvenc::GOPEntry( 'B',     6,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2,  6         },           2,   {  -2, -10, -26           } );
1667
0
        c->m_GOPList[  8 ] = vvenc::GOPEntry( 'B',     5,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5         },           2,   {  -1,  -3, -11, -27      } );
1668
0
        c->m_GOPList[  9 ] = vvenc::GOPEntry( 'B',     7,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 7      },           2,   {  -1,  -9, -25           } );
1669
0
        c->m_GOPList[ 10 ] = vvenc::GOPEntry( 'B',    12,    3,       -5.4095,  0.2571,  1.0,         3,             2,   {  4, 12         },           2,   {  -4, -20                } );
1670
0
        c->m_GOPList[ 11 ] = vvenc::GOPEntry( 'B',    10,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2, 10         },           2,   {  -2,  -6, -22           } );
1671
0
        c->m_GOPList[ 12 ] = vvenc::GOPEntry( 'B',     9,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  9         },           2,   {  -1,  -3,  -7, -23      } );
1672
0
        c->m_GOPList[ 13 ] = vvenc::GOPEntry( 'B',    11,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 11     },           2,   {  -1,  -5, -21           } );
1673
0
        c->m_GOPList[ 14 ] = vvenc::GOPEntry( 'B',    14,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2,  6, 14     },           2,   {  -2, -18                } );
1674
0
        c->m_GOPList[ 15 ] = vvenc::GOPEntry( 'B',    13,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5, 13     },           2,   {  -1,  -3, -19           } );
1675
0
        c->m_GOPList[ 16 ] = vvenc::GOPEntry( 'B',    15,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 15     },           2,   {  -1, -17                } );
1676
0
        c->m_GOPList[ 17 ] = vvenc::GOPEntry( 'B',    24,    0,       -3.0625,  0.1875,  1.0,         2,             2,   {  8, 24         },           2,   {  -8,   8                } );
1677
0
        c->m_GOPList[ 18 ] = vvenc::GOPEntry( 'B',    20,    3,       -5.4095,  0.2571,  1.0,         3,             2,   {  4, 20         },           2,   {  -4, -12                } );
1678
0
        c->m_GOPList[ 19 ] = vvenc::GOPEntry( 'B',    18,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2, 18         },           2,   {  -2,  -6, -14           } );
1679
0
        c->m_GOPList[ 20 ] = vvenc::GOPEntry( 'B',    17,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1, 17         },           2,   {  -1,  -3,  -7, -15      } );
1680
0
        c->m_GOPList[ 21 ] = vvenc::GOPEntry( 'B',    19,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 19     },           2,   {  -1,  -5, -13           } );
1681
0
        c->m_GOPList[ 22 ] = vvenc::GOPEntry( 'B',    22,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2,  6, 22     },           2,   {  -2, -10                } );
1682
0
        c->m_GOPList[ 23 ] = vvenc::GOPEntry( 'B',    21,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5, 21     },           2,   {  -1,  -3, -11           } );
1683
0
        c->m_GOPList[ 24 ] = vvenc::GOPEntry( 'B',    23,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3,  7, 23 },           2,   {  -1,  -9                } );
1684
0
        c->m_GOPList[ 25 ] = vvenc::GOPEntry( 'B',    28,    3,       -5.4095,  0.2571,  1.0,         3,             2,   {  4, 12, 28     },           2,   {  -4,   4                } );
1685
0
        c->m_GOPList[ 26 ] = vvenc::GOPEntry( 'B',    26,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2, 10, 26     },           2,   {  -2,  -6                } );
1686
0
        c->m_GOPList[ 27 ] = vvenc::GOPEntry( 'B',    25,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  9, 25     },           2,   {  -1,  -3, -7            } );
1687
0
        c->m_GOPList[ 28 ] = vvenc::GOPEntry( 'B',    27,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 11, 27 },           2,   {  -1,  -5                } );
1688
0
        c->m_GOPList[ 29 ] = vvenc::GOPEntry( 'B',    30,    5,       -4.4895,  0.1947,  1.0,         4,             2,   {  2, 14, 30     },           2,   {  -2,   2                } );
1689
0
        c->m_GOPList[ 30 ] = vvenc::GOPEntry( 'B',    29,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1, 13, 29     },           2,   {  -1,  -3                } );
1690
0
        c->m_GOPList[ 31 ] = vvenc::GOPEntry( 'B',    31,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 15, 31 },           2,   {  -1,   1                } );
1691
0
      }
1692
0
      else
1693
0
      {
1694
0
        if( c->m_GOPList[ 0 ].m_POC != -1 )
1695
0
        {
1696
0
          msg.log( VVENC_WARNING, "Configuration warning: custom gop configuartion and option AddGOP32refPics detected, given gop configuration will be overwritten!\n\n" );
1697
0
        }
1698
        //overwrite GOPEntries
1699
0
        c->m_GOPList[  0 ] = vvenc::GOPEntry(  'B',   32,   -1,           0.0,     0.0,  1.0,         0,             2,   { 32, 64, 48, 40, 36 },       1,   {  32, 48                 } );
1700
0
        c->m_GOPList[  1 ] = vvenc::GOPEntry(  'B',   16,    0,       -4.9309,  0.2265,  1.0,         1,             3,   { 16, 32, 48, 24, 20 },       1,   { -16                     } );
1701
0
        c->m_GOPList[  2 ] = vvenc::GOPEntry(  'B',    8,    1,       -4.5000,  0.1900,  1.0,         2,             4,   {  8, 24, 16, 40, 12 },       2,   {  -8, -24                } );
1702
0
        c->m_GOPList[  3 ] = vvenc::GOPEntry(  'B',    4,    3,       -5.4095,  0.2571,  1.0,         3,             3,   {  4,  8, 20         },       3,   {  -4, -12, -28,          } );
1703
0
        c->m_GOPList[  4 ] = vvenc::GOPEntry(  'B',    2,    5,       -4.4895,  0.1947,  1.0,         4,             3,   {  2,  6, 18         },       4,   {  -2,  -6, -14, -30      } );
1704
0
        c->m_GOPList[  5 ] = vvenc::GOPEntry(  'B',    1,    6,       -5.4429,  0.2429,  1.0,         5,             1,   {  1                 },       2,   {  -1,  -3,  -7, -15, -31 } );
1705
0
        c->m_GOPList[  6 ] = vvenc::GOPEntry(  'B',    3,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3             },       2,   {  -1,  -5, -13, -29      } );
1706
0
        c->m_GOPList[  7 ] = vvenc::GOPEntry(  'B',    6,    5,       -4.4895,  0.1947,  1.0,         4,             3,   {  2,  4,  6         },       3,   {  -2, -10, -26           } );
1707
0
        c->m_GOPList[  8 ] = vvenc::GOPEntry(  'B',    5,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5             },       2,   {  -1,  -3, -11, -27      } );
1708
0
        c->m_GOPList[  9 ] = vvenc::GOPEntry(  'B',    7,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3,  7         },       2,   {  -1,  -9, -25           } );
1709
0
        c->m_GOPList[ 10 ] = vvenc::GOPEntry(  'B',   12,    3,       -5.4095,  0.2571,  1.0,         3,             3,   {  4,  8, 12,  6     },       2,   {  -4, -20                } );
1710
0
        c->m_GOPList[ 11 ] = vvenc::GOPEntry(  'B',   10,    5,       -4.4895,  0.1947,  1.0,         4,             4,   {  2,  4,  6, 10     },       3,   {  -2,  -6, -22           } );
1711
0
        c->m_GOPList[ 12 ] = vvenc::GOPEntry(  'B',    9,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5,  9         },       2,   {  -1,  -3,  -7, -23      } );
1712
0
        c->m_GOPList[ 13 ] = vvenc::GOPEntry(  'B',   11,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 11         },       2,   {  -1,  -5, -21           } );
1713
0
        c->m_GOPList[ 14 ] = vvenc::GOPEntry(  'B',   14,    5,       -4.4895,  0.1947,  1.0,         4,             4,   {  2,  4,  6, 14     },       2,   {  -2, -18                } );
1714
0
        c->m_GOPList[ 15 ] = vvenc::GOPEntry(  'B',   13,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5, 13         },       2,   {  -1,  -3, -19           } );
1715
0
        c->m_GOPList[ 16 ] = vvenc::GOPEntry(  'B',   15,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3,  7, 15     },       2,   {  -1, -17                } );
1716
0
        c->m_GOPList[ 17 ] = vvenc::GOPEntry(  'B',   24,    1,       -4.5000,  0.1900,  1.0,         2,             3,   {  8, 16, 24         },       1,   {  -8                     } );
1717
0
        c->m_GOPList[ 18 ] = vvenc::GOPEntry(  'B',   20,    3,       -5.4095,  0.2571,  1.0,         3,             3,   {  4, 12, 20         },       2,   {  -4, -12                } );
1718
0
        c->m_GOPList[ 19 ] = vvenc::GOPEntry(  'B',   18,    5,       -4.4895,  0.1947,  1.0,         4,             3,   {  2, 10, 18         },       3,   {  -2,  -6, -14           } );
1719
0
        c->m_GOPList[ 20 ] = vvenc::GOPEntry(  'B',   17,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  9, 17         },       2,   {  -1,  -3,  -7, -15      } );
1720
0
        c->m_GOPList[ 21 ] = vvenc::GOPEntry(  'B',   19,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 19         },       2,   {  -1,  -5, -13           } );
1721
0
        c->m_GOPList[ 22 ] = vvenc::GOPEntry(  'B',   22,    5,       -4.4895,  0.1947,  1.0,         4,             3,   {  2,  6, 22         },       3,   {  -2, -10, 4             } );
1722
0
        c->m_GOPList[ 23 ] = vvenc::GOPEntry(  'B',   21,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5, 21         },       2,   {  -1,  -3, -11           } );
1723
0
        c->m_GOPList[ 24 ] = vvenc::GOPEntry(  'B',   23,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3,  7, 23     },       2,   {  -1, -9                 } );
1724
0
        c->m_GOPList[ 25 ] = vvenc::GOPEntry(  'B',   28,    3,       -5.4095,  0.2571,  1.0,         3,             4,   {  4,  8, 12, 28     },       1,   {  -4                     } );
1725
0
        c->m_GOPList[ 26 ] = vvenc::GOPEntry(  'B',   26,    5,       -4.4895,  0.1947,  1.0,         4,             4,   {  2,  6, 10, 26     },       2,   {  -2, -6                 } );
1726
0
        c->m_GOPList[ 27 ] = vvenc::GOPEntry(  'B',   25,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5,  9, 25     },       2,   {  -1, -3, -7             } );
1727
0
        c->m_GOPList[ 28 ] = vvenc::GOPEntry(  'B',   27,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3, 11, 27     },       2,   {  -1, -5                 } );
1728
0
        c->m_GOPList[ 29 ] = vvenc::GOPEntry(  'B',   30,    5,       -4.4895,  0.1947,  1.0,         4,             4,   {  2,  6, 14, 30     },       1,   {  -2                     } );
1729
0
        c->m_GOPList[ 30 ] = vvenc::GOPEntry(  'B',   29,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  5, 13, 29     },       2,   {  -1, -3                 } );
1730
0
        c->m_GOPList[ 31 ] = vvenc::GOPEntry(  'B',   31,    6,       -5.4429,  0.2429,  1.0,         5,             2,   {  1,  3,  7, 15, 31 },       1,   {  -1                     } );
1731
0
      }
1732
0
    }
1733
0
    else
1734
0
    {
1735
0
      vvenc_confirmParameter( c, true, "GOP auto configuration only supported for GOP size (1,8,16,32)" );
1736
0
    }
1737
1738
0
    if( autoGop && c->m_numRefPics != 0 )
1739
0
    {
1740
0
      const int maxTLayer  = c->m_picReordering && c->m_GOPSize > 1 ? vvenc::ceilLog2( c->m_GOPSize ) : 0;
1741
0
      const int numRefCode = c->m_numRefPics;
1742
1743
0
      for( int i = 0; i < 64; i++ )
1744
0
      {
1745
0
        if( c->m_GOPList[i].m_POC == -1 ) break;
1746
1747
0
        int tLayer  = c->m_GOPList[i].m_temporalId;
1748
0
        int numRefs = numRefCode < 10 ? numRefCode : ( int( numRefCode / pow( 10, maxTLayer - tLayer ) ) % 10 );
1749
1750
0
        if( c->m_GOPList[i].m_sliceType != 'I' )
1751
0
          vvenc_confirmParameter( c, numRefs > c->m_GOPList[i].m_numRefPics[0], "Invalid number of references set in NumRefPics!" );
1752
0
        if( c->m_GOPList[i].m_sliceType == 'B' )
1753
0
          vvenc_confirmParameter( c, numRefs > c->m_GOPList[i].m_numRefPics[1], "Invalid number of references set in NumRefPics!" );
1754
0
        if( c->m_GOPList[i].m_sliceType != 'I' )
1755
0
          vvenc_confirmParameter( c, numRefs == 0, "Invalid number of references set in NumRefPics!" );
1756
0
      }
1757
0
    }
1758
1759
0
    if( autoGop && c->m_numRefPicsSCC != 0 )
1760
0
    {
1761
0
      const int maxTLayer  = c->m_picReordering && c->m_GOPSize > 1 ? vvenc::ceilLog2( c->m_GOPSize ) : 0;
1762
0
      const int numRefCode = c->m_numRefPicsSCC;
1763
1764
0
      for( int i = 0; i < 64; i++ )
1765
0
      {
1766
0
        if( c->m_GOPList[i].m_POC == -1 ) break;
1767
1768
0
        int tLayer  = c->m_GOPList[i].m_temporalId;
1769
0
        int numRefs = numRefCode < 10 ? numRefCode : ( int( numRefCode / pow( 10, maxTLayer - tLayer ) ) % 10 );
1770
1771
0
        if( c->m_GOPList[i].m_sliceType != 'I' )
1772
0
          vvenc_confirmParameter( c, numRefs > c->m_GOPList[i].m_numRefPics[0], "Invalid number of references set in NumRefPics!" );
1773
0
        if( c->m_GOPList[i].m_sliceType == 'B' )
1774
0
          vvenc_confirmParameter( c, numRefs > c->m_GOPList[i].m_numRefPics[1], "Invalid number of references set in NumRefPics!" );
1775
0
        if( c->m_GOPList[i].m_sliceType != 'I' )
1776
0
          vvenc_confirmParameter( c, numRefs == 0, "Invalid number of references set in NumRefPics!" );
1777
0
      }
1778
0
    }
1779
0
  }
1780
1781
0
  if (c->m_fga)
1782
0
  {
1783
0
    vvenc_confirmParameter( c, !c->m_vvencMCTF.MCTF, "Film grain analysis cannot be enabled when MCTF is disabled!");
1784
0
    vvenc_confirmParameter( c, c->m_IntraPeriod <=1, "Film grain analysis cannot be enabled when intra period is less than two!");
1785
0
  }
1786
1787
0
  vvenc_confirmParameter( c, !autoGop && c->m_numRefPics    != 0,                         "NumRefPics cannot be used if explicit GOP configuration is used!" );
1788
0
  vvenc_confirmParameter( c, !autoGop && c->m_numRefPicsSCC != 0,                         "NumRefPicsSCC cannot be used if explicit GOP configuration is used!" );
1789
0
  vvenc_confirmParameter( c, !autoGop && c->m_numRefPics    != 0 && c->m_addGOP32refPics, "NumRefPics and AddGOP32refPics options are mutually exclusive!" );
1790
0
  vvenc_confirmParameter( c, !autoGop && c->m_numRefPicsSCC != 0 && c->m_addGOP32refPics, "NumRefPicsSCC and AddGOP32refPics options are mutually exclusive!" );
1791
1792
0
  if ( ! c->m_MMVD && c->m_allowDisFracMMVD )
1793
0
  {
1794
0
    msg.log( VVENC_WARNING, "Configuration warning: MMVD disabled, thus disable AllowDisFracMMVD too\n\n" );
1795
0
    c->m_allowDisFracMMVD = false;
1796
0
  }
1797
1798
  //
1799
  // finalize initialization 
1800
  //
1801
1802
1803
0
  c->m_PROF &= bool(c->m_Affine);
1804
0
  if (c->m_Affine > 1)
1805
0
  {
1806
0
    c->m_PROF = bool(c->m_Affine);
1807
0
    c->m_AffineType = (c->m_Affine > 1) ? true : false;
1808
0
  }
1809
1810
  // check char array and reset them, if they seems to be unset
1811
0
  vvenc_checkCharArrayStr( c->m_traceRule, VVENC_MAX_STRING_LEN);
1812
0
  vvenc_checkCharArrayStr( c->m_traceFile, VVENC_MAX_STRING_LEN);
1813
0
  vvenc_checkCharArrayStr( c->m_summaryOutFilename, VVENC_MAX_STRING_LEN);
1814
0
  vvenc_checkCharArrayStr( c->m_summaryPicFilenameBase, VVENC_MAX_STRING_LEN);
1815
1816
0
  const int maxTLayer = c->m_picReordering && c->m_GOPSize > 1 ? vvenc::ceilLog2( c->m_GOPSize ) : 0;
1817
  
1818
0
  if( c->m_deblockLastTLayers > 0 )
1819
0
  {
1820
0
    if( maxTLayer > 0 )
1821
0
    {
1822
0
      vvenc_confirmParameter( c, c->m_bLoopFilterDisable, "DeblockLastTLayers can only be applied when deblocking filter is not disabled (LoopFilterDisable=0)" );
1823
0
      vvenc_confirmParameter( c, maxTLayer - c->m_deblockLastTLayers <= 0, "DeblockLastTLayers exceeds the range of possible deblockable temporal layers" );
1824
0
    }
1825
0
    c->m_loopFilterOffsetInPPS = false;
1826
0
  }
1827
1828
0
  if( c->m_alf )
1829
0
  {
1830
0
    if( c->m_alfSpeed > maxTLayer )
1831
0
    {
1832
0
      msg.log( VVENC_WARNING, "Configuration warning: ALFSpeed would disable ALF for the given GOP configuration, disabling ALFSpeed!\n\n" );
1833
1834
0
      c->m_alfSpeed = 0;
1835
0
    }
1836
0
  }
1837
1838
0
  c->m_configDone = true;
1839
1840
0
  c->m_confirmFailed = checkCfgParameter(c);
1841
1842
0
  return( c->m_confirmFailed );
1843
0
}
1844
1845
static bool checkCfgParameter( vvenc_config *c )
1846
0
{
1847
  // run base check first
1848
0
  vvenc_confirmParameter( c, c->m_profile == vvencProfile::VVENC_PROFILE_AUTO, "can not determin auto profile");
1849
0
  vvenc_confirmParameter( c, (c->m_profile != vvencProfile::VVENC_MAIN_10
1850
0
                           && c->m_profile != vvencProfile::VVENC_MAIN_10_STILL_PICTURE
1851
0
                           && c->m_profile != vvencProfile::VVENC_MAIN_10_444
1852
0
                           && c->m_profile != vvencProfile::VVENC_MAIN_10_444_STILL_PICTURE
1853
0
                           && c->m_profile != vvencProfile::VVENC_MULTILAYER_MAIN_10
1854
0
                           && c->m_profile != vvencProfile::VVENC_MULTILAYER_MAIN_10_STILL_PICTURE
1855
0
                           && c->m_profile != vvencProfile::  VVENC_MULTILAYER_MAIN_10_444
1856
0
                           && c->m_profile != vvencProfile::VVENC_MULTILAYER_MAIN_10_444_STILL_PICTURE),
1857
0
                              "unsupported profile. currently only supporting auto,main_10,main_10_still_picture");
1858
1859
0
  vvenc_confirmParameter( c, c->m_level   == vvencLevel::VVENC_LEVEL_AUTO, "can not determin level");
1860
1861
0
  vvenc_confirmParameter( c, c->m_fastInterSearchMode<VVENC_FASTINTERSEARCH_OFF || c->m_fastInterSearchMode>VVENC_FASTINTERSEARCH_MODE3,     "FastInterSearchMode parameter out of range [0...3]" );
1862
0
  vvenc_confirmParameter( c, c->m_motionEstimationSearchMethod < 0
1863
0
                          || c->m_motionEstimationSearchMethod >= VVENC_MESEARCH_NUMBER_OF_METHODS
1864
0
                          || c->m_motionEstimationSearchMethod == VVENC_MESEARCH_DEPRECATED,                                                 "FastSearch parameter out of range [0,1,3,4]");
1865
0
  vvenc_confirmParameter( c, c->m_motionEstimationSearchMethodSCC < 0
1866
0
                          || c->m_motionEstimationSearchMethodSCC == 1
1867
0
                          || c->m_motionEstimationSearchMethodSCC > 3,                                                                       "FastSearchSCC parameter out of range [0,2,3]" );
1868
0
  vvenc_confirmParameter( c, c->m_internChromaFormat > VVENC_CHROMA_420,                                                                     "Intern chroma format must be either 400, 420" );
1869
1870
0
  vvenc::MsgLog msg(c->m_msgCtx,c->m_msgFnc);
1871
1872
0
  switch ( c->m_conformanceWindowMode)
1873
0
  {
1874
0
  case 0:
1875
0
      break;
1876
0
  case 1:
1877
      // automatic padding to minimum CU size
1878
0
      vvenc_confirmParameter( c, c->m_aiPad[0] % vvenc::SPS::getWinUnitX(c->m_internChromaFormat) != 0, "picture width is not an integer multiple of the specified chroma subsampling" );
1879
0
      vvenc_confirmParameter( c, c->m_aiPad[1] % vvenc::SPS::getWinUnitY(c->m_internChromaFormat) != 0, "picture height is not an integer multiple of the specified chroma subsampling" );
1880
0
      break;
1881
0
  case 2:
1882
0
      break;
1883
0
  case 3:
1884
      // conformance
1885
0
      if ((c->m_confWinLeft == 0) && (c->m_confWinRight == 0) && (c->m_confWinTop == 0) && (c->m_confWinBottom == 0))
1886
0
      {
1887
0
        msg.log( VVENC_WARNING, "Configuration warning: Conformance window enabled, but all conformance window parameters set to zero\n\n" );
1888
0
      }
1889
0
      if ((c->m_aiPad[1] != 0) || (c->m_aiPad[0]!=0))
1890
0
      {
1891
0
        msg.log( VVENC_WARNING, "Configuration warning: Conformance window enabled, padding parameters will be ignored\n\n" );
1892
0
      }
1893
0
      break;
1894
0
  }
1895
1896
0
  vvenc_confirmParameter( c, c->m_colourPrimaries < 0 || c->m_colourPrimaries > 12,                 "colourPrimaries must be in range 0 <= x <= 12" );
1897
0
  vvenc_confirmParameter( c, c->m_transferCharacteristics < 0 || c->m_transferCharacteristics > 18, "transferCharacteristics must be in range 0 <= x <= 18" );
1898
0
  vvenc_confirmParameter( c, c->m_matrixCoefficients < 0 || c->m_matrixCoefficients > 14,           "matrixCoefficients must be in range 0 <= x <= 14" );
1899
1900
0
  vvenc_confirmParameter( c, vvenc_getQpValsSize(c->m_qpInValsCb )  != vvenc_getQpValsSize(c->m_qpOutValsCb), "Chroma QP table for Cb is incomplete.");
1901
0
  vvenc_confirmParameter( c, vvenc_getQpValsSize(c->m_qpInValsCr)   != vvenc_getQpValsSize(c->m_qpOutValsCr), "Chroma QP table for Cr is incomplete.");
1902
0
  vvenc_confirmParameter( c, vvenc_getQpValsSize(c->m_qpInValsCbCr) != vvenc_getQpValsSize(c->m_qpOutValsCbCr), "Chroma QP table for CbCr is incomplete.");
1903
1904
0
  if ( c->m_confirmFailed )
1905
0
  {
1906
0
    return c->m_confirmFailed;
1907
0
  }
1908
1909
0
  int qpBdOffsetC = 6 * (c->m_internalBitDepth[1] - 8);
1910
1911
0
  vvenc_confirmParameter( c,c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] < -26 - qpBdOffsetC || c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[0] > 36, "qpTableStartMinus26[0] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.");
1912
0
  vvenc_confirmParameter( c,c->m_qpInValsCb[0] != c->m_qpOutValsCb[0], "First qpInValCb value should be equal to first qpOutValCb value");
1913
0
  for (int i = 0; i < vvenc_getQpValsSize(c->m_qpInValsCb) - 1; i++)
1914
0
  {
1915
0
    vvenc_confirmParameter( c,c->m_qpInValsCb[i]  < -qpBdOffsetC || c->m_qpInValsCb[i] > vvenc::MAX_QP, "Some entries cfg_qpInValCb are out of valid range of -qpBdOffsetC to 63, inclusive.");
1916
0
    vvenc_confirmParameter( c,c->m_qpOutValsCb[i] < -qpBdOffsetC || c->m_qpOutValsCb[i] > vvenc::MAX_QP, "Some entries cfg_qpOutValCb are out of valid range of -qpBdOffsetC to 63, inclusive.");
1917
0
  }
1918
0
  if (!c->m_chromaQpMappingTableParams.m_sameCQPTableForAllChromaFlag)
1919
0
  {
1920
0
    vvenc_confirmParameter( c,c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] < -26 - qpBdOffsetC || c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[1] > 36, "qpTableStartMinus26[1] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.");
1921
0
    vvenc_confirmParameter( c,c->m_qpInValsCr[0] != c->m_qpOutValsCr[0], "First qpInValCr value should be equal to first qpOutValCr value");
1922
0
    for (int i = 0; i < vvenc_getQpValsSize(c->m_qpInValsCr) - 1; i++)
1923
0
    {
1924
0
      vvenc_confirmParameter( c,c->m_qpInValsCr[i] < -qpBdOffsetC || c->m_qpInValsCr[i] > vvenc::MAX_QP, "Some entries cfg_qpInValCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
1925
0
      vvenc_confirmParameter( c,c->m_qpOutValsCr[i] < -qpBdOffsetC || c->m_qpOutValsCr[i] > vvenc::MAX_QP, "Some entries cfg_qpOutValCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
1926
0
    }
1927
0
    vvenc_confirmParameter( c,c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] < -26 - qpBdOffsetC || c->m_chromaQpMappingTableParams.m_qpTableStartMinus26[2] > 36, "qpTableStartMinus26[2] is out of valid range of -26 -qpBdOffsetC to 36, inclusive.");
1928
0
    vvenc_confirmParameter( c,c->m_qpInValsCbCr[0] != c->m_qpOutValsCbCr[0], "First qpInValCbCr value should be equal to first qpOutValCbCr value");
1929
0
    for (int i = 0; i < vvenc_getQpValsSize(c->m_qpInValsCbCr) - 1; i++)
1930
0
    {
1931
0
      vvenc_confirmParameter( c,c->m_qpInValsCbCr[i]  < -qpBdOffsetC || c->m_qpInValsCbCr[i] > vvenc::MAX_QP, "Some entries cfg_qpInValCbCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
1932
0
      vvenc_confirmParameter( c,c->m_qpOutValsCbCr[i] < -qpBdOffsetC || c->m_qpOutValsCbCr[i] > vvenc::MAX_QP, "Some entries cfg_qpOutValCbCr are out of valid range of -qpBdOffsetC to 63, inclusive.");
1933
0
    }
1934
0
  }
1935
1936
  //
1937
  // do some check and set of parameters next
1938
  //
1939
1940
0
  vvenc_confirmParameter( c, c->m_AccessUnitDelimiter < 0,   "AccessUnitDelimiter must be >= 0" );
1941
0
  vvenc_confirmParameter( c, c->m_vuiParametersPresent < 0,  "vuiParametersPresent must be >= 0" );
1942
1943
0
  if( c->m_DepQuantEnabled )
1944
0
  {
1945
0
    vvenc_confirmParameter( c, !c->m_RDOQ || !c->m_useRDOQTS, "RDOQ and RDOQTS must be greater 0 if dependent quantization is enabled" );
1946
0
    vvenc_confirmParameter( c, c->m_SignDataHidingEnabled, "SignHideFlag must be equal to 0 if dependent quantization is enabled" );
1947
0
  }
1948
1949
0
  vvenc_confirmParameter( c, (c->m_MSBExtendedBitDepth[0] < c->m_inputBitDepth[0]), "MSB-extended bit depth for luma channel (--MSBExtendedBitDepth) must be greater than or equal to input bit depth for luma channel (--InputBitDepth)" );
1950
0
  vvenc_confirmParameter( c, (c->m_MSBExtendedBitDepth[1] < c->m_inputBitDepth[1]), "MSB-extended bit depth for chroma channel (--MSBExtendedBitDepthC) must be greater than or equal to input bit depth for chroma channel (--InputBitDepthC)" );
1951
1952
0
  const uint32_t maxBitDepth=(c->m_internChromaFormat==VVENC_CHROMA_400) ? c->m_internalBitDepth[0] : std::max(c->m_internalBitDepth[0], c->m_internalBitDepth[1]);
1953
0
  vvenc_confirmParameter( c,c->m_bitDepthConstraintValue<maxBitDepth, "The internalBitDepth must not be greater than the bitDepthConstraint value");
1954
1955
0
  vvenc_confirmParameter( c,c->m_bitDepthConstraintValue!=10, "BitDepthConstraint must be 8 for MAIN profile and 10 for MAIN10 profile.");
1956
0
  vvenc_confirmParameter( c,c->m_intraOnlyConstraintFlag==true, "IntraOnlyConstraintFlag must be false for non main_RExt profiles.");
1957
1958
  // check range of parameters
1959
0
  vvenc_confirmParameter( c, c->m_inputBitDepth[0  ] < 8,                                 "InputBitDepth must be at least 8" );
1960
0
  vvenc_confirmParameter( c, c->m_inputBitDepth[1] < 8,                                   "InputBitDepthC must be at least 8" );
1961
1962
0
  for (uint32_t channelType = 0; channelType < 2; channelType++)
1963
0
  {
1964
0
    vvenc_confirmParameter( c,(c->m_internalBitDepth[channelType] > 10) , "VVenC does not support internal bitdepth larger than 10!");
1965
0
  }
1966
1967
1968
0
  vvenc_confirmParameter( c, (isHDRMode(c->m_HdrMode) && c->m_internalBitDepth[0] < 10 )     ,       "InternalBitDepth must be at least 10 bit for HDR");
1969
0
  vvenc_confirmParameter( c, (isHDRMode(c->m_HdrMode) && c->m_internChromaFormat != VVENC_CHROMA_420 ) ,"ChromaFormatIDC must be YCbCr 4:2:0 for HDR");
1970
0
  vvenc_confirmParameter( c, (c->m_contentLightLevel[0] > 10000),  "max content light level must 0 <= cll <= 10000 ");
1971
0
  vvenc_confirmParameter( c, (c->m_contentLightLevel[1] > 10000),  "max average content light level must 0 <= cll <= 10000 ");
1972
1973
0
  {
1974
0
    bool outOfRGBRange = false;
1975
0
    for( size_t i = 0; i < sizeof(c->m_masteringDisplay); i++ )
1976
0
    {
1977
0
      if( i < 8 && c->m_masteringDisplay[i] > 50000 )
1978
0
      {
1979
0
        outOfRGBRange = true; break;
1980
0
      }
1981
0
    }
1982
0
    vvenc_confirmParameter( c, outOfRGBRange,  "mastering display colour volume RGB values must be in range 0 <= RGB <= 50000");
1983
0
  }
1984
1985
0
  vvenc_confirmParameter( c, c->m_log2SaoOffsetScale[0]   > (c->m_internalBitDepth[0  ]<10?0:(c->m_internalBitDepth[0  ]-10)), "SaoLumaOffsetBitShift must be in the range of 0 to InternalBitDepth-10, inclusive");
1986
0
  vvenc_confirmParameter( c, c->m_log2SaoOffsetScale[1] > (c->m_internalBitDepth[1]<10?0:(c->m_internalBitDepth[1]-10)), "SaoChromaOffsetBitShift must be in the range of 0 to InternalBitDepthC-10, inclusive");
1987
1988
0
  vvenc_confirmParameter( c, c->m_DecodingRefreshType < 0 || c->m_DecodingRefreshType > 6,                "Decoding refresh type must be comprised between 0 and 6 included" );
1989
0
  vvenc_confirmParameter( c, c->m_DecodingRefreshType == VVENC_DRT_IDR_NO_RADL && !c->m_poc0idr,          "Decoding refresh type VVENC_DRT_IDR_NO_RADL without POC0IDR not supported" );
1990
0
  vvenc_confirmParameter( c,   c->m_picReordering && (c->m_DecodingRefreshType == VVENC_DRT_NONE || c->m_DecodingRefreshType == VVENC_DRT_RECOVERY_POINT_SEI), "Decoding refresh type Recovery Point SEI for non low delay not supported" );
1991
0
  vvenc_confirmParameter( c, ! c->m_picReordering &&  c->m_DecodingRefreshType != VVENC_DRT_NONE,                                                              "Only decoding refresh type none for low delay supported" );
1992
1993
0
  vvenc_confirmParameter( c, c->m_QP < -6 * (c->m_internalBitDepth[0] - 8) || c->m_QP > vvenc::MAX_QP,                "QP exceeds supported range (-QpBDOffsety to 63)" );
1994
0
  for( int comp = 0; comp < 3; comp++)
1995
0
  {
1996
0
    vvenc_confirmParameter( c, c->m_loopFilterBetaOffsetDiv2[comp] < -12 || c->m_loopFilterBetaOffsetDiv2[comp] > 12,          "Loop Filter Beta Offset div. 2 exceeds supported range (-12 to 12)" );
1997
0
    vvenc_confirmParameter( c, c->m_loopFilterTcOffsetDiv2[comp] < -12 || c->m_loopFilterTcOffsetDiv2[comp] > 12,              "Loop Filter Tc Offset div. 2 exceeds supported range (-12 to 12)" );
1998
0
  }
1999
0
  vvenc_confirmParameter( c, c->m_SearchRange < 0 ,                                                         "Search Range must be more than 0" );
2000
0
  vvenc_confirmParameter( c, c->m_bipredSearchRange < 0 ,                                                   "Bi-prediction refinement search range must be more than 0" );
2001
0
  vvenc_confirmParameter( c, c->m_minSearchWindow < 0,                                                      "Minimum motion search window size for the adaptive window ME must be greater than or equal to 0" );
2002
2003
0
  vvenc_confirmParameter( c, c->m_vvencMCTF.MCTF > 2 || c->m_vvencMCTF.MCTF < 0,                    "MCTF out of range" );
2004
0
  vvenc_confirmParameter( c, c->m_vvencMCTF.numFrames != c->m_vvencMCTF.numStrength,                "MCTF parameter list sizes differ" );
2005
0
  vvenc_confirmParameter( c, c->m_vvencMCTF.MCTFSpeed < 0 || c->m_vvencMCTF.MCTFSpeed > 4,          "MCTFSpeed exceeds supported range (0..4)" );
2006
0
  vvenc_confirmParameter( c, c->m_vvencMCTF.MCTFUnitSize < 8,                                       "MCTFUnitSize is smaller than 8" );
2007
0
  vvenc_confirmParameter( c, c->m_vvencMCTF.MCTFUnitSize > 32,                                      "MCTFUnitSize is larger than 32" );
2008
0
  vvenc_confirmParameter( c, c->m_vvencMCTF.MCTFUnitSize & ( c->m_vvencMCTF.MCTFUnitSize - 1 ),     "MCTFUnitSize is not a power of 2" );
2009
0
  static const std::string errorSegLessRng = std::string( "When using segment parallel encoding more then " ) + static_cast< char >( VVENC_MCTF_RANGE + '0' ) + " frames have to be encoded";
2010
0
  vvenc_confirmParameter( c, c->m_SegmentMode != VVENC_SEG_OFF && c->m_SegmentMode != VVENC_SEG_LAST && c->m_framesToBeEncoded < VVENC_MCTF_RANGE, errorSegLessRng.c_str() );
2011
0
  for( int i = 0; i < c->m_vvencMCTF.numFrames; i++ )
2012
0
  {
2013
0
    vvenc_confirmParameter( c, c->m_vvencMCTF.MCTFFrames[ i ] <= 0, "MCTFFrame has to be greater then zero" );
2014
0
  }
2015
2016
0
  if (c->m_lumaReshapeEnable)
2017
0
  {
2018
0
    vvenc_confirmParameter( c, c->m_reshapeSignalType < vvenc::RESHAPE_SIGNAL_SDR || c->m_reshapeSignalType > vvenc::RESHAPE_SIGNAL_HLG, "LMCSSignalType out of range" );
2019
0
    vvenc_confirmParameter( c, c->m_updateCtrl < 0,    "Min. LMCS Update Control is 0");
2020
0
    vvenc_confirmParameter( c, c->m_updateCtrl > 2,    "Max. LMCS Update Control is 2");
2021
0
    vvenc_confirmParameter( c, c->m_adpOption < 0,     "Min. LMCS Adaptation Option is 0");
2022
0
    vvenc_confirmParameter( c, c->m_adpOption > 4,     "Max. LMCS Adaptation Option is 4");
2023
0
    vvenc_confirmParameter( c, c->m_initialCW < 0,     "Min. Initial Total Codeword is 0");
2024
0
    vvenc_confirmParameter( c, c->m_initialCW > 1023,  "Max. Initial Total Codeword is 1023");
2025
0
    vvenc_confirmParameter( c, c->m_LMCSOffset < -7,   "Min. LMCS Offset value is -7");
2026
0
    vvenc_confirmParameter( c, c->m_LMCSOffset > 7,    "Max. LMCS Offset value is 7");
2027
0
  }
2028
0
  vvenc_confirmParameter( c, c->m_EDO && c->m_bLoopFilterDisable,             "no EDO support with LoopFilter disabled" );
2029
0
  vvenc_confirmParameter( c, c->m_EDO < 0 || c->m_EDO > 2,                    "EDO out of range [0..2]" );
2030
0
  vvenc_confirmParameter( c, c->m_TMVPModeId < 0 || c->m_TMVPModeId > 2,      "TMVPMode out of range [0..2]" );
2031
0
  vvenc_confirmParameter( c, c->m_AMVRspeed < 0 || c->m_AMVRspeed > 7,        "AMVR/IMV out of range [0..7]" );
2032
0
  vvenc_confirmParameter( c, c->m_Affine < 0 || c->m_Affine > 5,              "Affine out of range [0..5]" );
2033
0
  vvenc_confirmParameter( c, c->m_MMVD < 0 || c->m_MMVD > 4,                  "MMVD out of range [0..4]" );
2034
0
  vvenc_confirmParameter( c, c->m_SMVD < 0 || c->m_SMVD > 3,                  "SMVD out of range [0..3]" );
2035
0
  vvenc_confirmParameter( c, c->m_Geo  < 0 || c->m_Geo  > 4,                  "Geo out of range [0..4]" );
2036
0
  vvenc_confirmParameter( c, c->m_CIIP < 0 || c->m_CIIP > 3,                  "CIIP out of range [0..3]" );
2037
0
  vvenc_confirmParameter( c, c->m_SBT  < 0 || c->m_SBT  > 3,                  "SBT out of range [0..3]" );
2038
0
  vvenc_confirmParameter( c, c->m_LFNST< 0 || c->m_LFNST> 3,                  "LFNST out of range [0..3]" );
2039
0
  vvenc_confirmParameter( c, c->m_vvencMCTF.MCTF < 0 || c->m_vvencMCTF.MCTF > 2,  "MCTF out of range [0..2]" );
2040
0
  vvenc_confirmParameter( c, c->m_ISP  < 0 || c->m_ISP > 3,                    "ISP out of range [0..3]" );
2041
0
  vvenc_confirmParameter( c, c->m_TS   < 0 || c->m_TS > 2,                     "TS out of range [0..2]" );
2042
0
  vvenc_confirmParameter( c, c->m_TSsize < 2 || c->m_TSsize > 5,               "TSsize out of range [2..5]" );
2043
0
  vvenc_confirmParameter( c, c->m_useBDPCM < 0 || c->m_useBDPCM > 2,           "BDPCM out of range [0..2]");
2044
0
  vvenc_confirmParameter( c, c->m_useBDPCM  && c->m_TS==0,                     "BDPCM cannot be used when transform skip is disabled" );
2045
0
  vvenc_confirmParameter( c, c->m_useBDPCM==1  && c->m_TS==2,                  "BDPCM cannot be permanently used when transform skip is auto" );
2046
0
  vvenc_confirmParameter( c, c->m_FastIntraTools <0 || c->m_FastIntraTools >2, "SpeedIntraTools out of range [0..2]");
2047
0
  vvenc_confirmParameter( c, c->m_IBCMode < 0 ||  c->m_IBCMode > 2,            "IBC out of range [0..2]");
2048
0
  vvenc_confirmParameter( c, c->m_IBCFastMethod < 0 ||  c->m_IBCFastMethod > 6,"IBCFastMethod out of range [0..6]");
2049
0
  vvenc_confirmParameter( c, c->m_BCW < 0 || c->m_BCW > 2,                     "BCW out of range [0..2]");
2050
0
  vvenc_confirmParameter( c, c->m_FIMMode < 0 || c->m_FIMMode > 4,             "FastInferMerge out of range [0..4]");
2051
0
  vvenc_confirmParameter( c, c->m_qtbttSpeedUp < 0 || c->m_qtbttSpeedUp > 7,   "QtbttExtraFast out of range [0..7]");
2052
0
  vvenc_confirmParameter( c, c->m_fastTTSplit < 0 || c->m_fastTTSplit > 7,     "FastTTSplit out of range [0..7]");
2053
0
  vvenc_confirmParameter( c, c->m_MTSIntraMaxCand < 0 || c->m_MTSIntraMaxCand > 4, "MTSIntraMaxCand out of range [0..4]");
2054
2055
0
  const int fimModeMap[] = { 0, 3, 19, 27, 29 };
2056
0
  const int maxTLayer = c->m_picReordering && c->m_GOPSize > 1 ? vvenc::ceilLog2( c->m_GOPSize ) : 0;
2057
0
  c->m_FastInferMerge = fimModeMap[ c->m_FIMMode ];
2058
0
  if( ( c->m_FastInferMerge & 7 ) > maxTLayer )
2059
0
  {
2060
0
    const int hbm = c->m_FastInferMerge >> 3;
2061
0
    const int lbm = std::min<int>( 7, maxTLayer );
2062
0
    c->m_FastInferMerge = ( hbm << 3 ) | lbm;
2063
0
  }
2064
2065
0
  c->m_qtbttSpeedUpMode = (c->m_qtbttSpeedUp > 2) ? (c->m_qtbttSpeedUp - 2) : 0;
2066
0
  const int QTBTSMModeMap[] = { 0, 1, 3, 4, 5, 7 };
2067
0
  c->m_qtbttSpeedUpMode = QTBTSMModeMap[c->m_qtbttSpeedUpMode];
2068
0
  static const float TT_THRESHOLDS[7] = { 1.1f, 1.075f, 1.05f, 1.025f, 1.0f,  0.975f, 0.95f };
2069
0
  c->m_fastTT_th = c->m_fastTTSplit ? TT_THRESHOLDS[c->m_fastTTSplit - 1] : 0;
2070
2071
0
  if( c->m_alf )
2072
0
  {
2073
0
    vvenc_confirmParameter( c, c->m_maxNumAlfAlternativesChroma < 1 || c->m_maxNumAlfAlternativesChroma > VVENC_MAX_NUM_ALF_ALTERNATIVES_CHROMA, std::string( std::string( "The maximum number of ALF Chroma filter alternatives must be in the range (1-" ) + std::to_string( VVENC_MAX_NUM_ALF_ALTERNATIVES_CHROMA ) + std::string( ", inclusive)" ) ).c_str() );
2074
0
  }
2075
2076
0
  vvenc_confirmParameter( c, c->m_useFastMrg < 0 || c->m_useFastMrg > 3,   "FastMrg out of range [0..3]" );
2077
0
  vvenc_confirmParameter( c, c->m_useFastMIP < 0 || c->m_useFastMIP > 3,   "FastMIP out of range [0..3]" );
2078
0
  vvenc_confirmParameter( c, c->m_fastSubPel < 0 || c->m_fastSubPel > 2,   "FastSubPel out of range [0..2]" );
2079
0
  vvenc_confirmParameter( c, c->m_useEarlyCU < 0 || c->m_useEarlyCU > 2,   "ECU out of range [0..2]" );
2080
0
  vvenc_confirmParameter( c, c->m_meReduceTap < 0 || c->m_meReduceTap > 2, "ReduceFilterME out of range [0..2]" );
2081
2082
0
  vvenc_confirmParameter( c, c->m_RCTargetBitrate == 0 && c->m_RCNumPasses != 1, "Only single pass encoding supported, when rate control is disabled" );
2083
0
  vvenc_confirmParameter( c, c->m_RCNumPasses < 1 || c->m_RCNumPasses > 2,       "Only one pass or two pass encoding supported" );
2084
0
  vvenc_confirmParameter( c, c->m_RCNumPasses < 2 && c->m_RCPass > 1,            "Only one pass supported in single pass encoding" );
2085
0
  vvenc_confirmParameter( c, c->m_RCPass != -1 && ( c->m_RCPass < 1 || c->m_RCPass > 2 ), "Invalid pass parameter, only -1, 1 or 2 supported" );
2086
0
  vvenc_confirmParameter( c, c->m_RCTargetBitrate > 0 && c->m_maxParallelFrames > 4, "Up to 4 parallel frames supported with rate control" );
2087
0
  vvenc_confirmParameter( c, c->m_LookAhead < -1 || c->m_LookAhead > 1,          "Look-ahead out of range [-1..1]" );
2088
0
  vvenc_confirmParameter( c, c->m_LookAhead && c->m_RCNumPasses != 1,       "Look-ahead encoding is not supported for two-pass rate control" );
2089
0
  vvenc_confirmParameter( c, !c->m_LookAhead && c->m_RCNumPasses == 1 && c->m_RCTargetBitrate > 0, "Look-ahead encoding must be used with one-pass rate control" );
2090
0
  vvenc_confirmParameter( c, c->m_LookAhead && c->m_RCTargetBitrate == 0,   "Look-ahead encoding is not supported when rate control is disabled" );
2091
2092
0
  vvenc_confirmParameter(c, !((c->m_level==VVENC_LEVEL1)
2093
0
    || (c->m_level==VVENC_LEVEL2) || (c->m_level==VVENC_LEVEL2_1)
2094
0
    || (c->m_level==VVENC_LEVEL3) || (c->m_level==VVENC_LEVEL3_1)
2095
0
    || (c->m_level==VVENC_LEVEL4) || (c->m_level==VVENC_LEVEL4_1)
2096
0
    || (c->m_level==VVENC_LEVEL5) || (c->m_level==VVENC_LEVEL5_1) || (c->m_level==VVENC_LEVEL5_2)
2097
0
    || (c->m_level==VVENC_LEVEL6) || (c->m_level==VVENC_LEVEL6_1) || (c->m_level==VVENC_LEVEL6_2) || (c->m_level==VVENC_LEVEL6_3)
2098
0
    || (c->m_level==VVENC_LEVEL15_5)), "invalid level selected");
2099
0
  vvenc_confirmParameter(c, !((c->m_levelTier==VVENC_TIER_MAIN) || (c->m_levelTier==VVENC_TIER_HIGH)), "invalid tier selected");
2100
2101
2102
0
  vvenc_confirmParameter( c, c->m_chromaCbQpOffset < -12,           "Min. Chroma Cb QP Offset is -12" );
2103
0
  vvenc_confirmParameter( c, c->m_chromaCbQpOffset >  12,           "Max. Chroma Cb QP Offset is  12" );
2104
0
  vvenc_confirmParameter( c, c->m_chromaCrQpOffset < -12,           "Min. Chroma Cr QP Offset is -12" );
2105
0
  vvenc_confirmParameter( c, c->m_chromaCrQpOffset >  12,           "Max. Chroma Cr QP Offset is  12" );
2106
0
  vvenc_confirmParameter( c, c->m_chromaCbQpOffsetDualTree < -12,   "Min. Chroma Cb QP Offset for dual tree is -12" );
2107
0
  vvenc_confirmParameter( c, c->m_chromaCbQpOffsetDualTree >  12,   "Max. Chroma Cb QP Offset for dual tree is  12" );
2108
0
  vvenc_confirmParameter( c, c->m_chromaCrQpOffsetDualTree < -12,   "Min. Chroma Cr QP Offset for dual tree is -12" );
2109
0
  vvenc_confirmParameter( c, c->m_chromaCrQpOffsetDualTree >  12,   "Max. Chroma Cr QP Offset for dual tree is  12" );
2110
2111
0
  if ( c->m_JointCbCrMode )
2112
0
  {
2113
0
    vvenc_confirmParameter( c, c->m_chromaCbCrQpOffset < -12, "Min. Joint Cb-Cr QP Offset is -12");
2114
0
    vvenc_confirmParameter( c, c->m_chromaCbCrQpOffset >  12, "Max. Joint Cb-Cr QP Offset is  12");
2115
0
    vvenc_confirmParameter( c, c->m_chromaCbCrQpOffsetDualTree < -12, "Min. Joint Cb-Cr QP Offset for dual tree is -12");
2116
0
    vvenc_confirmParameter( c, c->m_chromaCbCrQpOffsetDualTree >  12, "Max. Joint Cb-Cr QP Offset for dual tree is  12");
2117
0
  }
2118
2119
0
  if (c->m_usePerceptQPA && c->m_dualITree && (c->m_internChromaFormat != VVENC_CHROMA_400) && (c->m_chromaCbQpOffsetDualTree != 0 || c->m_chromaCrQpOffsetDualTree != 0 || c->m_chromaCbCrQpOffsetDualTree != 0))
2120
0
  {
2121
0
    msg.log( VVENC_WARNING, "Configuration warning: chroma QPA on, ignoring nonzero dual-tree chroma QP offsets!\n\n");
2122
0
  }
2123
2124
0
  vvenc_confirmParameter(c, c->m_usePerceptQPATempFiltISlice > 4,                                                       "PerceptQPATempFiltIPic out of range, must be 4 or less" );
2125
0
  vvenc_confirmParameter(c, c->m_usePerceptQPATempFiltISlice > 0 && c->m_vvencMCTF.MCTF == 0,                           "PerceptQPATempFiltIPic must be turned off when MCTF is off" );
2126
0
  vvenc_confirmParameter(c, c->m_SegmentMode != VVENC_SEG_OFF && c->m_usePerceptQPATempFiltISlice > 0 && c->m_usePerceptQPATempFiltISlice < 3, "Segmentwise encoding requires disabling of force 2nd order filter with PerceptQPATempFiltIPic set to 3 or 4"  );
2127
0
  vvenc_confirmParameter(c, ( c->m_leadFrames > 0 || c->m_trailFrames > 0 ) && c->m_usePerceptQPATempFiltISlice > 0 && c->m_usePerceptQPATempFiltISlice < 3, "Segmentwise encoding requires disabling of force 2nd order filter with PerceptQPATempFiltIPic set to 3 or 4"  );
2128
2129
0
  vvenc_confirmParameter(c, c->m_usePerceptQPA && (c->m_cuQpDeltaSubdiv > 2),                                           "MaxCuDQPSubdiv must be 2 or smaller when PerceptQPA is on" );
2130
2131
0
  vvenc_confirmParameter(c, c->m_MinQT[0] < 1<<vvenc::MIN_CU_LOG2,                                                      "Minimum QT size should be larger than or equal to 4");
2132
0
  vvenc_confirmParameter(c, c->m_MinQT[1] < 1<<vvenc::MIN_CU_LOG2,                                                      "Minimum QT size should be larger than or equal to 4");
2133
0
  vvenc_confirmParameter(c, c->m_CTUSize < 32,                                                                          "CTUSize must be greater than or equal to 32");
2134
0
  vvenc_confirmParameter(c, c->m_CTUSize > 128,                                                                         "CTUSize must be less than or equal to 128");
2135
0
  vvenc_confirmParameter(c, c->m_CTUSize != 32 && c->m_CTUSize != 64 && c->m_CTUSize != 128,                            "CTUSize must be a power of 2 (32, 64, or 128)");
2136
0
  vvenc_confirmParameter(c, (c->m_PadSourceWidth  % std::max( 8, 1 << c->m_log2MinCodingBlockSize )) != 0,              "Resulting coded frame width must be a multiple of Max(8, the minimum CU size)");
2137
0
  vvenc_confirmParameter(c, (c->m_PadSourceHeight % std::max( 8, 1 << c->m_log2MinCodingBlockSize )) != 0,              "Resulting coded frame width must be a multiple of Max(8, the minimum CU size)");
2138
0
  vvenc_confirmParameter(c, c->m_log2MaxTbSize > 6,                                                                     "Log2MaxTbSize must be 6 or smaller." );
2139
0
  vvenc_confirmParameter(c, c->m_log2MaxTbSize < 5,                                                                     "Log2MaxTbSize must be 5 or greater." );
2140
2141
0
  vvenc_confirmParameter( c, c->m_log2MinCodingBlockSize < 2,                                                           "Log2MinCodingBlockSize must be 2 or greater." );
2142
0
  vvenc_confirmParameter( c, c->m_CTUSize < ( 1 << c->m_log2MinCodingBlockSize ),                                       "Log2MinCodingBlockSize must be smaller than max CTU size." );
2143
0
  vvenc_confirmParameter( c, c->m_MinQT[ 0 ] < ( 1 << c->m_log2MinCodingBlockSize ),                                    "Log2MinCodingBlockSize must be greater than min QT size for I slices" );
2144
0
  vvenc_confirmParameter( c, c->m_MinQT[ 1 ] < ( 1 << c->m_log2MinCodingBlockSize ),                                    "Log2MinCodingBlockSize must be greater than min QT size for non I slices" );
2145
0
  const int chromaScaleX = ( (c->m_internChromaFormat==VVENC_CHROMA_444) ) ? 0 : 1;
2146
0
  vvenc_confirmParameter( c, ( c->m_MinQT[ 2 ] << chromaScaleX ) < ( 1 << c->m_log2MinCodingBlockSize ),                "Log2MinCodingBlockSize must be greater than min chroma QT size for I slices" );
2147
0
  vvenc_confirmParameter( c, c->m_dualITree && c->m_CTUSize == 128 && c->m_maxBT[0] == 128,                             "MaxBTLumaISlice has to be smaller than 128 if DualITree is enabled" );
2148
2149
0
  if( c->m_maxMTTDepth >= 10 && c->m_maxMTTDepth >= pow( 10, ( maxTLayer + 1 ) ) )
2150
0
  {
2151
0
    msg.log( VVENC_WARNING, "Configuration warning: MaxMTTHierarchyDepth>=10 & larger than maxTLayer\n\n" );
2152
0
  }
2153
0
  vvenc_confirmParameter(c, c->m_maxMTTDepth >= 10 && c->m_maxMTTDepth < pow(10, maxTLayer ), "MaxMTTHierarchyDepth>=10 & not set for all TLs");
2154
2155
0
  vvenc_confirmParameter(c, c->m_PadSourceWidth  % vvenc::SPS::getWinUnitX(c->m_internChromaFormat) != 0, "Picture width must be an integer multiple of the specified chroma subsampling");
2156
0
  vvenc_confirmParameter(c, c->m_PadSourceHeight % vvenc::SPS::getWinUnitY(c->m_internChromaFormat) != 0, "Picture height must be an integer multiple of the specified chroma subsampling");
2157
2158
0
  vvenc_confirmParameter(c, c->m_aiPad[0] % vvenc::SPS::getWinUnitX(c->m_internChromaFormat) != 0, "Horizontal padding must be an integer multiple of the specified chroma subsampling");
2159
0
  vvenc_confirmParameter(c, c->m_aiPad[1] % vvenc::SPS::getWinUnitY(c->m_internChromaFormat) != 0, "Vertical padding must be an integer multiple of the specified chroma subsampling");
2160
2161
0
  vvenc_confirmParameter(c, c->m_confWinLeft   % vvenc::SPS::getWinUnitX(c->m_internChromaFormat) != 0, "Left conformance window offset must be an integer multiple of the specified chroma subsampling");
2162
0
  vvenc_confirmParameter(c, c->m_confWinRight  % vvenc::SPS::getWinUnitX(c->m_internChromaFormat) != 0, "Right conformance window offset must be an integer multiple of the specified chroma subsampling");
2163
0
  vvenc_confirmParameter(c, c->m_confWinTop    % vvenc::SPS::getWinUnitY(c->m_internChromaFormat) != 0, "Top conformance window offset must be an integer multiple of the specified chroma subsampling");
2164
0
  vvenc_confirmParameter(c, c->m_confWinBottom % vvenc::SPS::getWinUnitY(c->m_internChromaFormat) != 0, "Bottom conformance window offset must be an integer multiple of the specified chroma subsampling");
2165
2166
0
  vvenc_confirmParameter(c, c->m_numThreads < 0,                                                  "NumThreads out of range" );
2167
0
  vvenc_confirmParameter(c, c->m_ensureWppBitEqual < 0       || c->m_ensureWppBitEqual > 1,       "WppBitEqual out of range (0,1)");
2168
0
  vvenc_confirmParameter(c, c->m_useAMaxBT < 0               || c->m_useAMaxBT > 1,               "AMaxBT out of range (0,1)");
2169
0
  vvenc_confirmParameter(c, c->m_cabacInitPresent < 0        || c->m_cabacInitPresent > 1,        "CabacInitPresent out of range (0,1)");
2170
0
  vvenc_confirmParameter(c, c->m_alfTempPred < 0             || c->m_alfTempPred > 1,             "ALFTempPred out of range (0,1)");
2171
2172
0
  vvenc_confirmParameter(c, c->m_alfUnitSize < c->m_CTUSize,                                      "ALF Unit Size must be greater than or equal to CTUSize");
2173
0
  vvenc_confirmParameter(c, c->m_alfUnitSize % c->m_CTUSize != 0,                                 "ALF Unit Size must be a multiple of CTUSize");
2174
2175
0
  vvenc_confirmParameter(c, c->m_alfSpeed < 0 || ( maxTLayer > 0 && c->m_alfSpeed > maxTLayer ),  "ALFSpeed out of range (0,log2(GopSize))" );
2176
0
  vvenc_confirmParameter(c, c->m_saoEncodingRate < 0.0       || c->m_saoEncodingRate > 1.0,       "SaoEncodingRate out of range [0.0 .. 1.0]");
2177
0
  vvenc_confirmParameter(c, c->m_saoEncodingRateChroma < 0.0 || c->m_saoEncodingRateChroma > 1.0, "SaoEncodingRateChroma out of range [0.0 .. 1.0]");
2178
0
  vvenc_confirmParameter(c, c->m_maxParallelFrames < 0,                                           "MaxParallelFrames out of range" );
2179
2180
0
  vvenc_confirmParameter(c, c->m_numThreads > 0 && c->m_ensureWppBitEqual == 0, "NumThreads > 0 requires WppBitEqual > 0");
2181
2182
0
  if( c->m_maxParallelFrames )
2183
0
  {
2184
0
    vvenc_confirmParameter(c, c->m_numThreads == 0,       "For frame parallel processing NumThreads > 0 is required" );
2185
0
    vvenc_confirmParameter(c, c->m_useAMaxBT,             "Frame parallel processing: AMaxBT is not supported (must be disabled)" );
2186
0
    vvenc_confirmParameter(c, c->m_cabacInitPresent,      "Frame parallel processing: CabacInitPresent is not supported (must be disabled)" );
2187
0
    vvenc_confirmParameter(c, c->m_saoEncodingRate > 0.0, "Frame parallel processing: SaoEncodingRate is not supported (must be disabled)" );
2188
#if ENABLE_TRACING
2189
    vvenc_confirmParameter(c, c->m_traceFile[0] != '\0' && c->m_maxParallelFrames > 1 && c->m_numThreads > 1, "Tracing and frame parallel encoding not supported" );
2190
#endif
2191
0
    vvenc_confirmParameter(c, c->m_maxParallelFrames > c->m_GOPSize && c->m_GOPSize != 1, "Max parallel frames should be less then GOP size" );
2192
0
    vvenc_confirmParameter(c, c->m_ifpLines && c->m_alfTempPred != 0, "IFP: ALFTempPred is not supported (must be disabled)" );
2193
0
    vvenc_confirmParameter(c, c->m_ifpLines && c->m_numTileRows > 1,  "IFP: Only single tile row is supported" );
2194
0
    vvenc_confirmParameter(c, c->m_ifpLines < 0, "IFPLines must be >= 0" );
2195
0
    vvenc_confirmParameter(c, c->m_ifp && c->m_ifpLines == 0, "IFP requires IFPLines=[-1 or >0]" );
2196
0
  }
2197
0
  if( c->m_ifpLines )
2198
0
  {
2199
0
    const int minNumThreadsIfp = getNumThreadsDefault( c ) * 3 / 2;
2200
0
    if( c->m_numThreads < minNumThreadsIfp )
2201
0
    {
2202
0
      msg.log( VVENC_WARNING, "Using IFP at low number of threads (<%d) does not provide more speedup, consider disabling IFP.\n", minNumThreadsIfp );
2203
0
    }
2204
0
  }
2205
2206
0
  if( c->m_numParallelGOPs )
2207
0
  {
2208
0
    vvenc_confirmParameter(c, (c->m_RCMaxBitrate > 0 && c->m_RCMaxBitrate < INT32_MAX) || c->m_RCTargetBitrate > 0, "No support for GOP parallel processing in rate control mode" );
2209
0
    vvenc_confirmParameter(c, c->m_numThreads == 0, "For GOP parallel processing, NumThreads > 0 is required" );
2210
0
    vvenc_confirmParameter(c, c->m_maxParallelFrames == 0, "For GOP parallel processing MaxParallelFrames > 0 is required" );
2211
0
    vvenc_confirmParameter(c, c->m_ifpLines == 0, "For GOP parallel processing IFP > 0 is required" );
2212
2213
    // GOP parallel profile
2214
0
    const int minNumThreadsGOPPP = getNumThreadsDefault( c ) * 2;
2215
0
    if( c->m_numThreads < minNumThreadsGOPPP )
2216
0
      msg.log( VVENC_WARNING, "Using NumParallelGOPs at low number of threads (<%d) does not provide more speedup, consider disabling NumParallelGOPs.\n", minNumThreadsGOPPP );
2217
0
  }
2218
2219
0
  vvenc_confirmParameter(c, c->m_explicitAPSid < 0 || c->m_explicitAPSid > 7, "ExplicitAPDid out of range [0 .. 7]" );
2220
2221
0
  vvenc_confirmParameter(c, c->m_maxNumMergeCand < 1,                              "MaxNumMergeCand must be 1 or greater.");
2222
0
  vvenc_confirmParameter(c, c->m_maxNumMergeCand > vvenc::MRG_MAX_NUM_CANDS,              "MaxNumMergeCand must be no more than MRG_MAX_NUM_CANDS." );
2223
0
  vvenc_confirmParameter(c, c->m_maxNumGeoCand > vvenc::GEO_MAX_NUM_UNI_CANDS,            "MaxNumGeoCand must be no more than GEO_MAX_NUM_UNI_CANDS." );
2224
0
  vvenc_confirmParameter(c, c->m_Geo > 0 && c->m_maxNumGeoCand > c->m_maxNumMergeCand,    "MaxNumGeoCand must be no more than MaxNumMergeCand." );
2225
0
  vvenc_confirmParameter(c, 0 < c->m_maxNumGeoCand && c->m_maxNumGeoCand < 2,         "MaxNumGeoCand must be no less than 2 unless MaxNumGeoCand is 0." );
2226
0
  vvenc_confirmParameter(c, c->m_maxNumAffineMergeCand < (c->m_SbTMVP ? 1 : 0),       "MaxNumAffineMergeCand must be greater than 0 when SbTMVP is enabled");
2227
0
  vvenc_confirmParameter(c, c->m_maxNumAffineMergeCand > vvenc::AFFINE_MRG_MAX_NUM_CANDS, "MaxNumAffineMergeCand must be no more than AFFINE_MRG_MAX_NUM_CANDS." );
2228
2229
2230
0
  vvenc_confirmParameter(c, c->m_bufferingPeriodSEIEnabled && (!c->m_hrdParametersPresent), "BufferingPeriodSEI requires HrdParametersPresent enabled");
2231
0
  vvenc_confirmParameter(c, c->m_pictureTimingSEIEnabled && (!c->m_hrdParametersPresent),   "PictureTimingSEI requires HrdParametersPresent enabled");
2232
2233
  // max CU width and height should be power of 2
2234
0
  uint32_t ui = c->m_CTUSize;
2235
0
  while(ui)
2236
0
  {
2237
0
    ui >>= 1;
2238
0
    if( (ui & 1) == 1)
2239
0
    {
2240
0
      vvenc_confirmParameter(c, ui != 1 , "CTU Size should be 2^n");
2241
0
    }
2242
0
  }
2243
2244
0
  vvenc_confirmParameter(c,  c->m_IntraPeriod != 1 && c->m_intraOnlyConstraintFlag, "IntraOnlyConstraintFlag cannot be 1 for inter sequences");
2245
2246
0
  if( c->m_GOPList[ 0 ].m_POC != -1 )
2247
0
  {
2248
0
    int multipleFactor = /*m_compositeRefEnabled ? 2 :*/ 1;
2249
0
    for(int i=0; i<c->m_GOPSize; i++)
2250
0
    {
2251
0
      if (c->m_GOPList[i].m_POC == c->m_GOPSize * multipleFactor)
2252
0
      {
2253
0
        vvenc_confirmParameter(c,  c->m_GOPList[i].m_temporalId!=0 , "The last frame in each GOP must have temporal ID = 0 " );
2254
0
      }
2255
0
    }
2256
2257
0
    if ( (c->m_IntraPeriod != 1) && !c->m_loopFilterOffsetInPPS && (!c->m_bLoopFilterDisable) )
2258
0
    {
2259
0
      for(int i=0; i<c->m_GOPSize; i++)
2260
0
      {
2261
0
        for( int comp = 0; comp < 3; comp++ )
2262
0
        {
2263
          //TODO: c->m_GOPList[i].m_tcOffsetDiv2 and c->m_GOPList[i].m_betaOffsetDiv2 are checked with the luma value also for the chroma components (currently not used or all values are equal)
2264
0
          vvenc_confirmParameter(c,  (c->m_GOPList[i].m_betaOffsetDiv2 + c->m_loopFilterBetaOffsetDiv2[comp]) < -12 || (c->m_GOPList[i].m_betaOffsetDiv2 + c->m_loopFilterBetaOffsetDiv2[comp]) > 12, "Loop Filter Beta Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
2265
0
          vvenc_confirmParameter(c,  (c->m_GOPList[i].m_tcOffsetDiv2 + c->m_loopFilterTcOffsetDiv2[comp]) < -12 || (c->m_GOPList[i].m_tcOffsetDiv2 + c->m_loopFilterTcOffsetDiv2[comp]) > 12, "Loop Filter Tc Offset div. 2 for one of the GOP entries exceeds supported range (-12 to 12)" );
2266
0
        }
2267
0
      }
2268
0
    }
2269
2270
0
    for(int i=0; i<c->m_GOPSize; i++)
2271
0
    {
2272
0
      vvenc_confirmParameter(c, abs(c->m_GOPList[i].m_CbQPoffset               ) > 12, "Cb QP Offset for one of the GOP entries exceeds supported range (-12 to 12)" );
2273
0
      vvenc_confirmParameter(c, abs(c->m_GOPList[i].m_CbQPoffset + c->m_chromaCbQpOffset) > 12, "Cb QP Offset for one of the GOP entries, when combined with the PPS Cb offset, exceeds supported range (-12 to 12)" );
2274
0
      vvenc_confirmParameter(c, abs(c->m_GOPList[i].m_CrQPoffset               ) > 12, "Cr QP Offset for one of the GOP entries exceeds supported range (-12 to 12)" );
2275
0
      vvenc_confirmParameter(c, abs(c->m_GOPList[i].m_CrQPoffset + c->m_chromaCrQpOffset) > 12, "Cr QP Offset for one of the GOP entries, when combined with the PPS Cr offset, exceeds supported range (-12 to 12)" );
2276
0
    }
2277
2278
0
    for(int i=0; i<c->m_GOPSize; i++)
2279
0
    {
2280
0
      vvenc_confirmParameter(c, c->m_GOPList[i].m_sliceType!='B' && c->m_GOPList[i].m_sliceType!='P' && c->m_GOPList[i].m_sliceType!='I', "Slice type must be equal to B or P or I");
2281
0
    }
2282
0
  }
2283
2284
0
  vvenc_confirmParameter(c, abs(c->m_sliceChromaQpOffsetIntraOrPeriodic[0]                 ) > 12, "Intra/periodic Cb QP Offset exceeds supported range (-12 to 12)" );
2285
0
  vvenc_confirmParameter(c, abs(c->m_sliceChromaQpOffsetIntraOrPeriodic[0]  + c->m_chromaCbQpOffset ) > 12, "Intra/periodic Cb QP Offset, when combined with the PPS Cb offset, exceeds supported range (-12 to 12)" );
2286
0
  vvenc_confirmParameter(c, abs(c->m_sliceChromaQpOffsetIntraOrPeriodic[1]                 ) > 12, "Intra/periodic Cr QP Offset exceeds supported range (-12 to 12)" );
2287
0
  vvenc_confirmParameter(c, abs(c->m_sliceChromaQpOffsetIntraOrPeriodic[1]  + c->m_chromaCrQpOffset ) > 12, "Intra/periodic Cr QP Offset, when combined with the PPS Cr offset, exceeds supported range (-12 to 12)" );
2288
2289
0
  vvenc_confirmParameter(c, c->m_fastLocalDualTreeMode < 0 || c->m_fastLocalDualTreeMode > 2, "FastLocalDualTreeMode must be in range [0..2]" );
2290
2291
0
  if( c->m_picPartitionFlag || c->m_numTileCols > 1 || c->m_numTileRows > 1 || c->m_tileColumnWidth[0] > 0 || c->m_tileRowHeight[0] > 0 )
2292
0
  {
2293
0
    if( !c->m_picPartitionFlag ) c->m_picPartitionFlag = true;
2294
2295
0
    checkCfgPicPartitioningParameter( c );
2296
0
  }
2297
0
  vvenc_confirmParameter(c, c->m_GOPQPA < 0, "GOPQPA must be >= 0");
2298
2299
0
  vvenc_confirmParameter(c, c->m_GOPQPA > 0 && c->m_usePerceptQPA, "GOP-wise QPA cannot be enabled if perceptual QPA is enabled");
2300
0
  vvenc_confirmParameter(c, c->m_GOPQPA < 0, "GOPQPA must be >= 0");
2301
2302
0
  return( c->m_confirmFailed );
2303
0
}
2304
2305
static void initMultithreading( vvenc_config *c )
2306
0
{
2307
0
  int mtProfile      = c->m_mtProfile;
2308
2309
0
  if( mtProfile < 0 )
2310
0
  {
2311
0
    int numThreads     = c->m_numThreads;
2312
0
    int defaultThreads = getNumThreadsDefault( c );
2313
2314
0
    if( numThreads <= defaultThreads ) mtProfile = 0;
2315
0
    else if( 2 * numThreads <= 3 * defaultThreads ) mtProfile = 1;
2316
0
    else if( numThreads <= 2 * defaultThreads ) mtProfile = 2;
2317
0
    else mtProfile = 3;
2318
0
  }
2319
2320
0
  c->m_mtProfile = mtProfile;
2321
2322
0
  if( mtProfile == 0 )
2323
0
  {
2324
0
    if( c->m_entropyCodingSyncEnabled < 0 ) c->m_entropyCodingSyncEnabled = 0;
2325
0
    if( c->m_ifp < 0 ) c->m_ifp = 0;
2326
2327
0
    return;
2328
0
  }
2329
2330
0
  bool isHD   = std::min( c->m_SourceWidth, c->m_SourceHeight ) >= 720;
2331
0
  bool isLCTU = c->m_CTUSize == 128;
2332
0
  bool isTileDefault = c->m_numTileCols < 0 && c->m_numTileRows < 0 && c->m_tileRowHeight[0] == 0 && c->m_tileColumnWidth[0] == 0;
2333
2334
0
  if( isLCTU )
2335
0
  {
2336
0
    if( c->m_entropyCodingSyncEnabled < 0 ) c->m_entropyCodingSyncEnabled = ( !isHD || mtProfile >= 2 ) ? 1 : 0;
2337
0
    if( c->m_ifp < 0 ) c->m_ifp = mtProfile == 3 ? 1 : 0;
2338
0
  }
2339
0
  else
2340
0
  {
2341
0
    if( c->m_entropyCodingSyncEnabled < 0 ) c->m_entropyCodingSyncEnabled = mtProfile == 3 ? 1 : 0;
2342
0
    if( c->m_ifp < 0 ) c->m_ifp =  ( !isHD || mtProfile >= 2 ) ? 1 : 0;
2343
0
  }
2344
  
2345
0
  if( isHD && isTileDefault )
2346
0
  {
2347
0
    c->m_numTileRows = c->m_ifp == 1 ? 1 : 2;
2348
0
    c->m_numTileCols = 2;
2349
0
  }
2350
0
}
2351
2352
static void checkCfgPicPartitioningParameter( vvenc_config *c )
2353
0
{
2354
0
  vvenc::PPS pps;
2355
2356
0
  pps.picWidthInLumaSamples  = c->m_SourceWidth;
2357
0
  pps.picHeightInLumaSamples = c->m_SourceHeight;
2358
0
  pps.log2CtuSize            = vvenc::ceilLog2( c->m_CTUSize );
2359
0
  pps.picWidthInCtu          = ( pps.picWidthInLumaSamples + c->m_CTUSize - 1 ) / c->m_CTUSize;
2360
0
  pps.picHeightInCtu         = ( pps.picHeightInLumaSamples + c->m_CTUSize - 1 ) / c->m_CTUSize;
2361
2362
0
  int lastNonZeroColumn = -1, lastNonZeroRow = -1;
2363
0
  bool validCfg = true;
2364
0
  checkCfgInputArrays( c, lastNonZeroColumn, lastNonZeroRow, validCfg );
2365
0
  if( !validCfg ) return;
2366
2367
0
  int numTileColumnWidths, numTileRowHeights;
2368
2369
0
  bool colWidth_all_zero  = lastNonZeroColumn == -1;
2370
0
  bool rowHeight_all_zero = lastNonZeroRow == -1;
2371
2372
  //number of tiles is set explicitly, e.g. Tiles=2x2
2373
  //TileColumnWidthArray and TileRowHeightArray have to be not set
2374
0
  if( c->m_numTileCols > 1 || c->m_numTileRows > 1 )
2375
0
  {
2376
0
    vvenc_confirmParameter( c, !colWidth_all_zero  && ( lastNonZeroColumn + 1 ) != c->m_numTileCols, "Explicit number of tile columns and column widths are given, but not consistent!" );
2377
0
    vvenc_confirmParameter( c, !rowHeight_all_zero && ( lastNonZeroRow    + 1 ) != c->m_numTileRows, "Explicit number of tile rows and column heights are given, but not consistent!" );
2378
2379
0
    if( !colWidth_all_zero || !rowHeight_all_zero ) return;
2380
2381
0
    if( c->m_numTileCols > 1 )
2382
0
    {
2383
0
      unsigned int tileWidth = pps.picWidthInCtu / c->m_numTileCols;
2384
0
      if( tileWidth * c->m_numTileCols < pps.picWidthInCtu ) tileWidth++;
2385
0
      c->m_tileColumnWidth[0] = tileWidth;
2386
0
    }
2387
0
    else
2388
0
    {
2389
0
      c->m_tileColumnWidth[0] = pps.picWidthInCtu;
2390
0
    }
2391
0
    if( c->m_numTileRows > 1 )
2392
0
    {
2393
0
      unsigned int tileHeight = pps.picHeightInCtu / c->m_numTileRows;
2394
0
      if( tileHeight * c->m_numTileRows < pps.picHeightInCtu ) tileHeight++;
2395
0
      c->m_tileRowHeight[0] = tileHeight;
2396
0
    }
2397
0
    else
2398
0
    {
2399
0
      c->m_tileRowHeight[0] = pps.picHeightInCtu;
2400
0
    }
2401
2402
0
    numTileColumnWidths = 1;
2403
0
    numTileRowHeights   = 1;
2404
0
  }
2405
0
  else
2406
0
  {
2407
    // set default tile column if not provided
2408
0
    if( colWidth_all_zero )
2409
0
    {
2410
0
      c->m_tileColumnWidth[0] = pps.picWidthInCtu;
2411
0
    }
2412
    // set default tile row if not provided
2413
0
    if( rowHeight_all_zero )
2414
0
    {
2415
0
      c->m_tileRowHeight[0] = pps.picHeightInCtu;
2416
0
    }
2417
2418
    // remove any tile columns that can be specified implicitly
2419
0
    if( c->m_tileColumnWidth[1] > 0 )
2420
0
    {
2421
0
      while( lastNonZeroColumn > 0 && c->m_tileColumnWidth[lastNonZeroColumn-1] == c->m_tileColumnWidth[lastNonZeroColumn] )
2422
0
      {
2423
0
        c->m_tileColumnWidth[lastNonZeroColumn] = 0;
2424
0
        lastNonZeroColumn--;
2425
0
      }
2426
0
      numTileColumnWidths = lastNonZeroColumn+1;
2427
0
    }
2428
0
    else
2429
0
    {
2430
0
      numTileColumnWidths = 1;
2431
0
    }
2432
2433
    // remove any tile rows that can be specified implicitly
2434
0
    if( c->m_tileRowHeight[1] > 0 )
2435
0
    {
2436
0
      while( lastNonZeroRow > 0 && c->m_tileRowHeight[lastNonZeroRow-1] == c->m_tileRowHeight[lastNonZeroRow] )
2437
0
      {
2438
0
        c->m_tileRowHeight[lastNonZeroRow] = 0;
2439
0
        lastNonZeroRow--;
2440
0
      }
2441
0
      numTileRowHeights = lastNonZeroRow+1;
2442
0
    }
2443
0
    else
2444
0
    {
2445
0
      numTileRowHeights = 1;
2446
0
    }
2447
0
  }
2448
  // setup tiles in temporary PPS structure
2449
0
  uint32_t remSize = pps.picWidthInCtu;
2450
0
  int colIdx;
2451
0
  for( colIdx=0; remSize > 0 && colIdx < numTileColumnWidths; colIdx++ )
2452
0
  {
2453
0
    vvenc_confirmParameter( c, c->m_tileColumnWidth[ colIdx ] == 0, "Tile column widths cannot be equal to 0" );
2454
0
    c->m_tileColumnWidth[ colIdx ] = std::min( remSize, c->m_tileColumnWidth[ colIdx ]);
2455
0
    pps.tileColWidth.push_back( c->m_tileColumnWidth[ colIdx ] );
2456
0
    remSize -= c->m_tileColumnWidth[ colIdx ];
2457
0
  }
2458
0
  if( colIdx < numTileColumnWidths && remSize == 0 )
2459
0
  {
2460
0
    vvenc_confirmParameter( c, true, "Explicitly given tile column widths exceed picture width" );
2461
0
    return;
2462
0
  }
2463
0
  pps.numExpTileCols  = numTileColumnWidths;
2464
0
  c->m_numExpTileCols = numTileColumnWidths;
2465
0
  remSize = pps.picHeightInCtu;
2466
0
  int rowIdx;
2467
0
  for( rowIdx=0; remSize > 0 && rowIdx < numTileRowHeights; rowIdx++ )
2468
0
  {
2469
0
    vvenc_confirmParameter( c, c->m_tileRowHeight[ rowIdx ] == 0, "Tile row heights cannot be equal to 0" );
2470
0
    c->m_tileRowHeight[ rowIdx ] = std::min( remSize, c->m_tileRowHeight[ rowIdx ]);
2471
0
    pps.tileRowHeight.push_back( c->m_tileRowHeight[ rowIdx ] );
2472
0
    remSize -= c->m_tileRowHeight[ rowIdx ];
2473
0
  }
2474
0
  if( rowIdx < numTileRowHeights && remSize == 0 )
2475
0
  {
2476
0
    vvenc_confirmParameter( c, true, "Explicitly given tile row heights exceed picture width" );
2477
0
    return;
2478
0
  }
2479
0
  pps.numExpTileRows  = numTileRowHeights;
2480
0
  c->m_numExpTileRows = numTileRowHeights;
2481
0
  pps.initTiles();
2482
2483
0
  uint32_t maxTileCols, maxTileRows;
2484
0
  vvenc::LevelTierFeatures::getMaxTileColsRowsPerLevel( c->m_level, maxTileCols, maxTileRows );
2485
0
  vvenc_confirmParameter( c, pps.numTileCols > maxTileCols, "Number of tile columns exceeds maximum number allowed according to specified level" );
2486
0
  vvenc_confirmParameter( c, pps.numTileRows > maxTileRows, "Number of tile rows exceeds maximum number allowed according to specified level" );
2487
0
  c->m_numTileCols = pps.numTileCols;
2488
0
  c->m_numTileRows = pps.numTileRows;
2489
2490
0
  for( int col = 0; col < pps.numTileCols; col++ ) c->m_tileColumnWidth[col] = pps.tileColWidth [col];
2491
0
  for( int row = 0; row < pps.numTileRows; row++ ) c->m_tileRowHeight  [row] = pps.tileRowHeight[row];
2492
2493
0
  vvenc_confirmParameter( c, c->m_treatAsSubPic && ( c->m_numTileCols > 1 || c->m_numTileRows > 1 ), "TreatAsSubPic and Tiles not supported yet");
2494
0
}
2495
2496
static void checkCfgInputArrays( vvenc_config *c, int &lastNonZeroCol, int &lastNonZeroRow, bool &cfgIsValid )
2497
0
{
2498
0
  int lastNonZeroIdx = -1;
2499
0
  for( int i = 9; i >= 0; i-- )
2500
0
  {
2501
0
    if( c->m_tileColumnWidth[i] != 0 )
2502
0
    {
2503
0
      lastNonZeroIdx = i;
2504
0
      break;
2505
0
    }
2506
0
  }
2507
0
  lastNonZeroCol = lastNonZeroIdx;
2508
2509
0
  lastNonZeroIdx = -1;
2510
2511
0
  for( int i = 9; i >= 0; i-- )
2512
0
  {
2513
0
    if( c->m_tileRowHeight[i] != 0 )
2514
0
    {
2515
0
      lastNonZeroIdx = i;
2516
0
      break;
2517
0
    }
2518
0
  }
2519
0
  lastNonZeroRow = lastNonZeroIdx;
2520
2521
0
  if( lastNonZeroCol > 0 )
2522
0
  {
2523
0
    for( int i = 0; i < lastNonZeroCol; i++ )
2524
0
    {
2525
0
      vvenc_confirmParameter( c, c->m_tileColumnWidth[i] == 0, "Tile column width cannot be 0! Check your TileColumnWidthArray" );
2526
0
      cfgIsValid = c->m_tileColumnWidth[i] != 0;
2527
0
    }
2528
0
  }
2529
0
  if( lastNonZeroRow > 0 )
2530
0
  {
2531
0
    for( int i = 0; i < lastNonZeroRow; i++ )
2532
0
    {
2533
0
      vvenc_confirmParameter( c, c->m_tileRowHeight[i] == 0, "Tile row height cannot be 0! Check your TileRowHeightArray" );
2534
0
      cfgIsValid = c->m_tileRowHeight[i] != 0;
2535
0
    }
2536
0
  }
2537
2538
0
}
2539
2540
VVENC_DECL int vvenc_init_default( vvenc_config *c, int width, int height, int framerate, int targetbitrate, int qp, vvencPresetMode preset )
2541
0
{
2542
0
  int iRet = VVENC_OK;
2543
0
  vvenc_config_default( c );
2544
0
  c->m_SourceWidth         = width;                    // luminance width of input picture
2545
0
  c->m_SourceHeight        = height;                   // luminance height of input picture
2546
2547
0
  c->m_FrameRate           = framerate;                // temporal rate (fps num)
2548
0
  c->m_FrameScale          = 1;                        // temporal scale (fps denum)
2549
2550
0
  switch( framerate )
2551
0
  {
2552
0
    case 23:  c->m_FrameRate = 24000;  c->m_FrameScale = 1001; break;
2553
0
    case 29:  c->m_FrameRate = 30000;  c->m_FrameScale = 1001; break;
2554
0
    case 59:  c->m_FrameRate = 60000;  c->m_FrameScale = 1001; break;
2555
0
    case 119: c->m_FrameRate = 120000; c->m_FrameScale = 1001; break;
2556
0
    default: break;
2557
0
  }
2558
2559
0
  c->m_TicksPerSecond      = VVENC_TICKS_PER_SEC_DEF;  // ticks per second for dts generation
2560
2561
0
  c->m_inputBitDepth[0]    = 8;                        // input bitdepth
2562
0
  c->m_internalBitDepth[0] = 10;                       // internal bitdepth
2563
2564
0
  c->m_QP                  = qp;                       // quantization parameter 0-63
2565
0
  c->m_usePerceptQPA       = true;                     // perceptual QP adaptation (false: off, true: on)
2566
2567
0
  c->m_RCTargetBitrate     = targetbitrate;            // target bitrate for rate ctrl. in bps
2568
0
  c->m_RCMaxBitrate        = 0;                        // maximum instantaneous bitrate in bps
2569
2570
0
  c->m_numThreads          = -1;                       // number of worker threads (-1: auto, 0: off, else set worker threads)
2571
0
  c->m_mtProfile           = -1;                       // set mtProfile to auto
2572
2573
0
  iRet = vvenc_init_preset( c, preset );
2574
0
  return iRet;
2575
0
}
2576
2577
VVENC_DECL int vvenc_init_preset( vvenc_config *c, vvencPresetMode preset )
2578
0
{
2579
0
  memset(&c->m_qpInValsCb ,0, sizeof(c->m_qpInValsCb));
2580
0
  memset(&c->m_qpOutValsCb,0, sizeof(c->m_qpOutValsCb));
2581
2582
0
  std::vector<int>  qpVals = { 17, 22, 34, 42 };
2583
0
  std::copy(qpVals.begin(), qpVals.end(), c->m_qpInValsCb);
2584
2585
0
  qpVals = { 17, 23, 35, 39 };
2586
0
  std::copy(qpVals.begin(), qpVals.end(), c->m_qpOutValsCb);
2587
2588
  // basic settings
2589
0
  c->m_log2MinCodingBlockSize          = 2;
2590
0
  c->m_intraQPOffset                   = -3;
2591
0
  c->m_lambdaFromQPEnable              = true;
2592
0
  c->m_bUseASR                         = true;
2593
0
  c->m_bUseHADME                       = true;
2594
0
  c->m_fastHad                         = false;
2595
0
  c->m_useRDOQTS                       = true;
2596
0
  c->m_useSelectiveRDOQ                = 0;
2597
0
  c->m_fastQtBtEnc                     = true;
2598
0
  c->m_maxNumMergeCand                 = 6;
2599
0
  c->m_reshapeSignalType               = 0;
2600
0
  c->m_updateCtrl                      = 0;
2601
0
  c->m_LMCSOffset                      = 6;
2602
0
  c->m_RDOQ                            = 1;
2603
0
  c->m_SignDataHidingEnabled           = 0;
2604
0
  c->m_useFastLCTU                     = 1;
2605
0
  c->m_numRefPics                      = 0;
2606
0
  c->m_numRefPicsSCC                   = 0;
2607
2608
  // tools
2609
0
  c->m_Affine                          = 0;
2610
0
  c->m_alf                             = 0;
2611
0
  c->m_alfSpeed                        = 0;
2612
0
  c->m_allowDisFracMMVD                = 0;
2613
0
  c->m_BCW                             = 0;
2614
0
  c->m_blockImportanceMapping          = 0;
2615
0
  c->m_BDOF                            = 0;
2616
0
  c->m_ccalf                           = 0;
2617
0
  c->m_CIIP                            = 0;
2618
0
  c->m_DepQuantEnabled                 = 0;
2619
0
  c->m_DMVR                            = 0;
2620
0
  c->m_EDO                             = 0;
2621
0
  c->m_Geo                             = 0;
2622
0
  c->m_AMVRspeed                       = 0;
2623
0
  c->m_ISP                             = 0;
2624
0
  c->m_JointCbCrMode                   = 0;
2625
0
  c->m_LFNST                           = 0;
2626
0
  c->m_LMChroma                        = 0;
2627
0
  c->m_lumaReshapeEnable               = 0;
2628
0
  c->m_vvencMCTF.MCTF                  = 0;
2629
0
  c->m_vvencMCTF.MCTFSpeed             = 0;
2630
0
  c->m_MIP                             = 0;
2631
0
  c->m_useFastMIP                      = 0;
2632
0
  c->m_MMVD                            = 0;
2633
0
  c->m_MRL                             = 0;
2634
0
  c->m_MTS                             = 0;
2635
0
  c->m_MTSImplicit                     = 0;
2636
0
  c->m_PROF                            = 0;
2637
0
  c->m_bUseSAO                         = 1;
2638
0
  c->m_SbTMVP                          = 0;
2639
0
  c->m_SBT                             = 0;
2640
0
  c->m_SMVD                            = 0;
2641
0
  c->m_TMVPModeId                      = 1;
2642
0
  c->m_useNonLinearAlfChroma           = 0;
2643
0
  c->m_useNonLinearAlfLuma             = 0;
2644
2645
  // ssc tools
2646
0
  c->m_motionEstimationSearchMethodSCC = 2;
2647
0
  c->m_useBDPCM                        = 2;
2648
0
  c->m_IBCMode                         = 2;
2649
0
  c->m_IBCFastMethod                   = 6;
2650
0
  c->m_TS                              = 2;
2651
0
  c->m_useChromaTS                     = 0;
2652
0
  c->m_TSsize                          = 3;
2653
2654
0
  switch( preset )
2655
0
  {
2656
0
    case vvencPresetMode::VVENC_FIRSTPASS:
2657
2658
      // motion estimation
2659
0
      c->m_SearchRange                     = 128;
2660
0
      c->m_bipredSearchRange               = 1;
2661
0
      c->m_minSearchWindow                 = 96;
2662
0
      c->m_fastInterSearchMode             = VVENC_FASTINTERSEARCH_MODE3;
2663
0
      c->m_motionEstimationSearchMethod    = VVENC_MESEARCH_DIAMOND_FAST;
2664
0
      c->m_maxNumMergeCand                 = 4;
2665
2666
      // partitioning: CTUSize64 QT44MTT00
2667
0
      c->m_CTUSize                         = 64;
2668
0
      c->m_dualITree                       = 1;
2669
0
      c->m_MinQT[ 0 ]                      = 32;
2670
0
      c->m_MinQT[ 1 ]                      = 32;
2671
0
      c->m_MinQT[ 2 ]                      = 16;
2672
0
      c->m_maxMTTDepth                     = 0;
2673
0
      c->m_maxMTTDepthI                    = 0;
2674
2675
      // speedups
2676
0
      c->m_qtbttSpeedUp                    = 7;
2677
0
      c->m_fastTTSplit                     = 0;
2678
0
      c->m_contentBasedFastQtbt            = true;
2679
0
      c->m_fastHad                         = true;
2680
0
      c->m_usePbIntraFast                  = 2;
2681
0
      c->m_useFastMrg                      = 3;
2682
0
      c->m_fastLocalDualTreeMode           = 1;
2683
0
      c->m_fastSubPel                      = 2;
2684
0
      c->m_FastIntraTools                  = 0;
2685
0
      c->m_FIMMode                         = 4;
2686
0
      c->m_useEarlyCU                      = 2;
2687
0
      c->m_bIntegerET                      = 1;
2688
0
      c->m_IntraEstDecBit                  = 3;
2689
0
      c->m_numIntraModesFullRD             = 1;
2690
0
      c->m_reduceIntraChromaModesFullRD    = true;
2691
0
      c->m_meReduceTap                     = 2;
2692
0
      c->m_numRefPics                      = 1;
2693
0
      c->m_numRefPicsSCC                   = 0;
2694
2695
      // tools
2696
0
      c->m_blockImportanceMapping          = 1;
2697
0
      c->m_RDOQ                            = 2;
2698
0
      c->m_useSelectiveRDOQ                = 2;
2699
0
      c->m_SignDataHidingEnabled           = 1;
2700
0
      c->m_LMChroma                        = 1;
2701
0
      c->m_vvencMCTF.MCTF                  = 2;
2702
0
      c->m_vvencMCTF.MCTFSpeed             = 4;
2703
0
      c->m_MTSImplicit                     = 1;
2704
      // scc
2705
0
      c->m_IBCFastMethod                   = 6;
2706
0
      c->m_TSsize                          = 3;
2707
0
      c->m_saoScc                          = true;
2708
2709
0
      break;
2710
2711
0
    case vvencPresetMode::VVENC_FASTER:
2712
2713
0
      c->m_FirstPassMode                   = 4;
2714
2715
      // motion estimation
2716
0
      c->m_SearchRange                     = 128;
2717
0
      c->m_bipredSearchRange               = 1;
2718
0
      c->m_minSearchWindow                 = 96;
2719
0
      c->m_fastInterSearchMode             = VVENC_FASTINTERSEARCH_MODE3;
2720
0
      c->m_motionEstimationSearchMethod    = VVENC_MESEARCH_DIAMOND_FAST;
2721
0
      c->m_maxNumMergeCand                 = 4;
2722
2723
      // partitioning: CTUSize64 QT44MTT00
2724
0
      c->m_CTUSize                         = 64;
2725
0
      c->m_dualITree                       = 1;
2726
0
      c->m_MinQT[ 0 ]                      = 4;
2727
0
      c->m_MinQT[ 1 ]                      = 4;
2728
0
      c->m_MinQT[ 2 ]                      = 2;
2729
0
      c->m_maxMTTDepth                     = 0;
2730
0
      c->m_maxMTTDepthI                    = 0;
2731
2732
      // speedups
2733
0
      c->m_qtbttSpeedUp                    = 7;
2734
0
      c->m_fastTTSplit                     = 0;
2735
0
      c->m_contentBasedFastQtbt            = true;
2736
0
      c->m_fastHad                         = true;
2737
0
      c->m_usePbIntraFast                  = 2;
2738
0
      c->m_useFastMrg                      = 3;
2739
0
      c->m_fastLocalDualTreeMode           = 1;
2740
0
      c->m_fastSubPel                      = 1;
2741
0
      c->m_FastIntraTools                  = 0;
2742
0
      c->m_FIMMode                         = 4;
2743
0
      c->m_useEarlyCU                      = 2;
2744
0
      c->m_bIntegerET                      = 1;
2745
0
      c->m_IntraEstDecBit                  = 3;
2746
0
      c->m_numIntraModesFullRD             = 1;
2747
0
      c->m_reduceIntraChromaModesFullRD    = true;
2748
0
      c->m_meReduceTap                     = 2;
2749
0
      c->m_numRefPics                      = 1;
2750
0
      c->m_numRefPicsSCC                   = 0;
2751
2752
      // tools
2753
0
      c->m_alf                             = 1;
2754
0
      c->m_alfSpeed                        = 2;
2755
0
      c->m_alfUnitSize                     = 128;
2756
0
      c->m_blockImportanceMapping          = 1;
2757
0
      c->m_ccalf                           = 1;
2758
0
      c->m_DMVR                            = 1;
2759
0
      c->m_RDOQ                            = 2;
2760
0
      c->m_useSelectiveRDOQ                = 2;
2761
0
      c->m_SignDataHidingEnabled           = 1;
2762
0
      c->m_LMChroma                        = 1;
2763
0
      c->m_vvencMCTF.MCTF                  = 2;
2764
0
      c->m_vvencMCTF.MCTFSpeed             = 4;
2765
0
      c->m_MTSImplicit                     = 1;
2766
      // scc
2767
0
      c->m_IBCFastMethod                   = 6;
2768
0
      c->m_TSsize                          = 3;
2769
0
      c->m_saoScc                          = true;
2770
2771
0
      break;
2772
2773
0
    case vvencPresetMode::VVENC_FAST:
2774
2775
0
      c->m_FirstPassMode                   = 2;
2776
2777
      // motion estimation
2778
0
      c->m_SearchRange                     = 128;
2779
0
      c->m_bipredSearchRange               = 1;
2780
0
      c->m_minSearchWindow                 = 96;
2781
0
      c->m_fastInterSearchMode             = VVENC_FASTINTERSEARCH_MODE3;
2782
0
      c->m_motionEstimationSearchMethod    = VVENC_MESEARCH_DIAMOND_FAST;
2783
0
      c->m_maxNumMergeCand                 = 5;
2784
0
      c->m_maxNumAffineMergeCand           = 3;
2785
2786
      // partitioning: CTUSize64 QT44MTT10
2787
0
      c->m_CTUSize                         = 64;
2788
0
      c->m_dualITree                       = 1;
2789
0
      c->m_MinQT[ 0 ]                      = 4;
2790
0
      c->m_MinQT[ 1 ]                      = 4;
2791
0
      c->m_MinQT[ 2 ]                      = 2;
2792
0
      c->m_maxMTTDepth                     = 0;
2793
0
      c->m_maxMTTDepthI                    = 1;
2794
2795
      // speedups
2796
0
      c->m_qtbttSpeedUp                    = 3;
2797
0
      c->m_fastTTSplit                     = 0;
2798
0
      c->m_contentBasedFastQtbt            = true;
2799
0
      c->m_fastHad                         = false;
2800
0
      c->m_usePbIntraFast                  = 1;
2801
0
      c->m_useFastMrg                      = 3;
2802
0
      c->m_fastLocalDualTreeMode           = 1;
2803
0
      c->m_fastSubPel                      = 1;
2804
0
      c->m_FastIntraTools                  = 0;
2805
0
      c->m_FIMMode                         = 2;
2806
0
      c->m_useEarlyCU                      = 2;
2807
0
      c->m_bIntegerET                      = 0;
2808
0
      c->m_IntraEstDecBit                  = 2;
2809
0
      c->m_numIntraModesFullRD             = 1;
2810
0
      c->m_reduceIntraChromaModesFullRD    = true;
2811
0
      c->m_meReduceTap                     = 2;
2812
0
      c->m_numRefPics                      = 222111;
2813
0
      c->m_numRefPicsSCC                   = 0;
2814
2815
      // tools
2816
0
      c->m_Affine                          = 5;
2817
0
      c->m_alf                             = 1;
2818
0
      c->m_alfSpeed                        = 1;
2819
0
      c->m_alfUnitSize                     = 128;
2820
0
      c->m_allowDisFracMMVD                = 1;
2821
0
      c->m_blockImportanceMapping          = 1;
2822
0
      c->m_BDOF                            = 1;
2823
0
      c->m_ccalf                           = 1;
2824
0
      c->m_DepQuantEnabled                 = 1;
2825
0
      c->m_DMVR                            = 1;
2826
0
      c->m_AMVRspeed                       = 5;
2827
0
      c->m_JointCbCrMode                   = 1;
2828
0
      c->m_LFNST                           = 1;
2829
0
      c->m_LMChroma                        = 1;
2830
0
      c->m_vvencMCTF.MCTF                  = 2;
2831
0
      c->m_vvencMCTF.MCTFSpeed             = 3;
2832
0
      c->m_MMVD                            = 3;
2833
0
      c->m_MRL                             = 1;
2834
0
      c->m_MTSImplicit                     = 1;
2835
0
      c->m_PROF                            = 1;
2836
0
      c->m_SbTMVP                          = 1;
2837
      // scc
2838
0
      c->m_IBCFastMethod                   = 4;
2839
0
      c->m_TSsize                          = 4;
2840
2841
0
      break;
2842
2843
0
    case vvencPresetMode::VVENC_MEDIUM:
2844
0
    case vvencPresetMode::VVENC_MEDIUM_LOWDECNRG:
2845
2846
      // motion estimation
2847
0
      c->m_SearchRange                     = 384;
2848
0
      c->m_bipredSearchRange               = 4;
2849
0
      c->m_minSearchWindow                 = 96;
2850
0
      c->m_fastInterSearchMode             = VVENC_FASTINTERSEARCH_MODE3;
2851
0
      c->m_motionEstimationSearchMethod    = VVENC_MESEARCH_DIAMOND_FAST;
2852
0
      c->m_maxNumMergeCand                 = 5;
2853
0
      c->m_maxNumAffineMergeCand           = 3;
2854
0
      c->m_maxNumGeoCand                   = 3;
2855
2856
      // partitioning: CTUSize128 QT44MTT21
2857
0
      c->m_CTUSize                         = 128;
2858
0
      c->m_dualITree                       = 1;
2859
0
      c->m_MinQT[ 0 ]                      = 8;
2860
0
      c->m_MinQT[ 1 ]                      = 8;
2861
0
      c->m_MinQT[ 2 ]                      = 4;
2862
0
      c->m_maxMTTDepth                     = 1;
2863
0
      c->m_maxMTTDepthI                    = 2;
2864
2865
      // speedups
2866
0
      c->m_qtbttSpeedUp                    = 3;
2867
0
      c->m_fastTTSplit                     = 5;
2868
0
      c->m_contentBasedFastQtbt            = true;
2869
0
      c->m_fastHad                         = false;
2870
0
      c->m_usePbIntraFast                  = 1;
2871
0
      c->m_useFastMrg                      = 3;
2872
0
      c->m_fastLocalDualTreeMode           = 1;
2873
0
      c->m_fastSubPel                      = 1;
2874
0
      c->m_FastIntraTools                  = 1;
2875
0
      c->m_FIMMode                         = 0;
2876
0
      c->m_useEarlyCU                      = 0;
2877
0
      c->m_bIntegerET                      = 0;
2878
0
      c->m_IntraEstDecBit                  = 2;
2879
0
      c->m_numIntraModesFullRD             = -1;
2880
0
      c->m_reduceIntraChromaModesFullRD    = true;
2881
0
      c->m_meReduceTap                     = 2;
2882
0
      c->m_numRefPics                      = 222221;
2883
0
      c->m_numRefPicsSCC                   = 0;
2884
2885
      // tools
2886
0
      c->m_Affine                          = 4;
2887
0
      c->m_alf                             = 1;
2888
0
      c->m_alfSpeed                        = 0;
2889
0
      c->m_allowDisFracMMVD                = 1;
2890
0
      c->m_blockImportanceMapping          = 1;
2891
0
      c->m_BDOF                            = 1;
2892
0
      c->m_ccalf                           = 1;
2893
0
      c->m_CIIP                            = 0;
2894
0
      c->m_DepQuantEnabled                 = 1;
2895
0
      c->m_DMVR                            = 1;
2896
0
      c->m_EDO                             = 2;
2897
0
      c->m_Geo                             = 4;
2898
0
      c->m_AMVRspeed                       = 5;
2899
0
      c->m_ISP                             = 3;
2900
0
      c->m_JointCbCrMode                   = 1;
2901
0
      c->m_LFNST                           = 1;
2902
0
      c->m_LMChroma                        = 1;
2903
0
      c->m_vvencMCTF.MCTF                  = 2;
2904
0
      c->m_vvencMCTF.MCTFSpeed             = 2;
2905
0
      c->m_MIP                             = 1;
2906
0
      c->m_useFastMIP                      = 3;
2907
0
      c->m_MMVD                            = 3;
2908
0
      c->m_MRL                             = 1;
2909
0
      c->m_MTSImplicit                     = 1;
2910
0
      c->m_PROF                            = 1;
2911
0
      c->m_SbTMVP                          = 1;
2912
0
      c->m_SMVD                            = 3;
2913
      // scc
2914
0
      c->m_IBCFastMethod                   = 3;
2915
0
      c->m_TSsize                          = 4;
2916
2917
0
      if( preset == vvencPresetMode::VVENC_MEDIUM_LOWDECNRG )
2918
0
      {
2919
0
        c->m_numRefPics                    = 2;
2920
0
        c->m_deblockLastTLayers            = 1;
2921
0
        c->m_maxMTTDepth                   = 332222;
2922
0
        c->m_maxMTTDepthI                  = 3;
2923
0
        c->m_Affine                        = 3;
2924
0
        c->m_alfSpeed                      = 1;
2925
0
        c->m_BCW                           = 2;
2926
0
        c->m_BDOF                          = 0;
2927
0
        c->m_DMVR                          = 0;
2928
0
        c->m_ISP                           = 0;
2929
0
        c->m_LFNST                         = 0;
2930
0
        c->m_MIP                           = 0;
2931
0
        c->m_useFastMIP                    = 0;
2932
0
        c->m_bUseSAO                       = true;
2933
0
        c->m_saoScc                        = true;
2934
0
        c->m_SbTMVP                        = 0;
2935
0
        c->m_useFastMrg                    = 3;
2936
0
      }
2937
2938
0
      break;
2939
2940
0
    case vvencPresetMode::VVENC_SLOW:
2941
2942
      // motion estimation
2943
0
      c->m_SearchRange                     = 384;
2944
0
      c->m_bipredSearchRange               = 4;
2945
0
      c->m_minSearchWindow                 = 96;
2946
0
      c->m_fastInterSearchMode             = VVENC_FASTINTERSEARCH_MODE3;
2947
0
      c->m_motionEstimationSearchMethod    = VVENC_MESEARCH_DIAMOND_FAST;
2948
2949
      // partitioning: CTUSize128 QT44MTT32
2950
0
      c->m_CTUSize                         = 128;
2951
0
      c->m_dualITree                       = 1;
2952
0
      c->m_MinQT[ 0 ]                      = 8;
2953
0
      c->m_MinQT[ 1 ]                      = 8;
2954
0
      c->m_MinQT[ 2 ]                      = 4;
2955
0
      c->m_maxMTTDepth                     = 2;
2956
0
      c->m_maxMTTDepthI                    = 3;
2957
2958
      // speedups
2959
0
      c->m_qtbttSpeedUp                    = 2;
2960
0
      c->m_fastTTSplit                     = 5;
2961
0
      c->m_contentBasedFastQtbt            = true;
2962
0
      c->m_fastHad                         = false;
2963
0
      c->m_usePbIntraFast                  = 1;
2964
0
      c->m_useFastMrg                      = 2;
2965
0
      c->m_fastLocalDualTreeMode           = 1;
2966
0
      c->m_fastSubPel                      = 1;
2967
0
      c->m_FastIntraTools                  = 0;
2968
0
      c->m_FIMMode                         = 0;
2969
0
      c->m_useEarlyCU                      = 0;
2970
0
      c->m_bIntegerET                      = 0;
2971
0
      c->m_IntraEstDecBit                  = 1;
2972
0
      c->m_numIntraModesFullRD             = -1;
2973
0
      c->m_reduceIntraChromaModesFullRD    = false;
2974
0
      c->m_meReduceTap                     = 2;
2975
0
      c->m_numRefPics                      = 2;
2976
0
      c->m_numRefPicsSCC                   = 0;
2977
2978
      // tools
2979
0
      c->m_Affine                          = 3;
2980
0
      c->m_alf                             = 1;
2981
0
      c->m_alfSpeed                        = 0;
2982
0
      c->m_allowDisFracMMVD                = 1;
2983
0
      c->m_BCW                             = 2;
2984
0
      c->m_blockImportanceMapping          = 1;
2985
0
      c->m_BDOF                            = 1;
2986
0
      c->m_ccalf                           = 1;
2987
0
      c->m_CIIP                            = 1;
2988
0
      c->m_DepQuantEnabled                 = 1;
2989
0
      c->m_DMVR                            = 1;
2990
0
      c->m_EDO                             = 2;
2991
0
      c->m_Geo                             = 2;
2992
0
      c->m_AMVRspeed                       = 1;
2993
0
      c->m_ISP                             = 3;
2994
0
      c->m_JointCbCrMode                   = 1;
2995
0
      c->m_LFNST                           = 1;
2996
0
      c->m_LMChroma                        = 1;
2997
0
      c->m_vvencMCTF.MCTF                  = 2;
2998
0
      c->m_vvencMCTF.MCTFSpeed             = 2;
2999
0
      c->m_MIP                             = 1;
3000
0
      c->m_useFastMIP                      = 0;
3001
0
      c->m_MMVD                            = 3;
3002
0
      c->m_MRL                             = 1;
3003
0
      c->m_MTSImplicit                     = 1;
3004
0
      c->m_PROF                            = 1;
3005
0
      c->m_SBT                             = 1;
3006
0
      c->m_SbTMVP                          = 1;
3007
0
      c->m_SMVD                            = 3;
3008
      // scc
3009
0
      c->m_IBCFastMethod                   = 1;
3010
0
      c->m_TSsize                          = 5;
3011
3012
0
      break;
3013
3014
0
    case vvencPresetMode::VVENC_SLOWER:
3015
3016
      // motion estimation
3017
0
      c->m_SearchRange                     = 384;
3018
0
      c->m_bipredSearchRange               = 4;
3019
0
      c->m_minSearchWindow                 = 96;
3020
0
      c->m_fastInterSearchMode             = VVENC_FASTINTERSEARCH_MODE3;
3021
0
      c->m_motionEstimationSearchMethod    = VVENC_MESEARCH_DIAMOND;
3022
3023
      // partitioning: CTUSize128 QT44MTT33
3024
0
      c->m_CTUSize                         = 128;
3025
0
      c->m_dualITree                       = 1;
3026
0
      c->m_MinQT[ 0 ]                      = 8;
3027
0
      c->m_MinQT[ 1 ]                      = 8;
3028
0
      c->m_MinQT[ 2 ]                      = 4;
3029
0
      c->m_maxMTTDepth                     = 333332;
3030
0
      c->m_maxMTTDepthI                    = 3;
3031
3032
      // speedups
3033
0
      c->m_qtbttSpeedUp                    = 1;
3034
0
      c->m_fastTTSplit                     = 1;
3035
0
      c->m_contentBasedFastQtbt            = false;
3036
0
      c->m_fastHad                         = false;
3037
0
      c->m_usePbIntraFast                  = 1;
3038
0
      c->m_useFastMrg                      = 1;
3039
0
      c->m_fastLocalDualTreeMode           = 1;
3040
0
      c->m_fastSubPel                      = 0;
3041
0
      c->m_FastIntraTools                  = 0;
3042
0
      c->m_FIMMode                         = 0;
3043
0
      c->m_useEarlyCU                      = 0;
3044
0
      c->m_bIntegerET                      = 0;
3045
0
      c->m_IntraEstDecBit                  = 1;
3046
0
      c->m_numIntraModesFullRD             = -1;
3047
0
      c->m_reduceIntraChromaModesFullRD    = false;
3048
0
      c->m_meReduceTap                     = 2;
3049
0
      c->m_numRefPics                      = 2;
3050
0
      c->m_numRefPicsSCC                   = 0;
3051
3052
      // tools
3053
0
      c->m_Affine                          = 1;
3054
0
      c->m_alf                             = 1;
3055
0
      c->m_alfSpeed                        = 0;
3056
0
      c->m_allowDisFracMMVD                = 1;
3057
0
      c->m_BCW                             = 2;
3058
0
      c->m_blockImportanceMapping          = 1;
3059
0
      c->m_BDOF                            = 1;
3060
0
      c->m_ccalf                           = 1;
3061
0
      c->m_CIIP                            = 1;
3062
0
      c->m_DepQuantEnabled                 = 1;
3063
0
      c->m_DMVR                            = 1;
3064
0
      c->m_EDO                             = 2;
3065
0
      c->m_Geo                             = 1;
3066
0
      c->m_AMVRspeed                       = 1;
3067
0
      c->m_ISP                             = 1;
3068
0
      c->m_JointCbCrMode                   = 1;
3069
0
      c->m_LFNST                           = 1;
3070
0
      c->m_LMChroma                        = 1;
3071
0
      c->m_vvencMCTF.MCTF                  = 2;
3072
0
      c->m_vvencMCTF.MCTFSpeed             = 2;
3073
0
      c->m_MIP                             = 1;
3074
0
      c->m_useFastMIP                      = 0;
3075
0
      c->m_MMVD                            = 1;
3076
0
      c->m_MRL                             = 1;
3077
0
      c->m_MTS                             = 1;
3078
0
      c->m_PROF                            = 1;
3079
0
      c->m_SBT                             = 1;
3080
0
      c->m_SbTMVP                          = 1;
3081
0
      c->m_SMVD                            = 1;
3082
0
      c->m_useNonLinearAlfChroma           = 1;
3083
0
      c->m_useNonLinearAlfLuma             = 1;
3084
      // scc
3085
0
      c->m_IBCFastMethod                   = 1;
3086
0
      c->m_TSsize                          = 5;
3087
3088
0
      break;
3089
3090
0
    case vvencPresetMode::VVENC_TOOLTEST:
3091
3092
      // motion estimation
3093
0
      c->m_SearchRange                     = 384;
3094
0
      c->m_bipredSearchRange               = 4;
3095
0
      c->m_minSearchWindow                 = 96;
3096
0
      c->m_fastInterSearchMode             = VVENC_FASTINTERSEARCH_MODE3;
3097
0
      c->m_motionEstimationSearchMethod    = VVENC_MESEARCH_DIAMOND_FAST;
3098
3099
      // partitioning: CTUSize128 QT44MTT21
3100
0
      c->m_CTUSize                         = 128;
3101
0
      c->m_dualITree                       = 1;
3102
0
      c->m_MinQT[ 0 ]                      = 8;
3103
0
      c->m_MinQT[ 1 ]                      = 8;
3104
0
      c->m_MinQT[ 2 ]                      = 4;
3105
0
      c->m_maxMTTDepth                     = 1;
3106
0
      c->m_maxMTTDepthI                    = 2;
3107
3108
      // speedups
3109
0
      c->m_qtbttSpeedUp                    = 2;
3110
0
      c->m_fastTTSplit                     = 0;
3111
0
      c->m_contentBasedFastQtbt            = true;
3112
0
      c->m_fastHad                         = true;
3113
0
      c->m_usePbIntraFast                  = 2;
3114
0
      c->m_useFastMrg                      = 2;
3115
0
      c->m_fastLocalDualTreeMode           = 1;
3116
0
      c->m_fastSubPel                      = 1;
3117
0
      c->m_FastIntraTools                  = 1;
3118
0
      c->m_FIMMode                         = 3;
3119
0
      c->m_useEarlyCU                      = 1;
3120
0
      c->m_bIntegerET                      = 1;
3121
0
      c->m_IntraEstDecBit                  = 3;
3122
0
      c->m_numIntraModesFullRD             = -1;
3123
0
      c->m_reduceIntraChromaModesFullRD    = false;
3124
0
      c->m_meReduceTap                     = 2;
3125
0
      c->m_numRefPics                      = 222221;
3126
0
      c->m_numRefPicsSCC                   = 0;
3127
3128
      // tools
3129
0
      c->m_Affine                          = 5;
3130
0
      c->m_alf                             = 1;
3131
0
      c->m_alfSpeed                        = 0;
3132
0
      c->m_allowDisFracMMVD                = 1;
3133
0
      c->m_BCW                             = 2;
3134
0
      c->m_blockImportanceMapping          = 0;
3135
0
      c->m_BDOF                            = 1;
3136
0
      c->m_ccalf                           = 1;
3137
0
      c->m_CIIP                            = 3;
3138
0
      c->m_DepQuantEnabled                 = 1;
3139
0
      c->m_DMVR                            = 1;
3140
0
      c->m_EDO                             = 1;
3141
0
      c->m_Geo                             = 3;
3142
0
      c->m_AMVRspeed                       = 3;
3143
0
      c->m_ISP                             = 2;
3144
0
      c->m_JointCbCrMode                   = 1;
3145
0
      c->m_LFNST                           = 1;
3146
0
      c->m_LMChroma                        = 1;
3147
0
      c->m_vvencMCTF.MCTF                  = 2;
3148
0
      c->m_vvencMCTF.MCTFSpeed             = 2;
3149
0
      c->m_MIP                             = 1;
3150
0
      c->m_useFastMIP                      = 3;
3151
0
      c->m_MMVD                            = 2;
3152
0
      c->m_MRL                             = 1;
3153
0
      c->m_MTS                             = 1;
3154
0
      c->m_PROF                            = 1;
3155
0
      c->m_SBT                             = 2;
3156
0
      c->m_SbTMVP                          = 1;
3157
0
      c->m_SMVD                            = 3;
3158
0
      c->m_useNonLinearAlfChroma           = 1;
3159
0
      c->m_useNonLinearAlfLuma             = 1;
3160
      // scc
3161
0
      c->m_motionEstimationSearchMethodSCC = 3;
3162
0
      c->m_useBDPCM                        = 1;
3163
0
      c->m_IBCFastMethod                   = 5;
3164
0
      c->m_TS                              = 1;
3165
0
      c->m_useChromaTS                     = 1;
3166
0
      c->m_TSsize                          = 3;
3167
3168
0
      break;
3169
3170
0
    default:
3171
0
      return -1;
3172
0
  }
3173
3174
0
  return 0;
3175
0
}
3176
3177
VVENC_DECL const char* vvenc_get_config_as_string( vvenc_config *c, vvencMsgLevel eMsgLevel )
3178
0
{
3179
0
  std::stringstream css;
3180
0
  std::string loglvl("vvenc ");
3181
0
  switch ( eMsgLevel )
3182
0
  {
3183
0
    case VVENC_SILENT : loglvl.append("[silent]: ");  break;
3184
0
    case VVENC_ERROR  : loglvl.append("[error]: ");   break;
3185
0
    case VVENC_WARNING: loglvl.append("[warning]: "); break;
3186
0
    case VVENC_INFO   : loglvl.append("[info]: ");    break;
3187
0
    case VVENC_NOTICE : loglvl.append("[notice]: ");  break;
3188
0
    case VVENC_VERBOSE: loglvl.append("[verbose]: "); break;
3189
0
    case VVENC_DETAILS: loglvl.append("[details]: "); break;
3190
0
    default: break;
3191
0
  }
3192
3193
0
  if( eMsgLevel >= VVENC_INFO )
3194
0
  {
3195
0
    css << loglvl << "Internal format                        : " << c->m_PadSourceWidth << "x" << c->m_PadSourceHeight << "  " <<  (double)c->m_FrameRate/c->m_FrameScale << " Hz  "  << getDynamicRangeStr(c->m_HdrMode) << "\n";
3196
0
    css << loglvl << "Threads                                : " << c->m_numThreads << "  (parallel frames: " << c->m_maxParallelFrames <<")\n";
3197
3198
0
    css << loglvl << "Rate control                           : ";
3199
3200
0
    if ( c->m_RCTargetBitrate > 0 )
3201
0
    {
3202
0
      if( c->m_RCTargetBitrate < 1000000 )
3203
0
        css << "VBR  " <<  (double)c->m_RCTargetBitrate/1000.0 << " kbps  ";
3204
0
      else
3205
0
        css << "VBR  " <<  (double)c->m_RCTargetBitrate/1000000.0 << " Mbps  ";
3206
0
      if( c->m_RCNumPasses == 2 )
3207
0
      {
3208
0
        css << "two-pass";
3209
0
        if ( c->m_RCPass >= 0 )
3210
0
          css << "  pass " << c->m_RCPass << "/2";
3211
0
      }
3212
0
      else
3213
0
        css << "single-pass";
3214
0
#if !IFP_RC_DETERMINISTIC
3215
0
      if( c->m_ifpLines && c->m_numThreads > 1 )
3216
0
      {
3217
0
        css << " (non-deterministic due to IFP)";
3218
0
      }
3219
0
#endif
3220
0
    }
3221
0
    else
3222
0
    {
3223
0
      css << "QP " << c->m_QP;
3224
0
    }
3225
0
    if( c->m_RCMaxBitrate > 0 && c->m_RCMaxBitrate != INT32_MAX )
3226
0
    {
3227
0
      if ( c->m_RCTargetBitrate <= 0 )
3228
0
      {
3229
0
        css << "  capped CQF";
3230
0
      }
3231
0
      if( c->m_RCMaxBitrate < 1000000 )
3232
0
        css << "  (max. rate " <<  (double)c->m_RCMaxBitrate/1000.0 << " kbps)";
3233
0
      else
3234
0
        css << "  (max. rate " <<  (double)c->m_RCMaxBitrate/1000000.0 << " Mbps)";
3235
0
    }
3236
0
    css << "\n";
3237
3238
0
    css << loglvl << "Perceptual optimization                : " << (c->m_usePerceptQPA ? "Enabled" : "Disabled") << "\n";
3239
0
    css << loglvl << "Intra period (keyframe)                : " << c->m_IntraPeriod << "\n";
3240
0
    css << loglvl << "Decoding refresh type                  : " << vvenc_getDecodingRefreshTypeStr(c->m_DecodingRefreshType,c->m_poc0idr) << "\n";
3241
3242
0
    if( c->m_masteringDisplay[0] != 0 || c->m_masteringDisplay[1] != 0 || c->m_masteringDisplay[8] != 0  )
3243
0
    {
3244
0
      css << loglvl << "Mastering display color volume         : " << vvenc_getMasteringDisplayStr( c->m_masteringDisplay ) << "\n";
3245
0
  }
3246
0
    if( c->m_contentLightLevel[0] != 0 || c->m_contentLightLevel[1] != 0 )
3247
0
    {
3248
0
      css << loglvl << "Content light level                    : " << vvenc_getContentLightLevelStr( c->m_contentLightLevel ) << "\n";
3249
0
    }
3250
0
  }
3251
3252
0
  if( eMsgLevel >= VVENC_NOTICE )
3253
0
  {
3254
0
    css << loglvl << "Sequence PSNR output                   : " << (c->m_printMSEBasedSequencePSNR ? "Linear average, MSE-based" : "Linear average only") << "\n";
3255
0
    css << loglvl << "Hexadecimal PSNR output                : " << (c->m_printHexPsnr ? "Enabled" : "Disabled") << "\n";
3256
0
    css << loglvl << "Sequence MSE output                    : " << (c->m_printSequenceMSE ? "Enabled" : "Disabled") << "\n";
3257
0
    css << loglvl << "Frame MSE output                       : " << (c->m_printFrameMSE ? "Enabled" : "Disabled") << "\n";
3258
0
    css << loglvl << "Cabac-zero-word-padding                : " << (c->m_cabacZeroWordPaddingEnabled ? "Enabled" : "Disabled") << "\n";
3259
    //css << loglvl << "Frame/Field                            : Frame based coding\n";
3260
0
    if ( c->m_framesToBeEncoded > 0 )
3261
0
      css << loglvl << "Frame index                            : " << c->m_framesToBeEncoded << " frames\n";
3262
0
    else
3263
0
      css << loglvl << "Frame index                            : all frames\n";
3264
3265
0
    css << loglvl << "Profile                                : " << getProfileStr( c->m_profile ) << "\n";
3266
0
    css << loglvl << "Level                                  : " << getLevelStr( c->m_level ) << "\n";
3267
0
    css << loglvl << "CU size                                : " << c->m_CTUSize << "\n";
3268
0
    css << loglvl << "Max TB size                            : " << (1 << c->m_log2MaxTbSize) << "\n";
3269
0
    css << loglvl << "Min CB size                            : " << (1 << c->m_log2MinCodingBlockSize) << "\n";
3270
0
    css << loglvl << "Motion search range                    : " << c->m_SearchRange << "\n";
3271
0
    css << loglvl << "QP                                     : " << c->m_QP << "\n";
3272
0
    css << loglvl << "Max dQP signaling subdiv               : " << c->m_cuQpDeltaSubdiv << "\n";
3273
0
    css << loglvl << "Cb QP Offset (dual tree)               : " << c->m_chromaCbQpOffset << " (" << c->m_chromaCbQpOffsetDualTree << ")\n";
3274
0
    css << loglvl << "Cr QP Offset (dual tree)               : " << c->m_chromaCrQpOffset << " (" << c->m_chromaCrQpOffsetDualTree << ")\n";
3275
0
    css << loglvl << "GOP size                               : " << c->m_GOPSize << "\n";
3276
0
    css << loglvl << "PicReordering                          : " << c->m_picReordering << "\n";
3277
0
    css << loglvl << "Input bit depth                        : (Y:" << c->m_inputBitDepth[ 0 ] << ", C:" << c->m_inputBitDepth[ 1 ] << ")\n";
3278
0
    css << loglvl << "MSB-extended bit depth                 : (Y:" << c->m_MSBExtendedBitDepth[ 0 ] << ", C:" << c->m_MSBExtendedBitDepth[ 1 ] << ")\n";
3279
0
    css << loglvl << "Internal bit depth                     : (Y:" << c->m_internalBitDepth[ 0 ] << ", C:" << c->m_internalBitDepth[ 1 ] << ")\n";
3280
0
    css << loglvl << "cu_chroma_qp_offset_subdiv             : " << c->m_cuChromaQpOffsetSubdiv << "\n";
3281
0
    if (c->m_bUseSAO)
3282
0
    {
3283
0
      css << loglvl << "log2_sao_offset_scale_luma             : " << c->m_log2SaoOffsetScale[ 0 ] << "\n";
3284
0
      css << loglvl << "log2_sao_offset_scale_chroma           : " << c->m_log2SaoOffsetScale[ 1 ] << "\n";
3285
0
    }
3286
0
    css << loglvl << "Cost function                          : " << getCostFunctionStr( c->m_costMode ) << "\n";
3287
0
    css << loglvl << "Film grain analysis                    : " << (int)c->m_fga << "\n";
3288
0
    }
3289
3290
0
  if( eMsgLevel >= VVENC_VERBOSE )
3291
0
  {    
3292
    // verbose output
3293
0
    css << "\n";
3294
0
    css << loglvl << "CODING TOOL CFG: ";
3295
0
    css << "CTU" << c->m_CTUSize << " QTMin" << vvenc::Log2( c->m_CTUSize / c->m_MinQT[0] ) << vvenc::Log2( c->m_CTUSize / c->m_MinQT[1] ) << "BTT" << c->m_maxMTTDepthI << c->m_maxMTTDepth << " ";
3296
0
    css << "IBD:" << ((c->m_internalBitDepth[ 0 ] > c->m_MSBExtendedBitDepth[ 0 ]) || (c->m_internalBitDepth[ 1 ] > c->m_MSBExtendedBitDepth[ 1 ])) << " ";
3297
0
    css << "SAO:" << (c->m_bUseSAO ? 1 : 0) << " ";
3298
0
    css << "ALF:" << (c->m_alf ? 1 : 0) << " ";
3299
0
    if( c->m_alf )
3300
0
    {
3301
0
      css << "(NonLinLuma:" << c->m_useNonLinearAlfLuma << " ";
3302
0
      css << "NonLinChr:" << c->m_useNonLinearAlfChroma << ") ";
3303
0
    }
3304
0
    css << "CCALF:" << (c->m_ccalf ? 1 : 0) << " ";
3305
3306
0
    css << "Tiles:" << c->m_numTileCols << "x" << c->m_numTileRows << " ";
3307
0
    css << "Slices:"<< c->m_numSlicesInPic << " ";
3308
3309
0
    const int iWaveFrontSubstreams = c->m_entropyCodingSyncEnabled ? ( c->m_PadSourceHeight + c->m_CTUSize - 1 ) / c->m_CTUSize : 1;
3310
0
    css << "WPP:" << (c->m_entropyCodingSyncEnabled ? 1 : 0) << " ";
3311
0
    css << "WPP-Substreams:" << iWaveFrontSubstreams << " ";
3312
0
    css << "TMVP:" << c->m_TMVPModeId << " ";
3313
3314
0
    css << "DQ:" << c->m_DepQuantEnabled << " ";
3315
0
    css << "SDH:" << c->m_SignDataHidingEnabled << " ";
3316
0
    css << "CST:" << c->m_dualITree << " ";
3317
0
    css << "BDOF:" << c->m_BDOF << " ";
3318
0
    css << "DMVR:" << c->m_DMVR << " ";
3319
0
    css << "MTSImplicit:" << c->m_MTSImplicit << " ";
3320
0
    css << "SBT:" << c->m_SBT << " ";
3321
0
    css << "JCbCr:" << c->m_JointCbCrMode << " ";
3322
0
    css << "CabacInitPresent:" << c->m_cabacInitPresent << " ";
3323
0
    css << "AMVR:" << c->m_AMVRspeed << " ";
3324
0
    css << "SMVD:" << c->m_SMVD << " ";
3325
3326
0
    css << "LMCS:" << c->m_lumaReshapeEnable << " ";
3327
0
    if( c->m_lumaReshapeEnable )
3328
0
    {
3329
0
      css << "(Signal:" << (c->m_reshapeSignalType == 0 ? "SDR" : (c->m_reshapeSignalType == 2 ? "HDR-HLG" : "HDR-PQ")) << " ";
3330
0
      css << "Opt:" << c->m_adpOption << "";
3331
0
      if( c->m_adpOption > 0 )
3332
0
      {
3333
0
        css << " CW:" << c->m_initialCW << "";
3334
0
      }
3335
0
      css << ") ";
3336
0
    }
3337
0
    css << "CIIP:" << c->m_CIIP << " ";
3338
0
    css << "MIP:" << c->m_MIP << " ";
3339
0
    css << "AFFINE:" << c->m_Affine << " ";
3340
0
    if( c->m_Affine )
3341
0
    {
3342
0
      css << "(PROF:" << c->m_PROF << ", ";
3343
0
      css << "Type:" << c->m_AffineType << ") ";
3344
0
    }
3345
0
    css << "MMVD:" << c->m_MMVD << " ";
3346
0
    if( c->m_MMVD )
3347
0
      css << "DisFracMMVD:" << c->m_allowDisFracMMVD << " ";
3348
0
    css << "SbTMVP:" << c->m_SbTMVP << " ";
3349
0
    css << "GPM:" << c->m_Geo << " ";
3350
0
    css << "LFNST:" << c->m_LFNST << " ";
3351
0
    css << "MTS:" << c->m_MTS << " ";
3352
0
    if( c->m_MTS )
3353
0
    {
3354
0
      css << "(IntraCand:" << c->m_MTSIntraMaxCand << ") ";
3355
0
    }
3356
0
    css << "ISP:" << c->m_ISP << " ";
3357
0
    css << "TS:" << c->m_TS << " ";
3358
0
    if( c->m_TS )
3359
0
    {
3360
0
      css << "TSLog2MaxSize:" << c->m_TSsize << " ";
3361
0
      css << "useChromaTS:" << c->m_useChromaTS << " ";
3362
0
    }
3363
0
    css << "BDPCM:" << c->m_useBDPCM << " ";
3364
0
    css << "IBC:" << c->m_IBCMode << " ";
3365
0
    css << "BCW:" << c->m_BCW << " ";
3366
3367
0
    css << "\n" << loglvl << "ENC. ALG. CFG: ";
3368
0
    css << "QPA:" << c->m_usePerceptQPA << " ";
3369
0
    css << "HAD:" << c->m_bUseHADME << " ";
3370
0
    if( c->m_fastHad ) css << "(fast) ";
3371
0
    css << "RDQ:" << c->m_RDOQ << " ";
3372
0
    css << "RDQTS:" << c->m_useRDOQTS << " ";
3373
0
    css << "ASR:" << c->m_bUseASR << " ";
3374
0
    css << "MinSearchWindow:" << c->m_minSearchWindow << " ";
3375
0
    css << "EDO:" << c->m_EDO << " ";
3376
0
    css << "MCTF:" << c->m_vvencMCTF.MCTF << " ";
3377
0
    css << "BIM:" << c->m_blockImportanceMapping << " ";
3378
3379
0
    css << "\n" << loglvl << "PRE-ANALYSIS CFG: ";
3380
0
    css << "STA:" << (int)c->m_sliceTypeAdapt << " ";
3381
0
    css << "LeadFrames:" << c->m_leadFrames << " ";
3382
0
    css << "TrailFrames:" << c->m_trailFrames << " ";
3383
3384
0
    css << "\n" << loglvl << "FAST TOOL CFG: ";
3385
0
    css << "ECU:" << c->m_useEarlyCU << " ";
3386
0
    css << "FEN:" << c->m_fastInterSearchMode << " ";
3387
0
    css << "FDM:" << c->m_useFastDecisionForMerge << " ";
3388
0
    css << "FastSearch:" << c->m_motionEstimationSearchMethod << " ";
3389
0
    if( c->m_motionEstimationSearchMethodSCC )
3390
0
    {
3391
0
      css << "(SCC:" << c->m_motionEstimationSearchMethodSCC << ") ";
3392
0
    }
3393
0
    css << "LCTUFast:" << c->m_useFastLCTU << " ";
3394
0
    css << "FastMrg:" << c->m_useFastMrg << " ";
3395
0
    css << "PBIntraFast:" << c->m_usePbIntraFast << " ";
3396
0
    css << "AMaxBT:" << c->m_useAMaxBT << " ";
3397
0
    css << "FastQtBtEnc:" << c->m_fastQtBtEnc << " ";
3398
0
    css << "ContentBasedFastQtbt:" << c->m_contentBasedFastQtbt << " ";
3399
0
    if( c->m_MIP )
3400
0
    {
3401
0
      css << "FastMIP:" << c->m_useFastMIP << " ";
3402
0
    }
3403
0
    css << "FastIntraTools:" << c->m_FastIntraTools << " ";
3404
0
    css << "IntraEstDecBit:" << c->m_IntraEstDecBit << " ";
3405
0
    css << "FastLocalDualTree:" << c->m_fastLocalDualTreeMode << " ";
3406
0
    css << "IntegerET:" << c->m_bIntegerET << " ";
3407
0
    css << "FastSubPel:" << c->m_fastSubPel << " ";
3408
0
    css << "ReduceFilterME:" << c->m_meReduceTap << " ";
3409
0
    css << "QtbttExtraFast:" << c->m_qtbttSpeedUp << " ";
3410
0
    css << "FastTTSplit:" << c->m_fastTTSplit << " ";
3411
0
    if( c->m_IBCMode )
3412
0
    {
3413
0
      css << "IBCFastMethod:" << c->m_IBCFastMethod << " ";
3414
0
    }
3415
0
    css << "FIM:" << c->m_FIMMode << " ";
3416
0
    if( c->m_FastInferMerge )
3417
0
    {
3418
0
      css << "(" << c->m_FastInferMerge << ") ";
3419
0
    }
3420
0
    if( c->m_alf )
3421
0
    {
3422
0
      css << "ALFSpeed:" << c->m_alfSpeed << " ";
3423
0
    }
3424
0
    if( c->m_quantThresholdVal & 1 )
3425
0
      css << "QuantThr:" << (c->m_quantThresholdVal >> 1) << ".5 ";
3426
0
    else
3427
0
      css << "QuantThr:" << (c->m_quantThresholdVal >> 1) << " ";
3428
0
    css << "SelectiveRDQO:" << ( int ) c->m_useSelectiveRDOQ << " ";
3429
3430
0
    css << "\n" << loglvl << "RATE CONTROL CFG: ";
3431
0
    css << "RateControl:" << ( c->m_RCTargetBitrate > 0 ) << " ";
3432
0
    if ( c->m_RCTargetBitrate > 0 )
3433
0
    {
3434
0
      css << "Passes:" << c->m_RCNumPasses << " ";
3435
0
      css << "Pass:" << c->m_RCPass << " ";
3436
0
      css << "TargetBitrate:" << c->m_RCTargetBitrate << " ";
3437
0
      if ( c->m_RCInitialQP > 0 )
3438
0
      {
3439
0
        css << "RCInitialQP:" << c->m_RCInitialQP << " ";
3440
0
      }
3441
0
    }
3442
0
    else
3443
0
    {
3444
0
      css << "QP:" << c->m_QP << " ";
3445
0
    }
3446
0
    if ( c->m_RCMaxBitrate > 0 && c->m_RCMaxBitrate != INT32_MAX )
3447
0
    {
3448
0
      if ( c->m_RCTargetBitrate <= 0 )
3449
0
      {
3450
0
        css << "(capped CQF) ";
3451
0
      }
3452
0
      css << "MaxBitrate:" << c->m_RCMaxBitrate << " ";
3453
0
    }
3454
3455
0
    css << "LookAhead:" << c->m_LookAhead << " ";
3456
0
    css << "FirstPassMode:" << c->m_FirstPassMode << " ";
3457
3458
0
    css << "\n" << loglvl << "PARALLEL PROCESSING CFG: ";
3459
0
    css << "NumThreads:" << c->m_numThreads << " ";
3460
0
    css << "MaxParallelFrames:" << c->m_maxParallelFrames << " ";
3461
0
    css << "IFP:" << (c->m_ifp ? 1: 0) << " (IFPLines:" << (int)c->m_ifpLines << ")" << " ";
3462
0
    css << "NumParallelGOPs:" << (int) c->m_numParallelGOPs << " ";
3463
0
    if( c->m_picPartitionFlag )
3464
0
    {
3465
0
      css << "TileParallelCtuEnc:" << c->m_tileParallelCtuEnc << " ";
3466
0
    }
3467
0
    css << "WppBitEqual:" << c->m_ensureWppBitEqual << " ";
3468
0
    css << "WF:" << (int) c->m_entropyCodingSyncEnabled << " ";
3469
0
    css << "\n";
3470
0
  }
3471
3472
0
  vvenc_cfgString = css.str();
3473
0
  return vvenc_cfgString.c_str();
3474
0
}
3475
3476
VVENC_DECL void vvenc_set_msg_callback( vvenc_config *cfg, void *msgCtx, vvencLoggingCallback msgFnc )
3477
0
{
3478
0
  if( cfg )
3479
0
  {
3480
0
    cfg->m_msgCtx = msgCtx;
3481
0
    cfg->m_msgFnc = msgFnc;
3482
0
  }
3483
0
}
3484
3485
3486
VVENC_DECL int vvenc_set_param(vvenc_config *c, const char *name, const char *value)
3487
0
{
3488
0
  if ( !name )
3489
0
  {
3490
0
    return VVENC_PARAM_BAD_NAME;
3491
0
  }
3492
3493
0
  bool bError = false;
3494
3495
0
  std::string n(name);
3496
0
  std::string v(value);
3497
0
  std::transform( n.begin(), n.end(), n.begin(), ::tolower );
3498
3499
0
  if ( name[0] == '-'  || name[1] == '-' ) // name prefix given - not supported
3500
0
  {
3501
0
    return VVENC_PARAM_BAD_NAME;
3502
0
  }
3503
0
  else
3504
0
  {
3505
0
    std::string namePrefix="--";  // add long option name prefix
3506
0
    n = namePrefix;
3507
0
    n.append(name);
3508
0
  }
3509
3510
0
  if (!value)
3511
0
  {
3512
0
    v = "true";
3513
0
  }
3514
0
  else if (value[0] == '=')
3515
0
  {
3516
0
    value += 1;
3517
0
    v = value;
3518
0
  }
3519
3520
0
  char *argv[2];
3521
0
  argv[0]=(char*)n.c_str();
3522
0
  argv[1]=(char*)v.c_str();
3523
3524
0
  int ret = vvenc_set_param_list ( c, 2, argv);
3525
0
  if( ret != 0 )
3526
0
  {
3527
0
    return ret;
3528
0
  }
3529
3530
0
  return bError ? VVENC_PARAM_BAD_VALUE : 0;
3531
0
}
3532
3533
VVENC_DECL int vvenc_set_param_list( vvenc_config *c, int argc, char* argv[] )
3534
0
{
3535
0
  if ( !argc || !c )
3536
0
  {
3537
0
    return -1;
3538
0
  }
3539
3540
0
  apputils::VVEncAppCfg cVVEncAppCfg;
3541
0
  std::stringstream cssO;
3542
0
  int ret =  cVVEncAppCfg.parse( argc, argv, c, cssO );
3543
3544
0
  if( !cssO.str().empty() )
3545
0
  {    
3546
0
    vvenc::MsgLog msg(c->m_msgCtx,c->m_msgFnc);
3547
0
    vvencMsgLevel msgLvl = VVENC_INFO;
3548
0
    if( ret < 0 ) msgLvl = VVENC_ERROR;
3549
0
    else if( ret == 2 ) msgLvl = VVENC_WARNING;
3550
3551
0
    msg.log( msgLvl , "%s\n", cssO.str().c_str());
3552
0
  }
3553
3554
0
  return ret;
3555
0
}
3556
3557
3558
VVENC_NAMESPACE_END
3559
3560