/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 | | |