mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
@@ -1,82 +1,8 @@
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use hbb_common::{
|
||||
log,
|
||||
message_proto::{video_frame, VideoFrame, Message, VoiceCallRequest, VoiceCallResponse}, get_time,
|
||||
get_time,
|
||||
message_proto::{video_frame, Message, VideoFrame, VoiceCallRequest, VoiceCallResponse},
|
||||
};
|
||||
|
||||
const MAX_LATENCY: i64 = 500;
|
||||
const MIN_LATENCY: i64 = 100;
|
||||
|
||||
/// Latency controller for syncing audio with the video stream.
|
||||
/// Only sync the audio to video, not the other way around.
|
||||
#[derive(Debug)]
|
||||
pub struct LatencyController {
|
||||
last_video_remote_ts: i64, // generated on remote device
|
||||
update_time: Instant,
|
||||
allow_audio: bool,
|
||||
audio_only: bool
|
||||
}
|
||||
|
||||
impl Default for LatencyController {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
last_video_remote_ts: Default::default(),
|
||||
update_time: Instant::now(),
|
||||
allow_audio: Default::default(),
|
||||
audio_only: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LatencyController {
|
||||
/// Create a new latency controller.
|
||||
pub fn new() -> Arc<Mutex<LatencyController>> {
|
||||
Arc::new(Mutex::new(LatencyController::default()))
|
||||
}
|
||||
|
||||
/// Set whether this [LatencyController] should be working in audio only mode.
|
||||
pub fn set_audio_only(&mut self, only: bool) {
|
||||
self.audio_only = only;
|
||||
}
|
||||
|
||||
/// Update the latency controller with the latest video timestamp.
|
||||
pub fn update_video(&mut self, timestamp: i64) {
|
||||
self.last_video_remote_ts = timestamp;
|
||||
self.update_time = Instant::now();
|
||||
}
|
||||
|
||||
/// Check if the audio should be played based on the current latency.
|
||||
pub fn check_audio(&mut self, timestamp: i64) -> bool {
|
||||
// Compute audio latency.
|
||||
let expected = self.update_time.elapsed().as_millis() as i64 + self.last_video_remote_ts;
|
||||
let latency = if self.audio_only {
|
||||
expected
|
||||
} else {
|
||||
expected - timestamp
|
||||
};
|
||||
// Set MAX and MIN, avoid fixing too frequently.
|
||||
if self.allow_audio {
|
||||
if latency.abs() > MAX_LATENCY {
|
||||
log::debug!("LATENCY > {}ms cut off, latency:{}", MAX_LATENCY, latency);
|
||||
self.allow_audio = false;
|
||||
}
|
||||
} else {
|
||||
if latency.abs() < MIN_LATENCY {
|
||||
log::debug!("LATENCY < {}ms resume, latency:{}", MIN_LATENCY, latency);
|
||||
self.allow_audio = true;
|
||||
}
|
||||
}
|
||||
// No video frame here, which means the update time is not up to date.
|
||||
// We manually update the time here.
|
||||
self.update_time = Instant::now();
|
||||
self.allow_audio
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum CodecFormat {
|
||||
VP9,
|
||||
@@ -135,4 +61,4 @@ pub fn new_voice_call_response(request_timestamp: i64, accepted: bool) -> Messag
|
||||
let mut msg = Message::new();
|
||||
msg.set_voice_call_response(resp);
|
||||
msg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,13 +318,11 @@ impl<T: InvokeUiSession> Remote<T> {
|
||||
let mut msg = Message::new();
|
||||
msg.set_audio_frame(frame.clone());
|
||||
tx_audio.send(Data::Message(msg)).ok();
|
||||
log::debug!("send audio frame {}", frame.timestamp);
|
||||
}
|
||||
Some(message::Union::Misc(misc)) => {
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc.clone());
|
||||
tx_audio.send(Data::Message(msg)).ok();
|
||||
log::debug!("send audio misc {:?}", misc.audio_format());
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user