1use num_derive::*;
11
12use crate::partition::BlockSize;
13use crate::serialize::{Deserialize, Serialize};
14
15use std::fmt;
16
17#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
20#[non_exhaustive]
21pub struct SpeedSettings {
22 pub multiref: bool,
26
27 pub fast_deblock: bool,
29
30 pub rdo_lookahead_frames: usize,
34
35 pub scene_detection_mode: SceneDetectionSpeed,
37
38 pub cdef: bool,
40
41 pub lrf: bool,
43
44 pub lru_on_skip: bool,
47
48 pub sgr_complexity: SGRComplexityLevel,
50
51 pub segmentation: SegmentationLevel,
55
56 pub partition: PartitionSpeedSettings,
59
60 pub transform: TransformSpeedSettings,
62
63 pub prediction: PredictionSpeedSettings,
65
66 pub motion: MotionSpeedSettings,
68}
69
70impl Default for SpeedSettings {
71 fn default() -> Self {
73 SpeedSettings {
74 multiref: true,
75 fast_deblock: false,
76 rdo_lookahead_frames: 40,
77 scene_detection_mode: SceneDetectionSpeed::Standard,
78 cdef: true,
79 lrf: true,
80 lru_on_skip: true,
81 sgr_complexity: SGRComplexityLevel::Full,
82 segmentation: SegmentationLevel::Complex,
83 partition: PartitionSpeedSettings {
84 encode_bottomup: true,
85 non_square_partition_max_threshold: BlockSize::BLOCK_64X64,
86 partition_range: PartitionRange::new(
87 BlockSize::BLOCK_4X4,
88 BlockSize::BLOCK_64X64,
89 ),
90 },
91 transform: TransformSpeedSettings {
92 reduced_tx_set: false,
93 tx_domain_distortion: true,
96 tx_domain_rate: false,
97 rdo_tx_decision: true,
98 enable_inter_tx_split: false,
99 },
100 prediction: PredictionSpeedSettings {
101 prediction_modes: PredictionModesSetting::ComplexAll,
102 fine_directional_intra: true,
103 },
104 motion: MotionSpeedSettings {
105 include_near_mvs: true,
106 use_satd_subpel: true,
107 me_allow_full_search: true,
108 },
109 }
110 }
111}
112
113impl SpeedSettings {
114 pub fn from_preset(speed: u8) -> Self {
116 let mut settings = SpeedSettings::default();
118
119 if speed >= 1 {
120 settings.lru_on_skip = false;
121 settings.segmentation = SegmentationLevel::Simple;
122 }
123
124 if speed >= 2 {
125 settings.partition.non_square_partition_max_threshold =
126 BlockSize::BLOCK_8X8;
127
128 settings.prediction.prediction_modes =
129 PredictionModesSetting::ComplexKeyframes;
130 }
131
132 if speed >= 3 {
133 settings.rdo_lookahead_frames = 30;
134
135 settings.partition.partition_range =
136 PartitionRange::new(BlockSize::BLOCK_8X8, BlockSize::BLOCK_64X64);
137 }
138
139 if speed >= 4 {
140 settings.partition.encode_bottomup = false;
141 }
142
143 if speed >= 5 {
144 settings.sgr_complexity = SGRComplexityLevel::Reduced;
145 settings.motion.include_near_mvs = false;
146 }
147
148 if speed >= 6 {
149 settings.rdo_lookahead_frames = 20;
150
151 settings.transform.rdo_tx_decision = false;
152 settings.transform.reduced_tx_set = true;
153
154 settings.motion.me_allow_full_search = false;
155 }
156
157 if speed >= 7 {
158 settings.prediction.prediction_modes = PredictionModesSetting::Simple;
159 settings.multiref = false;
165 settings.fast_deblock = true;
166 }
167
168 if speed >= 8 {
169 settings.rdo_lookahead_frames = 10;
170 settings.lrf = false;
171 }
172
173 if speed >= 9 {
174 settings.partition.partition_range =
178 PartitionRange::new(BlockSize::BLOCK_16X16, BlockSize::BLOCK_32X32);
179
180 settings.transform.enable_inter_tx_split = true;
182 }
183
184 if speed >= 10 {
185 settings.scene_detection_mode = SceneDetectionSpeed::Fast;
186
187 settings.partition.partition_range =
188 PartitionRange::new(BlockSize::BLOCK_32X32, BlockSize::BLOCK_32X32);
189
190 settings.motion.use_satd_subpel = false;
191 }
192
193 settings
194 }
195}
196
197#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
198#[cfg_attr(test, derive(Default))]
199pub struct TransformSpeedSettings {
201 pub reduced_tx_set: bool,
205
206 pub tx_domain_distortion: bool,
210
211 pub tx_domain_rate: bool,
215
216 pub rdo_tx_decision: bool,
220
221 pub enable_inter_tx_split: bool,
223}
224
225#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
226#[cfg_attr(test, derive(Default))]
227pub struct PartitionSpeedSettings {
229 pub encode_bottomup: bool,
233
234 pub non_square_partition_max_threshold: BlockSize,
237
238 pub partition_range: PartitionRange,
242}
243
244#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
245#[cfg_attr(test, derive(Default))]
246pub struct MotionSpeedSettings {
248 pub use_satd_subpel: bool,
252
253 pub include_near_mvs: bool,
257
258 pub me_allow_full_search: bool,
261}
262
263#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
264#[cfg_attr(test, derive(Default))]
265pub struct PredictionSpeedSettings {
267 pub prediction_modes: PredictionModesSetting,
271
272 pub fine_directional_intra: bool,
274}
275
276#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
278pub struct PartitionRange {
279 pub(crate) min: BlockSize,
280 pub(crate) max: BlockSize,
281}
282
283impl PartitionRange {
284 pub fn new(min: BlockSize, max: BlockSize) -> Self {
291 assert!(max >= min);
292 assert!(min.is_sqr());
295 assert!(max.is_sqr());
297
298 Self { min, max }
299 }
300}
301
302#[cfg(test)]
303impl Default for PartitionRange {
304 fn default() -> Self {
305 PartitionRange::new(BlockSize::BLOCK_4X4, BlockSize::BLOCK_64X64)
306 }
307}
308
309#[derive(
311 Clone,
312 Copy,
313 Debug,
314 PartialOrd,
315 PartialEq,
316 Eq,
317 FromPrimitive,
318 Serialize,
319 Deserialize,
320)]
321pub enum SceneDetectionSpeed {
322 Fast,
324 Standard,
326 None,
329}
330
331impl fmt::Display for SceneDetectionSpeed {
332 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
333 write!(
334 f,
335 "{}",
336 match self {
337 SceneDetectionSpeed::Fast => "Fast",
338 SceneDetectionSpeed::Standard => "Standard",
339 SceneDetectionSpeed::None => "None",
340 }
341 )
342 }
343}
344
345#[derive(
347 Clone,
348 Copy,
349 Debug,
350 PartialOrd,
351 PartialEq,
352 Eq,
353 FromPrimitive,
354 Serialize,
355 Deserialize,
356)]
357pub enum PredictionModesSetting {
358 Simple,
360 ComplexKeyframes,
363 ComplexAll,
365}
366
367impl fmt::Display for PredictionModesSetting {
368 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
369 write!(
370 f,
371 "{}",
372 match self {
373 PredictionModesSetting::Simple => "Simple",
374 PredictionModesSetting::ComplexKeyframes => "Complex-KFs",
375 PredictionModesSetting::ComplexAll => "Complex-All",
376 }
377 )
378 }
379}
380
381#[cfg(test)]
382impl Default for PredictionModesSetting {
383 fn default() -> Self {
384 PredictionModesSetting::Simple
385 }
386}
387
388#[derive(
390 Clone,
391 Copy,
392 Debug,
393 PartialOrd,
394 PartialEq,
395 Eq,
396 FromPrimitive,
397 Serialize,
398 Deserialize,
399)]
400pub enum SGRComplexityLevel {
401 Full,
403 Reduced,
405}
406
407impl fmt::Display for SGRComplexityLevel {
408 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
409 write!(
410 f,
411 "{}",
412 match self {
413 SGRComplexityLevel::Full => "Full",
414 SGRComplexityLevel::Reduced => "Reduced",
415 }
416 )
417 }
418}
419
420#[derive(
422 Clone,
423 Copy,
424 Debug,
425 PartialOrd,
426 PartialEq,
427 Eq,
428 FromPrimitive,
429 Serialize,
430 Deserialize,
431)]
432pub enum SegmentationLevel {
433 Disabled,
435 Simple,
437 Complex,
439 Full,
441}
442
443impl fmt::Display for SegmentationLevel {
444 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
445 write!(
446 f,
447 "{}",
448 match self {
449 SegmentationLevel::Disabled => "Disabled",
450 SegmentationLevel::Simple => "Simple",
451 SegmentationLevel::Complex => "Complex",
452 SegmentationLevel::Full => "Full",
453 }
454 )
455 }
456}