lesavka/client/src/launcher/diagnostics/diagnostics_models.rs

186 lines
5.9 KiB
Rust

use serde::{Deserialize, Serialize};
use std::collections::VecDeque;
use std::fmt::Write as _;
use crate::uplink_telemetry::UpstreamStreamTelemetry;
use super::{
devices::CameraMode,
state::{CaptureSizeChoice, FeedSourcePreset, InputRouting, LauncherState, ViewMode},
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PerformanceSample {
pub rtt_ms: f32,
pub probe_spread_ms: f32,
pub input_latency_ms: f32,
pub probe_loss_pct: f32,
pub client_process_cpu_pct: f32,
pub server_process_cpu_pct: f32,
pub video_loss_pct: f32,
pub left_receive_fps: f32,
pub left_present_fps: f32,
pub left_server_fps: f32,
pub left_stream_spread_ms: f32,
pub left_packet_gap_peak_ms: f32,
pub left_present_gap_peak_ms: f32,
pub left_queue_depth: u32,
pub left_queue_peak: u32,
pub left_server_source_gap_peak_ms: f32,
pub left_server_send_gap_peak_ms: f32,
pub left_server_queue_peak: u32,
pub left_server_encoder_label: String,
pub left_decoder_label: String,
pub left_stream_caps_label: String,
pub left_decoded_caps_label: String,
pub left_rendered_caps_label: String,
pub right_receive_fps: f32,
pub right_present_fps: f32,
pub right_server_fps: f32,
pub right_stream_spread_ms: f32,
pub right_packet_gap_peak_ms: f32,
pub right_present_gap_peak_ms: f32,
pub right_queue_depth: u32,
pub right_queue_peak: u32,
pub right_server_source_gap_peak_ms: f32,
pub right_server_send_gap_peak_ms: f32,
pub right_server_queue_peak: u32,
pub right_server_encoder_label: String,
pub right_decoder_label: String,
pub right_stream_caps_label: String,
pub right_decoded_caps_label: String,
pub right_rendered_caps_label: String,
pub upstream_camera: UpstreamStreamTelemetry,
pub upstream_microphone: UpstreamStreamTelemetry,
pub dropped_frames: u64,
pub queue_depth: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiagnosticsLog {
capacity: usize,
history: VecDeque<PerformanceSample>,
}
impl DiagnosticsLog {
pub fn new(capacity: usize) -> Self {
let capacity = capacity.max(1);
Self {
capacity,
history: VecDeque::with_capacity(capacity),
}
}
pub fn record(&mut self, sample: PerformanceSample) {
if self.history.len() == self.capacity {
let _ = self.history.pop_front();
}
self.history.push_back(sample);
}
pub fn latest(&self) -> Option<&PerformanceSample> {
self.history.back()
}
pub fn len(&self) -> usize {
self.history.len()
}
pub fn is_empty(&self) -> bool {
self.history.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = &PerformanceSample> {
self.history.iter()
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct MediaChannelState {
pub camera: bool,
pub microphone: bool,
pub audio: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SnapshotReport {
pub client_version: String,
pub server_version: Option<String>,
pub server_available: bool,
pub routing: InputRouting,
pub view_mode: ViewMode,
pub remote_active: bool,
pub power_state: String,
pub client_process_cpu_pct: f32,
pub server_process_cpu_pct: f32,
pub preview_source: String,
pub client_display_limit: String,
pub left_surface: String,
pub left_feed_source: String,
pub left_capture_profile: String,
pub left_capture_transport: String,
pub left_breakout_profile: String,
pub left_decoder_label: String,
pub left_stream_spread_ms: f32,
pub left_packet_gap_peak_ms: f32,
pub left_present_gap_peak_ms: f32,
pub left_queue_depth: u32,
pub left_queue_peak: u32,
pub left_server_source_gap_peak_ms: f32,
pub left_server_send_gap_peak_ms: f32,
pub left_server_queue_peak: u32,
pub left_server_encoder_label: String,
pub left_stream_caps_label: String,
pub left_decoded_caps_label: String,
pub left_rendered_caps_label: String,
pub right_surface: String,
pub right_feed_source: String,
pub right_capture_profile: String,
pub right_capture_transport: String,
pub right_breakout_profile: String,
pub right_decoder_label: String,
pub right_stream_spread_ms: f32,
pub right_packet_gap_peak_ms: f32,
pub right_present_gap_peak_ms: f32,
pub right_queue_depth: u32,
pub right_queue_peak: u32,
pub right_server_source_gap_peak_ms: f32,
pub right_server_send_gap_peak_ms: f32,
pub right_server_queue_peak: u32,
pub right_server_encoder_label: String,
pub right_stream_caps_label: String,
pub right_decoded_caps_label: String,
pub right_rendered_caps_label: String,
pub selected_camera: Option<String>,
pub camera_quality_label: String,
pub selected_microphone: Option<String>,
pub selected_speaker: Option<String>,
pub media_channels: MediaChannelState,
pub audio_gain_label: String,
pub mic_gain_label: String,
pub upstream_camera: UpstreamStreamTelemetry,
pub upstream_microphone: UpstreamStreamTelemetry,
pub av_delivery_skew_ms: f32,
pub av_enqueue_skew_ms: f32,
pub av_sync_health: String,
pub calibration_available: bool,
pub calibration_profile: String,
pub calibration_source: String,
pub calibration_confidence: String,
pub calibration_detail: String,
pub calibration_updated_at: String,
pub factory_audio_offset_us: i64,
pub factory_video_offset_us: i64,
pub default_audio_offset_us: i64,
pub default_video_offset_us: i64,
pub active_audio_offset_us: i64,
pub active_video_offset_us: i64,
pub selected_keyboard: Option<String>,
pub selected_mouse: Option<String>,
pub status: String,
pub recent_samples: Vec<PerformanceSample>,
pub notes: Vec<String>,
pub recommendations: Vec<String>,
pub probe_command: String,
}