Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(server_core): 🐛 Fix tracking timing jitter #2285

Merged
merged 1 commit into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
The-personified-devil marked this conversation as resolved.
Show resolved Hide resolved
.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
Loading