1use super::types_config::{
8 AdaptationAlgorithm, AdaptationMetric, BufferOverflowStrategy, ProcessingComplexity,
9 RateControlMethod, RecoveryStrategy, StreamingProtocol, TransformParameter, VideoCodec,
10};
11use serde::{Deserialize, Serialize};
12use std::collections::HashMap;
13use std::time::Duration;
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct RealTimeProcessingConfig {
18 pub enabled: bool,
20 pub target_fps: f64,
22 pub max_latency: Duration,
24 pub buffer_management: BufferManagementConfig,
26 pub adaptive_quality: AdaptiveQualityConfig,
28 pub streaming: StreamingConfig,
30 pub performance_monitoring: PerformanceMonitoringConfig,
32 pub error_handling: RealTimeErrorHandling,
34}
35
36impl Default for RealTimeProcessingConfig {
37 fn default() -> Self {
38 Self {
39 enabled: false,
40 target_fps: 30.0,
41 max_latency: Duration::from_millis(100),
42 buffer_management: BufferManagementConfig::default(),
43 adaptive_quality: AdaptiveQualityConfig::default(),
44 streaming: StreamingConfig::default(),
45 performance_monitoring: PerformanceMonitoringConfig::default(),
46 error_handling: RealTimeErrorHandling::default(),
47 }
48 }
49}
50
51impl RealTimeProcessingConfig {
52 #[must_use]
54 pub fn low_latency() -> Self {
55 Self {
56 enabled: true,
57 target_fps: 60.0,
58 max_latency: Duration::from_millis(16), buffer_management: BufferManagementConfig::minimal(),
60 adaptive_quality: AdaptiveQualityConfig::responsive(),
61 streaming: StreamingConfig::low_latency(),
62 performance_monitoring: PerformanceMonitoringConfig::aggressive(),
63 error_handling: RealTimeErrorHandling::fast_recovery(),
64 }
65 }
66
67 #[must_use]
69 pub fn high_quality_streaming() -> Self {
70 Self {
71 enabled: true,
72 target_fps: 30.0,
73 max_latency: Duration::from_millis(200),
74 buffer_management: BufferManagementConfig::quality_focused(),
75 adaptive_quality: AdaptiveQualityConfig::quality_preserving(),
76 streaming: StreamingConfig::high_quality(),
77 performance_monitoring: PerformanceMonitoringConfig::comprehensive(),
78 error_handling: RealTimeErrorHandling::robust(),
79 }
80 }
81
82 #[must_use]
84 pub fn mobile_optimized() -> Self {
85 Self {
86 enabled: true,
87 target_fps: 15.0,
88 max_latency: Duration::from_millis(300),
89 buffer_management: BufferManagementConfig::memory_efficient(),
90 adaptive_quality: AdaptiveQualityConfig::bandwidth_aware(),
91 streaming: StreamingConfig::mobile_friendly(),
92 performance_monitoring: PerformanceMonitoringConfig::lightweight(),
93 error_handling: RealTimeErrorHandling::graceful_degradation(),
94 }
95 }
96
97 pub fn validate(&self) -> Result<(), RealTimeError> {
99 if self.enabled {
100 if self.target_fps <= 0.0 {
101 return Err(RealTimeError::InvalidConfiguration(
102 "Target FPS must be positive".to_string(),
103 ));
104 }
105
106 if self.max_latency.is_zero() {
107 return Err(RealTimeError::InvalidConfiguration(
108 "Maximum latency must be greater than zero".to_string(),
109 ));
110 }
111
112 self.buffer_management.validate()?;
114 self.adaptive_quality.validate()?;
115 self.streaming.validate()?;
116 }
117
118 Ok(())
119 }
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct BufferManagementConfig {
125 pub input_buffer_size: usize,
127 pub output_buffer_size: usize,
129 pub processing_buffer_size: usize,
131 pub overflow_strategy: BufferOverflowStrategy,
133 pub pre_allocation: bool,
135 pub dynamic_resizing: bool,
137 pub monitoring: BufferMonitoringConfig,
139}
140
141impl Default for BufferManagementConfig {
142 fn default() -> Self {
143 Self {
144 input_buffer_size: 3,
145 output_buffer_size: 2,
146 processing_buffer_size: 1,
147 overflow_strategy: BufferOverflowStrategy::DropOldest,
148 pre_allocation: true,
149 dynamic_resizing: false,
150 monitoring: BufferMonitoringConfig::default(),
151 }
152 }
153}
154
155impl BufferManagementConfig {
156 #[must_use]
158 pub fn minimal() -> Self {
159 Self {
160 input_buffer_size: 1,
161 output_buffer_size: 1,
162 processing_buffer_size: 1,
163 overflow_strategy: BufferOverflowStrategy::DropNewest,
164 pre_allocation: true,
165 dynamic_resizing: false,
166 monitoring: BufferMonitoringConfig::lightweight(),
167 }
168 }
169
170 #[must_use]
172 pub fn quality_focused() -> Self {
173 Self {
174 input_buffer_size: 10,
175 output_buffer_size: 5,
176 processing_buffer_size: 3,
177 overflow_strategy: BufferOverflowStrategy::ReduceQuality,
178 pre_allocation: true,
179 dynamic_resizing: true,
180 monitoring: BufferMonitoringConfig::comprehensive(),
181 }
182 }
183
184 #[must_use]
186 pub fn memory_efficient() -> Self {
187 Self {
188 input_buffer_size: 2,
189 output_buffer_size: 1,
190 processing_buffer_size: 1,
191 overflow_strategy: BufferOverflowStrategy::SkipFrames,
192 pre_allocation: false,
193 dynamic_resizing: true,
194 monitoring: BufferMonitoringConfig::essential(),
195 }
196 }
197
198 pub fn validate(&self) -> Result<(), RealTimeError> {
200 if self.input_buffer_size == 0 || self.output_buffer_size == 0 {
201 return Err(RealTimeError::InvalidConfiguration(
202 "Buffer sizes must be greater than zero".to_string(),
203 ));
204 }
205
206 Ok(())
207 }
208
209 #[must_use]
211 pub fn memory_usage(&self, frame_size_bytes: usize) -> usize {
212 (self.input_buffer_size + self.output_buffer_size + self.processing_buffer_size)
213 * frame_size_bytes
214 }
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct BufferMonitoringConfig {
220 pub enabled: bool,
222 pub interval: Duration,
224 pub usage_threshold: f64,
226 pub track_overflows: bool,
228 pub track_underruns: bool,
230}
231
232impl Default for BufferMonitoringConfig {
233 fn default() -> Self {
234 Self {
235 enabled: true,
236 interval: Duration::from_secs(1),
237 usage_threshold: 0.8,
238 track_overflows: true,
239 track_underruns: true,
240 }
241 }
242}
243
244impl BufferMonitoringConfig {
245 #[must_use]
247 pub fn lightweight() -> Self {
248 Self {
249 enabled: true,
250 interval: Duration::from_secs(5),
251 usage_threshold: 0.9,
252 track_overflows: true,
253 track_underruns: false,
254 }
255 }
256
257 #[must_use]
259 pub fn comprehensive() -> Self {
260 Self {
261 enabled: true,
262 interval: Duration::from_millis(100),
263 usage_threshold: 0.7,
264 track_overflows: true,
265 track_underruns: true,
266 }
267 }
268
269 #[must_use]
271 pub fn essential() -> Self {
272 Self {
273 enabled: true,
274 interval: Duration::from_secs(10),
275 usage_threshold: 0.95,
276 track_overflows: true,
277 track_underruns: false,
278 }
279 }
280}
281
282#[derive(Debug, Clone, Serialize, Deserialize)]
284pub struct AdaptiveQualityConfig {
285 pub enabled: bool,
287 pub quality_levels: Vec<QualityLevel>,
289 pub adaptation_algorithm: AdaptationAlgorithm,
291 pub adaptation_metrics: Vec<AdaptationMetric>,
293 pub adaptation_params: AdaptationParameters,
295 pub constraints: QualityConstraints,
297}
298
299impl Default for AdaptiveQualityConfig {
300 fn default() -> Self {
301 Self {
302 enabled: true,
303 quality_levels: vec![
304 QualityLevel::low(),
305 QualityLevel::medium(),
306 QualityLevel::high(),
307 ],
308 adaptation_algorithm: AdaptationAlgorithm::Threshold,
309 adaptation_metrics: vec![
310 AdaptationMetric::FrameRate,
311 AdaptationMetric::Latency,
312 AdaptationMetric::CPUUsage,
313 ],
314 adaptation_params: AdaptationParameters::default(),
315 constraints: QualityConstraints::default(),
316 }
317 }
318}
319
320impl AdaptiveQualityConfig {
321 #[must_use]
323 pub fn responsive() -> Self {
324 Self {
325 enabled: true,
326 quality_levels: vec![QualityLevel::low(), QualityLevel::medium()],
327 adaptation_algorithm: AdaptationAlgorithm::PID,
328 adaptation_metrics: vec![AdaptationMetric::FrameRate, AdaptationMetric::Latency],
329 adaptation_params: AdaptationParameters::responsive(),
330 constraints: QualityConstraints::flexible(),
331 }
332 }
333
334 #[must_use]
336 pub fn quality_preserving() -> Self {
337 Self {
338 enabled: true,
339 quality_levels: vec![
340 QualityLevel::medium(),
341 QualityLevel::high(),
342 QualityLevel::ultra(),
343 ],
344 adaptation_algorithm: AdaptationAlgorithm::Predictive,
345 adaptation_metrics: vec![
346 AdaptationMetric::QualityScore,
347 AdaptationMetric::Accuracy,
348 AdaptationMetric::FrameRate,
349 ],
350 adaptation_params: AdaptationParameters::conservative(),
351 constraints: QualityConstraints::strict(),
352 }
353 }
354
355 #[must_use]
357 pub fn bandwidth_aware() -> Self {
358 Self {
359 enabled: true,
360 quality_levels: vec![QualityLevel::low(), QualityLevel::medium()],
361 adaptation_algorithm: AdaptationAlgorithm::Fuzzy,
362 adaptation_metrics: vec![
363 AdaptationMetric::MemoryUsage,
364 AdaptationMetric::CPUUsage,
365 AdaptationMetric::FrameRate,
366 ],
367 adaptation_params: AdaptationParameters::bandwidth_focused(),
368 constraints: QualityConstraints::resource_limited(),
369 }
370 }
371
372 pub fn validate(&self) -> Result<(), RealTimeError> {
374 if self.enabled && self.quality_levels.is_empty() {
375 return Err(RealTimeError::InvalidConfiguration(
376 "Quality levels cannot be empty when adaptive quality is enabled".to_string(),
377 ));
378 }
379
380 for level in &self.quality_levels {
381 level.validate()?;
382 }
383
384 Ok(())
385 }
386}
387
388#[derive(Debug, Clone, Serialize, Deserialize)]
390pub struct QualityLevel {
391 pub id: String,
393 pub resolution: (usize, usize),
395 pub complexity: ProcessingComplexity,
397 pub expected_fps: f64,
399 pub quality_score: f64,
401 pub resource_requirements: ResourceRequirements,
403}
404
405impl QualityLevel {
406 #[must_use]
408 pub fn low() -> Self {
409 Self {
410 id: "low".to_string(),
411 resolution: (320, 240),
412 complexity: ProcessingComplexity::Low,
413 expected_fps: 60.0,
414 quality_score: 0.3,
415 resource_requirements: ResourceRequirements::minimal(),
416 }
417 }
418
419 #[must_use]
421 pub fn medium() -> Self {
422 Self {
423 id: "medium".to_string(),
424 resolution: (640, 480),
425 complexity: ProcessingComplexity::Medium,
426 expected_fps: 30.0,
427 quality_score: 0.6,
428 resource_requirements: ResourceRequirements::moderate(),
429 }
430 }
431
432 #[must_use]
434 pub fn high() -> Self {
435 Self {
436 id: "high".to_string(),
437 resolution: (1280, 720),
438 complexity: ProcessingComplexity::High,
439 expected_fps: 15.0,
440 quality_score: 0.8,
441 resource_requirements: ResourceRequirements::high(),
442 }
443 }
444
445 #[must_use]
447 pub fn ultra() -> Self {
448 Self {
449 id: "ultra".to_string(),
450 resolution: (1920, 1080),
451 complexity: ProcessingComplexity::Ultra,
452 expected_fps: 10.0,
453 quality_score: 1.0,
454 resource_requirements: ResourceRequirements::maximum(),
455 }
456 }
457
458 pub fn validate(&self) -> Result<(), RealTimeError> {
460 if self.expected_fps <= 0.0 {
461 return Err(RealTimeError::InvalidConfiguration(format!(
462 "Expected FPS must be positive for quality level '{}'",
463 self.id
464 )));
465 }
466
467 if !(0.0..=1.0).contains(&self.quality_score) {
468 return Err(RealTimeError::InvalidConfiguration(format!(
469 "Quality score must be between 0.0 and 1.0 for quality level '{}'",
470 self.id
471 )));
472 }
473
474 Ok(())
475 }
476}
477
478#[derive(Debug, Clone, Serialize, Deserialize)]
480pub struct ResourceRequirements {
481 pub cpu_usage: f64,
483 pub memory_usage: usize,
485 pub gpu_memory_usage: Option<usize>,
487 pub bandwidth: usize,
489}
490
491impl ResourceRequirements {
492 #[must_use]
494 pub fn minimal() -> Self {
495 Self {
496 cpu_usage: 20.0,
497 memory_usage: 50 * 1024 * 1024, gpu_memory_usage: Some(100 * 1024 * 1024), bandwidth: 1024 * 1024, }
501 }
502
503 #[must_use]
505 pub fn moderate() -> Self {
506 Self {
507 cpu_usage: 50.0,
508 memory_usage: 200 * 1024 * 1024, gpu_memory_usage: Some(500 * 1024 * 1024), bandwidth: 5 * 1024 * 1024, }
512 }
513
514 #[must_use]
516 pub fn high() -> Self {
517 Self {
518 cpu_usage: 80.0,
519 memory_usage: 500 * 1024 * 1024, gpu_memory_usage: Some(1024 * 1024 * 1024), bandwidth: 15 * 1024 * 1024, }
523 }
524
525 #[must_use]
527 pub fn maximum() -> Self {
528 Self {
529 cpu_usage: 95.0,
530 memory_usage: 1024 * 1024 * 1024, gpu_memory_usage: Some(2 * 1024 * 1024 * 1024), bandwidth: 50 * 1024 * 1024, }
534 }
535}
536
537#[derive(Debug, Clone, Serialize, Deserialize)]
539pub struct AdaptationParameters {
540 pub sensitivity: f64,
542 pub adaptation_interval: Duration,
544 pub hysteresis: f64,
546 pub min_adaptation_interval: Duration,
548 pub pid_params: Option<PIDParameters>,
550}
551
552impl Default for AdaptationParameters {
553 fn default() -> Self {
554 Self {
555 sensitivity: 0.5,
556 adaptation_interval: Duration::from_secs(2),
557 hysteresis: 0.1,
558 min_adaptation_interval: Duration::from_millis(500),
559 pid_params: Some(PIDParameters::default()),
560 }
561 }
562}
563
564impl AdaptationParameters {
565 #[must_use]
567 pub fn responsive() -> Self {
568 Self {
569 sensitivity: 0.8,
570 adaptation_interval: Duration::from_millis(500),
571 hysteresis: 0.05,
572 min_adaptation_interval: Duration::from_millis(100),
573 pid_params: Some(PIDParameters::responsive()),
574 }
575 }
576
577 #[must_use]
579 pub fn conservative() -> Self {
580 Self {
581 sensitivity: 0.3,
582 adaptation_interval: Duration::from_secs(5),
583 hysteresis: 0.2,
584 min_adaptation_interval: Duration::from_secs(2),
585 pid_params: Some(PIDParameters::conservative()),
586 }
587 }
588
589 #[must_use]
591 pub fn bandwidth_focused() -> Self {
592 Self {
593 sensitivity: 0.6,
594 adaptation_interval: Duration::from_secs(1),
595 hysteresis: 0.15,
596 min_adaptation_interval: Duration::from_millis(250),
597 pid_params: Some(PIDParameters::bandwidth_optimized()),
598 }
599 }
600}
601
602#[derive(Debug, Clone, Serialize, Deserialize)]
604pub struct PIDParameters {
605 pub kp: f64,
607 pub ki: f64,
609 pub kd: f64,
611 pub integral_limit: f64,
613}
614
615impl Default for PIDParameters {
616 fn default() -> Self {
617 Self {
618 kp: 1.0,
619 ki: 0.1,
620 kd: 0.05,
621 integral_limit: 10.0,
622 }
623 }
624}
625
626impl PIDParameters {
627 #[must_use]
629 pub fn responsive() -> Self {
630 Self {
631 kp: 2.0,
632 ki: 0.5,
633 kd: 0.1,
634 integral_limit: 5.0,
635 }
636 }
637
638 #[must_use]
640 pub fn conservative() -> Self {
641 Self {
642 kp: 0.5,
643 ki: 0.02,
644 kd: 0.01,
645 integral_limit: 20.0,
646 }
647 }
648
649 #[must_use]
651 pub fn bandwidth_optimized() -> Self {
652 Self {
653 kp: 1.5,
654 ki: 0.3,
655 kd: 0.08,
656 integral_limit: 8.0,
657 }
658 }
659}
660
661#[derive(Debug, Clone, Serialize, Deserialize)]
663pub struct QualityConstraints {
664 pub min_quality_score: f64,
666 pub max_quality_degradation: f64,
668 pub min_frame_rate: f64,
670 pub max_latency: Duration,
672 pub max_resource_usage: ResourceConstraints,
674}
675
676impl Default for QualityConstraints {
677 fn default() -> Self {
678 Self {
679 min_quality_score: 0.3,
680 max_quality_degradation: 0.2,
681 min_frame_rate: 10.0,
682 max_latency: Duration::from_millis(500),
683 max_resource_usage: ResourceConstraints::default(),
684 }
685 }
686}
687
688impl QualityConstraints {
689 #[must_use]
691 pub fn flexible() -> Self {
692 Self {
693 min_quality_score: 0.2,
694 max_quality_degradation: 0.3,
695 min_frame_rate: 5.0,
696 max_latency: Duration::from_secs(1),
697 max_resource_usage: ResourceConstraints::relaxed(),
698 }
699 }
700
701 #[must_use]
703 pub fn strict() -> Self {
704 Self {
705 min_quality_score: 0.7,
706 max_quality_degradation: 0.1,
707 min_frame_rate: 20.0,
708 max_latency: Duration::from_millis(100),
709 max_resource_usage: ResourceConstraints::strict(),
710 }
711 }
712
713 #[must_use]
715 pub fn resource_limited() -> Self {
716 Self {
717 min_quality_score: 0.2,
718 max_quality_degradation: 0.4,
719 min_frame_rate: 5.0,
720 max_latency: Duration::from_secs(2),
721 max_resource_usage: ResourceConstraints::limited(),
722 }
723 }
724}
725
726#[derive(Debug, Clone, Serialize, Deserialize)]
728pub struct ResourceConstraints {
729 pub max_cpu_usage: f64,
731 pub max_memory_usage: usize,
733 pub max_gpu_memory_usage: Option<usize>,
735 pub max_bandwidth: usize,
737}
738
739impl Default for ResourceConstraints {
740 fn default() -> Self {
741 Self {
742 max_cpu_usage: 80.0,
743 max_memory_usage: 512 * 1024 * 1024, max_gpu_memory_usage: Some(1024 * 1024 * 1024), max_bandwidth: 10 * 1024 * 1024, }
747 }
748}
749
750impl ResourceConstraints {
751 #[must_use]
753 pub fn relaxed() -> Self {
754 Self {
755 max_cpu_usage: 95.0,
756 max_memory_usage: 2 * 1024 * 1024 * 1024, max_gpu_memory_usage: Some(4 * 1024 * 1024 * 1024), max_bandwidth: 100 * 1024 * 1024, }
760 }
761
762 #[must_use]
764 pub fn strict() -> Self {
765 Self {
766 max_cpu_usage: 60.0,
767 max_memory_usage: 256 * 1024 * 1024, max_gpu_memory_usage: Some(512 * 1024 * 1024), max_bandwidth: 5 * 1024 * 1024, }
771 }
772
773 #[must_use]
775 pub fn limited() -> Self {
776 Self {
777 max_cpu_usage: 40.0,
778 max_memory_usage: 128 * 1024 * 1024, max_gpu_memory_usage: Some(256 * 1024 * 1024), max_bandwidth: 2 * 1024 * 1024, }
782 }
783}
784
785#[derive(Debug, Clone, Serialize, Deserialize)]
787pub struct StreamingConfig {
788 pub enabled: bool,
790 pub protocol: StreamingProtocol,
792 pub encoding: EncodingConfig,
794 pub network_optimization: NetworkOptimizationConfig,
796 pub error_resilience: ErrorResilienceConfig,
798}
799
800impl Default for StreamingConfig {
801 fn default() -> Self {
802 Self {
803 enabled: false,
804 protocol: StreamingProtocol::WebRTC,
805 encoding: EncodingConfig::default(),
806 network_optimization: NetworkOptimizationConfig::default(),
807 error_resilience: ErrorResilienceConfig::default(),
808 }
809 }
810}
811
812impl StreamingConfig {
813 #[must_use]
815 pub fn low_latency() -> Self {
816 Self {
817 enabled: true,
818 protocol: StreamingProtocol::WebRTC,
819 encoding: EncodingConfig::low_latency(),
820 network_optimization: NetworkOptimizationConfig::latency_optimized(),
821 error_resilience: ErrorResilienceConfig::fast_recovery(),
822 }
823 }
824
825 #[must_use]
827 pub fn high_quality() -> Self {
828 Self {
829 enabled: true,
830 protocol: StreamingProtocol::DASH,
831 encoding: EncodingConfig::high_quality(),
832 network_optimization: NetworkOptimizationConfig::quality_optimized(),
833 error_resilience: ErrorResilienceConfig::robust(),
834 }
835 }
836
837 #[must_use]
839 pub fn mobile_friendly() -> Self {
840 Self {
841 enabled: true,
842 protocol: StreamingProtocol::HLS,
843 encoding: EncodingConfig::mobile_optimized(),
844 network_optimization: NetworkOptimizationConfig::bandwidth_efficient(),
845 error_resilience: ErrorResilienceConfig::adaptive(),
846 }
847 }
848
849 pub fn validate(&self) -> Result<(), RealTimeError> {
851 if self.enabled {
852 self.encoding.validate()?;
853 self.network_optimization.validate()?;
854 }
855 Ok(())
856 }
857}
858
859#[derive(Debug, Clone, Serialize, Deserialize)]
861pub struct EncodingConfig {
862 pub codec: VideoCodec,
864 pub bitrate: u64,
866 pub keyframe_interval: usize,
868 pub rate_control: RateControlMethod,
870 pub quality_parameter: f64,
872 pub preset: EncodingPreset,
874 pub custom_params: HashMap<String, TransformParameter>,
876}
877
878impl Default for EncodingConfig {
879 fn default() -> Self {
880 Self {
881 codec: VideoCodec::H264,
882 bitrate: 2_000_000, keyframe_interval: 30,
884 rate_control: RateControlMethod::VBR,
885 quality_parameter: 23.0, preset: EncodingPreset::Medium,
887 custom_params: HashMap::new(),
888 }
889 }
890}
891
892impl EncodingConfig {
893 #[must_use]
895 pub fn low_latency() -> Self {
896 Self {
897 codec: VideoCodec::H264,
898 bitrate: 1_000_000, keyframe_interval: 15,
900 rate_control: RateControlMethod::CBR,
901 quality_parameter: 28.0,
902 preset: EncodingPreset::UltraFast,
903 custom_params: HashMap::new(),
904 }
905 }
906
907 #[must_use]
909 pub fn high_quality() -> Self {
910 Self {
911 codec: VideoCodec::H265,
912 bitrate: 8_000_000, keyframe_interval: 60,
914 rate_control: RateControlMethod::CRF,
915 quality_parameter: 18.0,
916 preset: EncodingPreset::Slow,
917 custom_params: HashMap::new(),
918 }
919 }
920
921 #[must_use]
923 pub fn mobile_optimized() -> Self {
924 Self {
925 codec: VideoCodec::H264,
926 bitrate: 500_000, keyframe_interval: 20,
928 rate_control: RateControlMethod::VBR,
929 quality_parameter: 30.0,
930 preset: EncodingPreset::Fast,
931 custom_params: HashMap::new(),
932 }
933 }
934
935 pub fn validate(&self) -> Result<(), RealTimeError> {
937 if self.bitrate == 0 {
938 return Err(RealTimeError::InvalidConfiguration(
939 "Bitrate must be greater than zero".to_string(),
940 ));
941 }
942
943 if self.keyframe_interval == 0 {
944 return Err(RealTimeError::InvalidConfiguration(
945 "Keyframe interval must be greater than zero".to_string(),
946 ));
947 }
948
949 Ok(())
950 }
951}
952
953#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
955pub enum EncodingPreset {
956 UltraFast,
958 VeryFast,
960 Fast,
962 Medium,
964 Slow,
966 VerySlow,
968 Placebo,
970}
971
972impl Default for EncodingPreset {
973 fn default() -> Self {
974 Self::Medium
975 }
976}
977
978#[derive(Debug, Clone, Serialize, Deserialize)]
980pub struct NetworkOptimizationConfig {
981 pub adaptive_bitrate: bool,
983 pub monitor_network: bool,
985 pub bandwidth_prediction: bool,
987 pub fec_enabled: bool,
989 pub network_buffer_size: Duration,
991 pub congestion_control: CongestionControlAlgorithm,
993}
994
995impl Default for NetworkOptimizationConfig {
996 fn default() -> Self {
997 Self {
998 adaptive_bitrate: true,
999 monitor_network: true,
1000 bandwidth_prediction: false,
1001 fec_enabled: false,
1002 network_buffer_size: Duration::from_millis(1000),
1003 congestion_control: CongestionControlAlgorithm::BBR,
1004 }
1005 }
1006}
1007
1008impl NetworkOptimizationConfig {
1009 #[must_use]
1011 pub fn latency_optimized() -> Self {
1012 Self {
1013 adaptive_bitrate: true,
1014 monitor_network: true,
1015 bandwidth_prediction: true,
1016 fec_enabled: false,
1017 network_buffer_size: Duration::from_millis(100),
1018 congestion_control: CongestionControlAlgorithm::BBR,
1019 }
1020 }
1021
1022 #[must_use]
1024 pub fn quality_optimized() -> Self {
1025 Self {
1026 adaptive_bitrate: true,
1027 monitor_network: true,
1028 bandwidth_prediction: true,
1029 fec_enabled: true,
1030 network_buffer_size: Duration::from_millis(3000),
1031 congestion_control: CongestionControlAlgorithm::Cubic,
1032 }
1033 }
1034
1035 #[must_use]
1037 pub fn bandwidth_efficient() -> Self {
1038 Self {
1039 adaptive_bitrate: true,
1040 monitor_network: true,
1041 bandwidth_prediction: true,
1042 fec_enabled: false,
1043 network_buffer_size: Duration::from_millis(2000),
1044 congestion_control: CongestionControlAlgorithm::BBR,
1045 }
1046 }
1047
1048 pub fn validate(&self) -> Result<(), RealTimeError> {
1050 if self.network_buffer_size.is_zero() {
1051 return Err(RealTimeError::InvalidConfiguration(
1052 "Network buffer size must be greater than zero".to_string(),
1053 ));
1054 }
1055 Ok(())
1056 }
1057}
1058
1059#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1061pub enum CongestionControlAlgorithm {
1062 BBR,
1064 Cubic,
1066 Reno,
1068 NewReno,
1070 Custom,
1072}
1073
1074impl Default for CongestionControlAlgorithm {
1075 fn default() -> Self {
1076 Self::BBR
1077 }
1078}
1079
1080#[derive(Debug, Clone, Serialize, Deserialize)]
1082pub struct ErrorResilienceConfig {
1083 pub auto_retry: bool,
1085 pub max_retries: usize,
1087 pub retry_delay: Duration,
1089 pub graceful_degradation: bool,
1091 pub recovery_strategy: RecoveryStrategy,
1093 pub error_detection_sensitivity: f64,
1095}
1096
1097impl Default for ErrorResilienceConfig {
1098 fn default() -> Self {
1099 Self {
1100 auto_retry: true,
1101 max_retries: 3,
1102 retry_delay: Duration::from_millis(500),
1103 graceful_degradation: true,
1104 recovery_strategy: RecoveryStrategy::Degrade,
1105 error_detection_sensitivity: 0.5,
1106 }
1107 }
1108}
1109
1110impl ErrorResilienceConfig {
1111 #[must_use]
1113 pub fn fast_recovery() -> Self {
1114 Self {
1115 auto_retry: true,
1116 max_retries: 2,
1117 retry_delay: Duration::from_millis(100),
1118 graceful_degradation: true,
1119 recovery_strategy: RecoveryStrategy::Skip,
1120 error_detection_sensitivity: 0.8,
1121 }
1122 }
1123
1124 #[must_use]
1126 pub fn robust() -> Self {
1127 Self {
1128 auto_retry: true,
1129 max_retries: 5,
1130 retry_delay: Duration::from_millis(1000),
1131 graceful_degradation: true,
1132 recovery_strategy: RecoveryStrategy::Retry,
1133 error_detection_sensitivity: 0.3,
1134 }
1135 }
1136
1137 #[must_use]
1139 pub fn adaptive() -> Self {
1140 Self {
1141 auto_retry: true,
1142 max_retries: 3,
1143 retry_delay: Duration::from_millis(250),
1144 graceful_degradation: true,
1145 recovery_strategy: RecoveryStrategy::Fallback,
1146 error_detection_sensitivity: 0.6,
1147 }
1148 }
1149}
1150
1151#[derive(Debug, Clone, Serialize, Deserialize)]
1153pub struct PerformanceMonitoringConfig {
1154 pub enabled: bool,
1156 pub monitoring_interval: Duration,
1158 pub tracked_metrics: Vec<PerformanceMetric>,
1160 pub alert_thresholds: PerformanceThresholds,
1162 pub history_retention: Duration,
1164}
1165
1166impl Default for PerformanceMonitoringConfig {
1167 fn default() -> Self {
1168 Self {
1169 enabled: true,
1170 monitoring_interval: Duration::from_secs(1),
1171 tracked_metrics: vec![
1172 PerformanceMetric::FrameRate,
1173 PerformanceMetric::Latency,
1174 PerformanceMetric::CPUUsage,
1175 PerformanceMetric::MemoryUsage,
1176 ],
1177 alert_thresholds: PerformanceThresholds::default(),
1178 history_retention: Duration::from_secs(3600), }
1180 }
1181}
1182
1183impl PerformanceMonitoringConfig {
1184 #[must_use]
1186 pub fn aggressive() -> Self {
1187 Self {
1188 enabled: true,
1189 monitoring_interval: Duration::from_millis(100),
1190 tracked_metrics: vec![
1191 PerformanceMetric::FrameRate,
1192 PerformanceMetric::Latency,
1193 PerformanceMetric::CPUUsage,
1194 PerformanceMetric::MemoryUsage,
1195 PerformanceMetric::GPUUsage,
1196 PerformanceMetric::NetworkBandwidth,
1197 PerformanceMetric::BufferUtilization,
1198 ],
1199 alert_thresholds: PerformanceThresholds::strict(),
1200 history_retention: Duration::from_secs(7200), }
1202 }
1203
1204 #[must_use]
1206 pub fn comprehensive() -> Self {
1207 Self {
1208 enabled: true,
1209 monitoring_interval: Duration::from_millis(500),
1210 tracked_metrics: vec![
1211 PerformanceMetric::FrameRate,
1212 PerformanceMetric::Latency,
1213 PerformanceMetric::CPUUsage,
1214 PerformanceMetric::MemoryUsage,
1215 PerformanceMetric::GPUUsage,
1216 PerformanceMetric::NetworkBandwidth,
1217 PerformanceMetric::BufferUtilization,
1218 PerformanceMetric::QualityScore,
1219 PerformanceMetric::ErrorRate,
1220 ],
1221 alert_thresholds: PerformanceThresholds::balanced(),
1222 history_retention: Duration::from_secs(86400), }
1224 }
1225
1226 #[must_use]
1228 pub fn lightweight() -> Self {
1229 Self {
1230 enabled: true,
1231 monitoring_interval: Duration::from_secs(5),
1232 tracked_metrics: vec![PerformanceMetric::FrameRate, PerformanceMetric::Latency],
1233 alert_thresholds: PerformanceThresholds::relaxed(),
1234 history_retention: Duration::from_secs(1800), }
1236 }
1237}
1238
1239#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
1241pub enum PerformanceMetric {
1242 FrameRate,
1244 Latency,
1246 CPUUsage,
1248 MemoryUsage,
1250 GPUUsage,
1252 NetworkBandwidth,
1254 BufferUtilization,
1256 QualityScore,
1258 ErrorRate,
1260}
1261
1262#[derive(Debug, Clone, Serialize, Deserialize)]
1264pub struct PerformanceThresholds {
1265 pub min_frame_rate: f64,
1267 pub max_latency: Duration,
1269 pub max_cpu_usage: f64,
1271 pub max_memory_usage: f64,
1273 pub max_gpu_usage: Option<f64>,
1275 pub max_error_rate: f64,
1277}
1278
1279impl Default for PerformanceThresholds {
1280 fn default() -> Self {
1281 Self {
1282 min_frame_rate: 15.0,
1283 max_latency: Duration::from_millis(200),
1284 max_cpu_usage: 80.0,
1285 max_memory_usage: 80.0,
1286 max_gpu_usage: Some(80.0),
1287 max_error_rate: 0.05, }
1289 }
1290}
1291
1292impl PerformanceThresholds {
1293 #[must_use]
1295 pub fn strict() -> Self {
1296 Self {
1297 min_frame_rate: 25.0,
1298 max_latency: Duration::from_millis(50),
1299 max_cpu_usage: 60.0,
1300 max_memory_usage: 60.0,
1301 max_gpu_usage: Some(60.0),
1302 max_error_rate: 0.01, }
1304 }
1305
1306 #[must_use]
1308 pub fn balanced() -> Self {
1309 Self::default()
1310 }
1311
1312 #[must_use]
1314 pub fn relaxed() -> Self {
1315 Self {
1316 min_frame_rate: 10.0,
1317 max_latency: Duration::from_millis(500),
1318 max_cpu_usage: 95.0,
1319 max_memory_usage: 90.0,
1320 max_gpu_usage: Some(90.0),
1321 max_error_rate: 0.1, }
1323 }
1324}
1325
1326#[derive(Debug, Clone, Serialize, Deserialize)]
1328pub struct RealTimeErrorHandling {
1329 pub recovery_strategy: RecoveryStrategy,
1331 pub max_recovery_time: Duration,
1333 pub enable_fallback: bool,
1335 pub fallback_quality: ProcessingComplexity,
1337 pub circuit_breaker: CircuitBreakerConfig,
1339}
1340
1341impl Default for RealTimeErrorHandling {
1342 fn default() -> Self {
1343 Self {
1344 recovery_strategy: RecoveryStrategy::Degrade,
1345 max_recovery_time: Duration::from_millis(100),
1346 enable_fallback: true,
1347 fallback_quality: ProcessingComplexity::Low,
1348 circuit_breaker: CircuitBreakerConfig::default(),
1349 }
1350 }
1351}
1352
1353impl RealTimeErrorHandling {
1354 #[must_use]
1356 pub fn fast_recovery() -> Self {
1357 Self {
1358 recovery_strategy: RecoveryStrategy::Skip,
1359 max_recovery_time: Duration::from_millis(10),
1360 enable_fallback: true,
1361 fallback_quality: ProcessingComplexity::Low,
1362 circuit_breaker: CircuitBreakerConfig::sensitive(),
1363 }
1364 }
1365
1366 #[must_use]
1368 pub fn robust() -> Self {
1369 Self {
1370 recovery_strategy: RecoveryStrategy::Retry,
1371 max_recovery_time: Duration::from_millis(500),
1372 enable_fallback: true,
1373 fallback_quality: ProcessingComplexity::Medium,
1374 circuit_breaker: CircuitBreakerConfig::stable(),
1375 }
1376 }
1377
1378 #[must_use]
1380 pub fn graceful_degradation() -> Self {
1381 Self {
1382 recovery_strategy: RecoveryStrategy::Degrade,
1383 max_recovery_time: Duration::from_millis(200),
1384 enable_fallback: true,
1385 fallback_quality: ProcessingComplexity::Low,
1386 circuit_breaker: CircuitBreakerConfig::adaptive(),
1387 }
1388 }
1389}
1390
1391#[derive(Debug, Clone, Serialize, Deserialize)]
1393pub struct CircuitBreakerConfig {
1394 pub enabled: bool,
1396 pub failure_threshold: usize,
1398 pub success_threshold: usize,
1400 pub timeout: Duration,
1402 pub recovery_window: Duration,
1404}
1405
1406impl Default for CircuitBreakerConfig {
1407 fn default() -> Self {
1408 Self {
1409 enabled: true,
1410 failure_threshold: 5,
1411 success_threshold: 3,
1412 timeout: Duration::from_secs(30),
1413 recovery_window: Duration::from_secs(60),
1414 }
1415 }
1416}
1417
1418impl CircuitBreakerConfig {
1419 #[must_use]
1421 pub fn sensitive() -> Self {
1422 Self {
1423 enabled: true,
1424 failure_threshold: 2,
1425 success_threshold: 5,
1426 timeout: Duration::from_secs(10),
1427 recovery_window: Duration::from_secs(30),
1428 }
1429 }
1430
1431 #[must_use]
1433 pub fn stable() -> Self {
1434 Self {
1435 enabled: true,
1436 failure_threshold: 10,
1437 success_threshold: 2,
1438 timeout: Duration::from_secs(60),
1439 recovery_window: Duration::from_secs(120),
1440 }
1441 }
1442
1443 #[must_use]
1445 pub fn adaptive() -> Self {
1446 Self {
1447 enabled: true,
1448 failure_threshold: 5,
1449 success_threshold: 3,
1450 timeout: Duration::from_secs(30),
1451 recovery_window: Duration::from_secs(90),
1452 }
1453 }
1454}
1455
1456#[derive(Debug, Clone, PartialEq)]
1458pub enum RealTimeError {
1459 InvalidConfiguration(String),
1461 BufferOverflow,
1463 BufferUnderrun,
1465 LatencyExceeded { actual: Duration, limit: Duration },
1467 FrameRateTooLow { actual: f64, minimum: f64 },
1469 QualityDegradation { actual: f64, minimum: f64 },
1471 ResourceLimitExceeded(String),
1473 NetworkError(String),
1475 EncodingError(String),
1477 StreamingError(String),
1479}
1480
1481impl std::fmt::Display for RealTimeError {
1482 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1483 match self {
1484 Self::InvalidConfiguration(msg) => write!(f, "Invalid configuration: {msg}"),
1485 Self::BufferOverflow => write!(f, "Buffer overflow occurred"),
1486 Self::BufferUnderrun => write!(f, "Buffer underrun occurred"),
1487 Self::LatencyExceeded { actual, limit } => {
1488 write!(f, "Latency exceeded: {actual:?} > {limit:?}")
1489 }
1490 Self::FrameRateTooLow { actual, minimum } => {
1491 write!(f, "Frame rate too low: {actual} < {minimum}")
1492 }
1493 Self::QualityDegradation { actual, minimum } => {
1494 write!(f, "Quality degradation: {actual} < {minimum}")
1495 }
1496 Self::ResourceLimitExceeded(resource) => {
1497 write!(f, "Resource limit exceeded: {resource}")
1498 }
1499 Self::NetworkError(msg) => write!(f, "Network error: {msg}"),
1500 Self::EncodingError(msg) => write!(f, "Encoding error: {msg}"),
1501 Self::StreamingError(msg) => write!(f, "Streaming error: {msg}"),
1502 }
1503 }
1504}
1505
1506impl std::error::Error for RealTimeError {}
1507
1508#[allow(non_snake_case)]
1509#[cfg(test)]
1510mod tests {
1511 use super::*;
1512
1513 #[test]
1514 fn test_realtime_config_presets() {
1515 let low_latency = RealTimeProcessingConfig::low_latency();
1516 assert!(low_latency.enabled);
1517 assert_eq!(low_latency.target_fps, 60.0);
1518 assert_eq!(low_latency.max_latency, Duration::from_millis(16));
1519
1520 let high_quality = RealTimeProcessingConfig::high_quality_streaming();
1521 assert_eq!(high_quality.target_fps, 30.0);
1522 assert_eq!(high_quality.max_latency, Duration::from_millis(200));
1523
1524 let mobile = RealTimeProcessingConfig::mobile_optimized();
1525 assert_eq!(mobile.target_fps, 15.0);
1526 assert_eq!(mobile.max_latency, Duration::from_millis(300));
1527 }
1528
1529 #[test]
1530 fn test_buffer_management_config() {
1531 let minimal = BufferManagementConfig::minimal();
1532 assert_eq!(minimal.input_buffer_size, 1);
1533 assert_eq!(
1534 minimal.overflow_strategy,
1535 BufferOverflowStrategy::DropNewest
1536 );
1537
1538 let quality_focused = BufferManagementConfig::quality_focused();
1539 assert_eq!(quality_focused.input_buffer_size, 10);
1540 assert!(quality_focused.dynamic_resizing);
1541
1542 let memory_efficient = BufferManagementConfig::memory_efficient();
1543 assert_eq!(memory_efficient.input_buffer_size, 2);
1544 assert!(!memory_efficient.pre_allocation);
1545 }
1546
1547 #[test]
1548 fn test_adaptive_quality_config() {
1549 let responsive = AdaptiveQualityConfig::responsive();
1550 assert_eq!(responsive.adaptation_algorithm, AdaptationAlgorithm::PID);
1551 assert_eq!(responsive.quality_levels.len(), 2);
1552
1553 let quality_preserving = AdaptiveQualityConfig::quality_preserving();
1554 assert_eq!(
1555 quality_preserving.adaptation_algorithm,
1556 AdaptationAlgorithm::Predictive
1557 );
1558 assert_eq!(quality_preserving.quality_levels.len(), 3);
1559
1560 let bandwidth_aware = AdaptiveQualityConfig::bandwidth_aware();
1561 assert_eq!(
1562 bandwidth_aware.adaptation_algorithm,
1563 AdaptationAlgorithm::Fuzzy
1564 );
1565 }
1566
1567 #[test]
1568 fn test_quality_levels() {
1569 let low = QualityLevel::low();
1570 assert_eq!(low.complexity, ProcessingComplexity::Low);
1571 assert_eq!(low.expected_fps, 60.0);
1572
1573 let high = QualityLevel::high();
1574 assert_eq!(high.complexity, ProcessingComplexity::High);
1575 assert_eq!(high.expected_fps, 15.0);
1576
1577 assert!(low.validate().is_ok());
1578 assert!(high.validate().is_ok());
1579 }
1580
1581 #[test]
1582 fn test_streaming_config() {
1583 let low_latency = StreamingConfig::low_latency();
1584 assert_eq!(low_latency.protocol, StreamingProtocol::WebRTC);
1585 assert_eq!(low_latency.encoding.rate_control, RateControlMethod::CBR);
1586
1587 let high_quality = StreamingConfig::high_quality();
1588 assert_eq!(high_quality.protocol, StreamingProtocol::DASH);
1589 assert_eq!(high_quality.encoding.codec, VideoCodec::H265);
1590
1591 let mobile = StreamingConfig::mobile_friendly();
1592 assert_eq!(mobile.protocol, StreamingProtocol::HLS);
1593 assert_eq!(mobile.encoding.bitrate, 500_000);
1594 }
1595
1596 #[test]
1597 fn test_encoding_config() {
1598 let low_latency = EncodingConfig::low_latency();
1599 assert_eq!(low_latency.preset, EncodingPreset::UltraFast);
1600 assert_eq!(low_latency.keyframe_interval, 15);
1601
1602 let high_quality = EncodingConfig::high_quality();
1603 assert_eq!(high_quality.preset, EncodingPreset::Slow);
1604 assert_eq!(high_quality.codec, VideoCodec::H265);
1605
1606 assert!(low_latency.validate().is_ok());
1607 assert!(high_quality.validate().is_ok());
1608 }
1609
1610 #[test]
1611 fn test_network_optimization_config() {
1612 let latency_optimized = NetworkOptimizationConfig::latency_optimized();
1613 assert_eq!(
1614 latency_optimized.network_buffer_size,
1615 Duration::from_millis(100)
1616 );
1617 assert!(latency_optimized.bandwidth_prediction);
1618
1619 let quality_optimized = NetworkOptimizationConfig::quality_optimized();
1620 assert!(quality_optimized.fec_enabled);
1621 assert_eq!(
1622 quality_optimized.network_buffer_size,
1623 Duration::from_millis(3000)
1624 );
1625
1626 assert!(latency_optimized.validate().is_ok());
1627 assert!(quality_optimized.validate().is_ok());
1628 }
1629
1630 #[test]
1631 fn test_error_handling() {
1632 let fast_recovery = RealTimeErrorHandling::fast_recovery();
1633 assert_eq!(fast_recovery.recovery_strategy, RecoveryStrategy::Skip);
1634 assert_eq!(fast_recovery.max_recovery_time, Duration::from_millis(10));
1635
1636 let robust = RealTimeErrorHandling::robust();
1637 assert_eq!(robust.recovery_strategy, RecoveryStrategy::Retry);
1638 assert_eq!(robust.max_recovery_time, Duration::from_millis(500));
1639
1640 let graceful = RealTimeErrorHandling::graceful_degradation();
1641 assert_eq!(graceful.recovery_strategy, RecoveryStrategy::Degrade);
1642 }
1643
1644 #[test]
1645 fn test_realtime_error_display() {
1646 let error = RealTimeError::LatencyExceeded {
1647 actual: Duration::from_millis(200),
1648 limit: Duration::from_millis(100),
1649 };
1650 let error_str = error.to_string();
1651 assert!(error_str.contains("Latency exceeded"));
1652 assert!(error_str.contains("200ms"));
1653 assert!(error_str.contains("100ms"));
1654
1655 let error = RealTimeError::FrameRateTooLow {
1656 actual: 10.0,
1657 minimum: 20.0,
1658 };
1659 let error_str = error.to_string();
1660 assert!(error_str.contains("Frame rate too low"));
1661 assert!(error_str.contains("10"));
1662 assert!(error_str.contains("20"));
1663 }
1664
1665 #[test]
1666 fn test_config_validation() {
1667 let mut config = RealTimeProcessingConfig::default();
1668 config.enabled = true;
1669 assert!(config.validate().is_ok());
1670
1671 config.target_fps = 0.0;
1672 assert!(config.validate().is_err());
1673
1674 config.target_fps = 30.0;
1675 config.max_latency = Duration::from_secs(0);
1676 assert!(config.validate().is_err());
1677 }
1678}