Skip to content

Commit

Permalink
fix(server_core): 🐛 Fix tracking timing jitter (#2285)
Browse files Browse the repository at this point in the history
  • Loading branch information
zmerp committed Aug 15, 2024
1 parent 068bfb5 commit e98940d
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 170 deletions.
13 changes: 9 additions & 4 deletions alvr/server_core/src/c_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ use std::{
collections::{HashMap, VecDeque},
ffi::{c_char, CStr, CString},
ptr,
sync::mpsc,
time::{Duration, Instant},
};

static SERVER_CORE_CONTEXT: Lazy<RwLock<Option<ServerCoreContext>>> =
Lazy::new(|| RwLock::new(None));
static EVENTS_RECEIVER: Lazy<Mutex<Option<mpsc::Receiver<ServerCoreEvent>>>> =
Lazy::new(|| Mutex::new(None));
static TRACKING_QUEUE: Lazy<Mutex<VecDeque<Tracking>>> = Lazy::new(|| Mutex::new(VecDeque::new()));
static BUTTONS_QUEUE: Lazy<Mutex<VecDeque<Vec<ButtonEntry>>>> =
Lazy::new(|| Mutex::new(VecDeque::new()));
Expand Down Expand Up @@ -251,7 +254,9 @@ pub extern "C" fn alvr_initialize_logging() {

#[no_mangle]
pub unsafe extern "C" fn alvr_initialize() -> AlvrTargetConfig {
*SERVER_CORE_CONTEXT.write() = Some(ServerCoreContext::new());
let (context, receiver) = ServerCoreContext::new();
*SERVER_CORE_CONTEXT.write() = Some(context);
*EVENTS_RECEIVER.lock() = Some(receiver);

let data_manager_lock = SERVER_DATA_MANAGER.read();
let restart_settings = &data_manager_lock.session().openvr_config;
Expand All @@ -272,9 +277,9 @@ pub unsafe extern "C" fn alvr_start_connection() {
}

#[no_mangle]
pub unsafe extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent) -> bool {
if let Some(context) = &*SERVER_CORE_CONTEXT.read() {
if let Some(event) = context.poll_event() {
pub unsafe extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent, timeout_ns: u64) -> bool {
if let Some(receiver) = &*EVENTS_RECEIVER.lock() {
if let Ok(event) = receiver.recv_timeout(Duration::from_nanos(timeout_ns)) {
match event {
ServerCoreEvent::SetOpenvrProperty { .. } => {} // implementation not needed
ServerCoreEvent::ClientConnected => {
Expand Down
102 changes: 49 additions & 53 deletions alvr/server_core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,14 +723,14 @@ fn connection_pipeline(

#[cfg(windows)]
if let Ok(id) = alvr_audio::get_windows_device_id(&device) {
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::SetOpenvrProperty {
ctx.events_sender
.send(ServerCoreEvent::SetOpenvrProperty {
device_id: *alvr_common::HEAD_ID,
prop: alvr_session::OpenvrProperty::AudioDefaultPlaybackDeviceId(
id,
),
})
.ok();
} else {
continue;
};
Expand All @@ -752,14 +752,14 @@ fn connection_pipeline(
if let Ok(id) = AudioDevice::new_output(None)
.and_then(|d| alvr_audio::get_windows_device_id(&d))
{
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::SetOpenvrProperty {
ctx.events_sender
.send(ServerCoreEvent::SetOpenvrProperty {
device_id: *alvr_common::HEAD_ID,
prop: alvr_session::OpenvrProperty::AudioDefaultPlaybackDeviceId(
id,
),
})
.ok();
}
}
}
Expand All @@ -775,12 +775,12 @@ fn connection_pipeline(

#[cfg(windows)]
if let Ok(id) = alvr_audio::get_windows_device_id(&source) {
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::SetOpenvrProperty {
ctx.events_sender
.send(ServerCoreEvent::SetOpenvrProperty {
device_id: *alvr_common::HEAD_ID,
prop: alvr_session::OpenvrProperty::AudioDefaultRecordingDeviceId(id),
})
.ok();
}

let client_hostname = client_hostname.clone();
Expand Down Expand Up @@ -952,8 +952,8 @@ fn connection_pipeline(
let mut hand_gesture_manager_lock = hand_gesture_manager.lock();

if let Some(hand_skeleton) = tracking.hand_skeletons[0] {
ctx.events_queue.lock().push_back(ServerCoreEvent::Buttons(
trigger_hand_gesture_actions(
ctx.events_sender
.send(ServerCoreEvent::Buttons(trigger_hand_gesture_actions(
gestures_button_mapping_manager,
*HAND_LEFT_ID,
&hand_gesture_manager_lock.get_active_gestures(
Expand All @@ -962,12 +962,12 @@ fn connection_pipeline(
*HAND_LEFT_ID,
),
gestures_config.only_touch,
),
));
)))
.ok();
}
if let Some(hand_skeleton) = tracking.hand_skeletons[1] {
ctx.events_queue.lock().push_back(ServerCoreEvent::Buttons(
trigger_hand_gesture_actions(
ctx.events_sender
.send(ServerCoreEvent::Buttons(trigger_hand_gesture_actions(
gestures_button_mapping_manager,
*HAND_RIGHT_ID,
&hand_gesture_manager_lock.get_active_gestures(
Expand All @@ -976,17 +976,16 @@ fn connection_pipeline(
*HAND_RIGHT_ID,
),
gestures_config.only_touch,
),
));
)))
.ok();
}
}

if let Some(stats) = &mut *ctx.statistics_manager.lock() {
stats.report_tracking_received(tracking.target_timestamp);

ctx.events_queue
.lock()
.push_back(ServerCoreEvent::Tracking {
ctx.events_sender
.send(ServerCoreEvent::Tracking {
tracking: Box::new(Tracking {
target_timestamp: tracking.target_timestamp,
device_motions: motions,
Expand All @@ -1002,7 +1001,8 @@ fn connection_pipeline(
face_data: tracking.face_data,
}),
controllers_pose_time_offset: stats.tracker_pose_time_offset(),
});
})
.ok();
}
}
}
Expand All @@ -1027,9 +1027,9 @@ fn connection_pipeline(
let decoder_latency = client_stats.video_decode;
let (network_latency, game_latency) = stats.report_statistics(client_stats);

ctx.events_queue
.lock()
.push_back(ServerCoreEvent::GameRenderLatencyFeedback(game_latency));
ctx.events_sender
.send(ServerCoreEvent::GameRenderLatencyFeedback(game_latency))
.ok();

let server_data_lock = SERVER_DATA_MANAGER.read();
ctx.bitrate_manager.lock().report_frame_latencies(
Expand Down Expand Up @@ -1121,14 +1121,14 @@ fn connection_pipeline(
let wh = area.x * area.y;
if wh.is_finite() && wh > 0.0 {
info!("Received new playspace with size: {}", area);
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::PlayspaceSync(area));
ctx.events_sender
.send(ServerCoreEvent::PlayspaceSync(area))
.ok();
} else {
warn!("Received invalid playspace size: {}", area);
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::PlayspaceSync(Vec2::new(2.0, 2.0)));
ctx.events_sender
.send(ServerCoreEvent::PlayspaceSync(Vec2::new(2.0, 2.0)))
.ok();
}
}
}
Expand All @@ -1139,23 +1139,18 @@ fn connection_pipeline(
.send(&ServerControlPacket::DecoderConfig(config))
.ok();
}
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::RequestIDR);
ctx.events_sender.send(ServerCoreEvent::RequestIDR).ok();
}
ClientControlPacket::VideoErrorReport => {
// legacy endpoint. todo: remove
if let Some(stats) = &mut *ctx.statistics_manager.lock() {
stats.report_packet_loss();
}
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::RequestIDR)
ctx.events_sender.send(ServerCoreEvent::RequestIDR).ok();
}
ClientControlPacket::ViewsConfig(config) => {
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::ViewsConfig(ViewsConfig {
ctx.events_sender
.send(ServerCoreEvent::ViewsConfig(ViewsConfig {
local_view_transforms: [
Pose {
position: Vec3::new(-config.ipd_m / 2., 0., 0.),
Expand All @@ -1167,16 +1162,17 @@ fn connection_pipeline(
},
],
fov: config.fov,
}));
}))
.ok();
}
ClientControlPacket::Battery(packet) => {
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::Battery(BatteryInfo {
ctx.events_sender
.send(ServerCoreEvent::Battery(BatteryInfo {
device_id: packet.device_id,
gauge_value: packet.gauge_value,
is_plugged: packet.is_plugged,
}));
}))
.ok();

if let Some(stats) = &mut *ctx.statistics_manager.lock() {
stats.report_battery(
Expand Down Expand Up @@ -1219,9 +1215,9 @@ fn connection_pipeline(
.collect::<Vec<_>>();

if !button_entries.is_empty() {
ctx.events_queue
.lock()
.push_back(ServerCoreEvent::Buttons(button_entries));
ctx.events_sender
.send(ServerCoreEvent::Buttons(button_entries))
.ok();
}
};
}
Expand Down Expand Up @@ -1352,9 +1348,9 @@ fn connection_pipeline(
ClientListAction::SetConnectionState(ConnectionState::Streaming),
);

ctx.events_queue
.lock()
.push_back(ServerCoreEvent::ClientConnected);
ctx.events_sender
.send(ServerCoreEvent::ClientConnected)
.ok();

alvr_common::wait_rwlock(&disconnect_notif, &mut server_data_lock);

Expand Down Expand Up @@ -1398,9 +1394,9 @@ fn connection_pipeline(
keepalive_thread.join().ok();
lifecycle_check_thread.join().ok();

ctx.events_queue
.lock()
.push_back(ServerCoreEvent::ClientDisconnected);
ctx.events_sender
.send(ServerCoreEvent::ClientDisconnected)
.ok();

Ok(())
}
Loading

0 comments on commit e98940d

Please sign in to comment.