Skip to content

Commit

Permalink
feat(client): ✨ Expose server version from client_core (#2387)
Browse files Browse the repository at this point in the history
  • Loading branch information
zmerp authored Sep 13, 2024
1 parent 74924a2 commit 49d68b5
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 68 deletions.
25 changes: 16 additions & 9 deletions alvr/client_core/src/c_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use std::{
static CLIENT_CORE_CONTEXT: OptLazy<ClientCoreContext> = alvr_common::lazy_mut_none();
static HUD_MESSAGE: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new("".into()));
static SETTINGS: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new("".into()));
static SERVER_VERSION: Lazy<Mutex<String>> = Lazy::new(|| Mutex::new("".into()));
#[allow(clippy::type_complexity)]
static NAL_QUEUE: Lazy<Mutex<VecDeque<(u64, [ViewParams; 2], Vec<u8>)>>> =
Lazy::new(|| Mutex::new(VecDeque::new()));
Expand Down Expand Up @@ -310,17 +311,17 @@ pub extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent) -> bool {

AlvrEvent::HudMessageUpdated
}
ClientCoreEvent::StreamingStarted {
settings,
negotiated_config,
} => {
*SETTINGS.lock() = serde_json::to_string(&settings).unwrap();
ClientCoreEvent::StreamingStarted(stream_config) => {
*SETTINGS.lock() = serde_json::to_string(&stream_config.settings).unwrap();
*SERVER_VERSION.lock() = stream_config.server_version.to_string();

AlvrEvent::StreamingStarted {
view_width: negotiated_config.view_resolution.x,
view_height: negotiated_config.view_resolution.y,
refresh_rate_hint: negotiated_config.refresh_rate_hint,
enable_foveated_encoding: negotiated_config.enable_foveated_encoding,
view_width: stream_config.negotiated_config.view_resolution.x,
view_height: stream_config.negotiated_config.view_resolution.y,
refresh_rate_hint: stream_config.negotiated_config.refresh_rate_hint,
enable_foveated_encoding: stream_config
.negotiated_config
.enable_foveated_encoding,
}
}
ClientCoreEvent::StreamingStopped => AlvrEvent::StreamingStopped,
Expand Down Expand Up @@ -378,6 +379,12 @@ pub extern "C" fn alvr_get_settings_json(buffer: *mut c_char) -> u64 {
string_to_c_str(buffer, &SETTINGS.lock())
}

/// Will be updated after receiving StreamingStarted event
#[no_mangle]
pub extern "C" fn alvr_get_server_version(buffer: *mut c_char) -> u64 {
string_to_c_str(buffer, &SERVER_VERSION.lock())
}

/// Call only with external decoder
/// Returns the number of bytes of the next nal, or 0 if there are no nals ready.
/// If out_nal or out_timestamp_ns is null, no nal is dequeued. Use to get the nal allocation size.
Expand Down
13 changes: 6 additions & 7 deletions alvr/client_core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,16 +190,15 @@ fn connection_pipeline(
proto_control_socket.recv::<StreamConfigPacket>(HANDSHAKE_ACTION_TIMEOUT)?;
dbg_connection!("connection_pipeline: stream config received");

let (settings, negotiated_config) =
alvr_packets::decode_stream_config(&config_packet).to_con()?;
let stream_config = alvr_packets::decode_stream_config(&config_packet).to_con()?;

ctx.uses_multimodal_protocol
.set(negotiated_config.use_multimodal_protocol);
.set(stream_config.negotiated_config.use_multimodal_protocol);

let streaming_start_event = ClientCoreEvent::StreamingStarted {
settings: Box::new(settings.clone()),
negotiated_config: negotiated_config.clone(),
};
let streaming_start_event = ClientCoreEvent::StreamingStarted(Box::new(stream_config.clone()));

let settings = stream_config.settings;
let negotiated_config = stream_config.negotiated_config;

*ctx.statistics_manager.lock() = Some(StatisticsManager::new(
settings.connection.statistics_history_size,
Expand Down
11 changes: 4 additions & 7 deletions alvr/client_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ use alvr_common::{
HEAD_ID,
};
use alvr_packets::{
BatteryInfo, ButtonEntry, ClientControlPacket, FaceData, NegotiatedStreamingConfig,
ReservedClientControlPacket, Tracking, ViewParams, ViewsConfig,
BatteryInfo, ButtonEntry, ClientControlPacket, FaceData, ReservedClientControlPacket,
StreamConfig, Tracking, ViewParams, ViewsConfig,
};
use alvr_session::{CodecType, Settings};
use alvr_session::CodecType;
use connection::ConnectionContext;
use serde::{Deserialize, Serialize};
use std::{
Expand All @@ -56,10 +56,7 @@ pub fn platform() -> Platform {
#[derive(Serialize, Deserialize)]
pub enum ClientCoreEvent {
UpdateHudMessage(String),
StreamingStarted {
settings: Box<Settings>,
negotiated_config: NegotiatedStreamingConfig,
},
StreamingStarted(Box<StreamConfig>),
StreamingStopped,
Haptics {
device_id: u64,
Expand Down
10 changes: 4 additions & 6 deletions alvr/client_mock/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,10 @@ fn client_thread(
ClientCoreEvent::UpdateHudMessage(message) => {
window_output.hud_message = message;
}
ClientCoreEvent::StreamingStarted {
negotiated_config, ..
} => {
window_output.fps = negotiated_config.refresh_rate_hint;
ClientCoreEvent::StreamingStarted(config) => {
window_output.fps = config.negotiated_config.refresh_rate_hint;
window_output.connected = true;
window_output.resolution = negotiated_config.view_resolution;
window_output.resolution = config.negotiated_config.view_resolution;

let context = Arc::clone(&client_core_context);
let streaming = Arc::clone(&streaming);
Expand All @@ -278,7 +276,7 @@ fn client_thread(
tracking_thread(
context,
streaming,
negotiated_config.refresh_rate_hint,
config.negotiated_config.refresh_rate_hint,
input,
)
}));
Expand Down
23 changes: 10 additions & 13 deletions alvr/client_openxr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod interaction;
mod lobby;
mod stream;

use crate::stream::StreamConfig;
use crate::stream::ParsedStreamConfig;
use alvr_client_core::{
graphics::GraphicsContext, ClientCapabilities, ClientCoreContext, ClientCoreEvent, Platform,
};
Expand Down Expand Up @@ -201,7 +201,7 @@ pub fn entry_point() {
let graphics_context = Rc::new(GraphicsContext::new_gl());

let mut last_lobby_message = String::new();
let mut stream_config = None::<StreamConfig>;
let mut parsed_stream_config = None::<ParsedStreamConfig>;

'session_loop: loop {
let xr_system = xr_instance
Expand Down Expand Up @@ -263,14 +263,14 @@ pub fn entry_point() {
let interaction_context = Arc::new(interaction::initialize_interaction(
&xr_context,
platform,
stream_config
parsed_stream_config
.as_ref()
.map(|c| c.prefers_multimodal_input)
.unwrap_or(false),
stream_config
parsed_stream_config
.as_ref()
.and_then(|c| c.face_sources_config.clone()),
stream_config
parsed_stream_config
.as_ref()
.and_then(|c| c.body_sources_config.clone()),
));
Expand Down Expand Up @@ -356,22 +356,19 @@ pub fn entry_point() {
last_lobby_message.clone_from(&message);
lobby.update_hud_message(&message);
}
ClientCoreEvent::StreamingStarted {
settings,
negotiated_config,
} => {
let new_config = StreamConfig::new(&settings, negotiated_config);
ClientCoreEvent::StreamingStarted(config) => {
let new_config = ParsedStreamConfig::new(&*config);

// combined_eye_gaze is a setting that needs to be enabled at session
// creation. Since HTC headsets don't support session reinitialization, skip
// all elements that need it, that is face and eye tracking.
if stream_config.as_ref() != Some(&new_config)
if parsed_stream_config.as_ref() != Some(&new_config)
&& !matches!(
platform,
Platform::Focus3 | Platform::XRElite | Platform::ViveUnknown
)
{
stream_config = Some(new_config);
parsed_stream_config = Some(new_config);

xr_session.request_exit().ok();
} else {
Expand All @@ -384,7 +381,7 @@ pub fn entry_point() {
&new_config,
));

stream_config = Some(new_config);
parsed_stream_config = Some(new_config);
}
}
ClientCoreEvent::StreamingStopped => {
Expand Down
41 changes: 25 additions & 16 deletions alvr/client_openxr/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use alvr_common::{
glam::{UVec2, Vec2},
Pose, RelaxedAtomic, HAND_LEFT_ID, HAND_RIGHT_ID,
};
use alvr_packets::{FaceData, NegotiatedStreamingConfig, ViewParams};
use alvr_packets::{FaceData, StreamConfig, ViewParams};
use alvr_session::{
BodyTrackingSourcesConfig, ClientsideFoveationConfig, ClientsideFoveationMode, EncoderConfig,
FaceTrackingSourcesConfig, FoveatedEncodingConfig, Settings,
FaceTrackingSourcesConfig, FoveatedEncodingConfig,
};
use openxr as xr;
use std::{
Expand All @@ -30,7 +30,7 @@ use std::{
const MAX_PREDICTION: Duration = Duration::from_millis(70);

#[derive(PartialEq)]
pub struct StreamConfig {
pub struct ParsedStreamConfig {
pub view_resolution: UVec2,
pub refresh_rate_hint: f32,
pub foveated_encoding_config: Option<FoveatedEncodingConfig>,
Expand All @@ -41,28 +41,37 @@ pub struct StreamConfig {
pub prefers_multimodal_input: bool,
}

impl StreamConfig {
pub fn new(settings: &Settings, negotiated_config: NegotiatedStreamingConfig) -> StreamConfig {
StreamConfig {
view_resolution: negotiated_config.view_resolution,
refresh_rate_hint: negotiated_config.refresh_rate_hint,
foveated_encoding_config: negotiated_config
impl ParsedStreamConfig {
pub fn new(config: &StreamConfig) -> ParsedStreamConfig {
ParsedStreamConfig {
view_resolution: config.negotiated_config.view_resolution,
refresh_rate_hint: config.negotiated_config.refresh_rate_hint,
foveated_encoding_config: config
.negotiated_config
.enable_foveated_encoding
.then(|| settings.video.foveated_encoding.as_option().cloned())
.then(|| config.settings.video.foveated_encoding.as_option().cloned())
.flatten(),
clientside_foveation_config: settings.video.clientside_foveation.as_option().cloned(),
encoder_config: settings.video.encoder_config.clone(),
face_sources_config: settings
clientside_foveation_config: config
.settings
.video
.clientside_foveation
.as_option()
.cloned(),
encoder_config: config.settings.video.encoder_config.clone(),
face_sources_config: config
.settings
.headset
.face_tracking
.as_option()
.map(|c| c.sources.clone()),
body_sources_config: settings
body_sources_config: config
.settings
.headset
.body_tracking
.as_option()
.map(|c| c.sources.clone()),
prefers_multimodal_input: settings
prefers_multimodal_input: config
.settings
.headset
.controllers
.as_option()
Expand Down Expand Up @@ -93,7 +102,7 @@ impl StreamContext {
gfx_ctx: Rc<GraphicsContext>,
interaction_ctx: Arc<InteractionContext>,
platform: Platform,
config: &StreamConfig,
config: &ParsedStreamConfig,
) -> StreamContext {
if xr_ctx.instance.exts().fb_display_refresh_rate.is_some() {
xr_ctx
Expand Down
19 changes: 13 additions & 6 deletions alvr/packets/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use alvr_common::{
anyhow::Result,
glam::{UVec2, Vec2},
semver::Version,
ConnectionState, DeviceMotion, Fov, LogEntry, LogSeverity, Pose, ToAny,
};
use alvr_session::{CodecType, SessionConfig, Settings};
Expand Down Expand Up @@ -136,9 +137,14 @@ pub fn encode_stream_config(
})
}

pub fn decode_stream_config(
packet: &StreamConfigPacket,
) -> Result<(Settings, NegotiatedStreamingConfig)> {
#[derive(Serialize, Deserialize, Clone)]
pub struct StreamConfig {
pub server_version: Version,
pub settings: Settings,
pub negotiated_config: NegotiatedStreamingConfig,
}

pub fn decode_stream_config(packet: &StreamConfigPacket) -> Result<StreamConfig> {
let mut session_config = SessionConfig::default();
session_config.merge_from_json(&json::from_str(&packet.session)?)?;
let settings = session_config.to_settings();
Expand All @@ -155,16 +161,17 @@ pub fn decode_stream_config(
let use_multimodal_protocol =
json::from_value(negotiated_json["use_multimodal_protocol"].clone()).unwrap_or(false);

Ok((
Ok(StreamConfig {
server_version: session_config.server_version,
settings,
NegotiatedStreamingConfig {
negotiated_config: NegotiatedStreamingConfig {
view_resolution,
refresh_rate_hint,
game_audio_sample_rate,
enable_foveated_encoding,
use_multimodal_protocol,
},
))
})
}

#[derive(Serialize, Deserialize, Clone)]
Expand Down
8 changes: 4 additions & 4 deletions alvr/session/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ Tilted: the world gets tilted when long pressing the oculus button. This is usef
pub body_tracking: Switch<BodyTrackingConfig>,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
#[derive(SettingsSchema, Serialize, Deserialize, Clone, Copy)]
#[schema(gui = "button_group")]
pub enum SocketProtocol {
#[schema(strings(display_name = "UDP"))]
Expand All @@ -1028,7 +1028,7 @@ pub struct DiscoveryConfig {
pub auto_trust_clients: bool,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
#[derive(SettingsSchema, Serialize, Deserialize, Clone, Copy)]
pub enum SocketBufferSize {
Default,
Maximum,
Expand Down Expand Up @@ -1099,7 +1099,7 @@ This could happen on TCP. A IDR frame is requested in this case."#
pub dscp: Option<DscpTos>,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
#[derive(SettingsSchema, Serialize, Deserialize, Clone, Copy)]
#[repr(u8)]
#[schema(gui = "button_group")]
pub enum DropProbability {
Expand All @@ -1108,7 +1108,7 @@ pub enum DropProbability {
High = 0x11,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
#[derive(SettingsSchema, Serialize, Deserialize, Clone, Copy)]
pub enum DscpTos {
BestEffort,

Expand Down

0 comments on commit 49d68b5

Please sign in to comment.