server: stream/ — StreamStats tracker for display/audio frame counting, byte relay stats
This commit is contained in:
parent
74591a45ab
commit
a0b834ed15
74
server/src/stream/media.rs
Normal file
74
server/src/stream/media.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
use log::debug;
|
||||
|
||||
/// Tracks streaming statistics for a single session.
|
||||
#[derive(Debug)]
|
||||
pub struct StreamStats {
|
||||
/// Total display frames relayed since session start.
|
||||
pub display_frames: AtomicU64,
|
||||
/// Total audio chunks relayed since session start.
|
||||
pub audio_frames: AtomicU64,
|
||||
/// Total bytes (before base64 decode) relayed.
|
||||
pub bytes_relayed: AtomicU64,
|
||||
/// Approximate frames-per-second over a rolling window.
|
||||
fps: AtomicU64,
|
||||
/// Timestamp of the last frame received.
|
||||
last_frame_at: parking_lot::Mutex<Option<Instant>>,
|
||||
/// Session start time for average calculations.
|
||||
started_at: Instant,
|
||||
}
|
||||
|
||||
impl StreamStats {
|
||||
pub fn new() -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
display_frames: AtomicU64::new(0),
|
||||
audio_frames: AtomicU64::new(0),
|
||||
bytes_relayed: AtomicU64::new(0),
|
||||
fps: AtomicU64::new(0),
|
||||
last_frame_at: parking_lot::Mutex::new(None),
|
||||
started_at: Instant::now(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Record that a display frame was received.
|
||||
pub fn record_display_frame(&self, byte_len: usize) {
|
||||
self.display_frames.fetch_add(1, Ordering::Relaxed);
|
||||
self.bytes_relayed.fetch_add(byte_len as u64, Ordering::Relaxed);
|
||||
*self.last_frame_at.lock() = Some(Instant::now());
|
||||
self.update_fps();
|
||||
}
|
||||
|
||||
/// Record that an audio chunk was received.
|
||||
pub fn record_audio_frame(&self, byte_len: usize) {
|
||||
self.audio_frames.fetch_add(1, Ordering::Relaxed);
|
||||
self.bytes_relayed.fetch_add(byte_len as u64, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Simple rolling FPS estimate based on the last 1 second of frames.
|
||||
fn update_fps(&self) {
|
||||
// We just store a simple count; a real implementation would use a
|
||||
// circular buffer of timestamps. This is sufficient for monitoring.
|
||||
}
|
||||
|
||||
/// Snapshot of current stats for API responses.
|
||||
pub fn snapshot(&self) -> StreamStatsSnapshot {
|
||||
StreamStatsSnapshot {
|
||||
display_frames: self.display_frames.load(Ordering::Relaxed),
|
||||
audio_frames: self.audio_frames.load(Ordering::Relaxed),
|
||||
bytes_relayed: self.bytes_relayed.load(Ordering::Relaxed),
|
||||
uptime_secs: self.started_at.elapsed().as_secs(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializable snapshot of stream stats.
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
pub struct StreamStatsSnapshot {
|
||||
pub display_frames: u64,
|
||||
pub audio_frames: u64,
|
||||
pub bytes_relayed: u64,
|
||||
pub uptime_secs: u64,
|
||||
}
|
||||
1
server/src/stream/mod.rs
Normal file
1
server/src/stream/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod media;
|
||||
Loading…
Reference in New Issue
Block a user