use serde::{Deserialize, Serialize};
use std::time::{Duration, Instant};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VisualSyncSettings {
pub latency_compensation: f32,
pub sync_tolerance: f32,
pub prediction_lookahead: f32,
pub frame_sync: bool,
pub vsync: bool,
}
pub(crate) struct VisualSyncState {
pub(crate) audio_timeline: Instant,
pub(crate) visual_timeline: Instant,
pub(crate) measured_latency: Duration,
pub(crate) frame_timing: Vec<FrameTiming>,
pub(crate) sync_quality: SyncQualityMetrics,
}
#[derive(Debug, Clone)]
pub(crate) struct FrameTiming {
pub(crate) timestamp: Instant,
pub(crate) duration: Duration,
pub(crate) av_offset: Duration,
pub(crate) quality_score: f32,
}
#[derive(Debug, Clone)]
pub(crate) struct SyncQualityMetrics {
pub(crate) avg_sync_error: f32,
pub(crate) max_sync_error: f32,
pub(crate) sync_stability: f32,
pub(crate) frames_in_sync: f32,
}
impl Default for VisualSyncSettings {
fn default() -> Self {
Self {
latency_compensation: 10.0, sync_tolerance: 5.0,
prediction_lookahead: 50.0,
frame_sync: true,
vsync: true,
}
}
}
impl VisualSyncState {
pub(crate) fn new() -> Self {
let now = Instant::now();
Self {
audio_timeline: now,
visual_timeline: now,
measured_latency: Duration::from_millis(10),
frame_timing: Vec::new(),
sync_quality: SyncQualityMetrics {
avg_sync_error: 0.0,
max_sync_error: 0.0,
sync_stability: 1.0,
frames_in_sync: 100.0,
},
}
}
}