238 lines
6.0 KiB
Rust
238 lines
6.0 KiB
Rust
use alvr_common::{
|
|
glam::{UVec2, Vec2},
|
|
DeviceMotion, Fov, LogEntry, LogSeverity, Pose,
|
|
};
|
|
use alvr_session::{CodecType, ConnectionState, SessionConfig};
|
|
use serde::{Deserialize, Serialize};
|
|
use std::{
|
|
fmt::{self, Debug},
|
|
net::IpAddr,
|
|
path::PathBuf,
|
|
time::Duration,
|
|
};
|
|
|
|
pub const TRACKING: u16 = 0;
|
|
pub const HAPTICS: u16 = 1;
|
|
pub const AUDIO: u16 = 2;
|
|
pub const VIDEO: u16 = 3;
|
|
pub const STATISTICS: u16 = 4;
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
pub struct VideoStreamingCapabilities {
|
|
pub default_view_resolution: UVec2,
|
|
pub supported_refresh_rates: Vec<f32>,
|
|
pub microphone_sample_rate: u32,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub enum ClientConnectionResult {
|
|
ConnectionAccepted {
|
|
client_protocol_id: u64,
|
|
display_name: String,
|
|
server_ip: IpAddr,
|
|
streaming_capabilities: Option<VideoStreamingCapabilities>,
|
|
},
|
|
ClientStandby,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct StreamConfigPacket {
|
|
pub session: String, // JSON session that allows for extrapolation
|
|
pub negotiated: String, // JSON dictionary containing negotiated configuration. Can be extended
|
|
// without a breaking protocol change, but entries can't be removed.
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
pub struct DecoderInitializationConfig {
|
|
pub codec: CodecType,
|
|
pub config_buffer: Vec<u8>, // e.g. SPS + PPS NALs
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub enum ServerControlPacket {
|
|
StartStream,
|
|
InitializeDecoder(DecoderInitializationConfig),
|
|
Restarting,
|
|
KeepAlive,
|
|
ServerPredictionAverage(Duration), // todo: remove
|
|
Reserved(String),
|
|
ReservedBuffer(Vec<u8>),
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
pub struct ViewsConfig {
|
|
// Note: the head-to-eye transform is always a translation along the x axis
|
|
pub ipd_m: f32,
|
|
pub fov: [Fov; 2],
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
pub struct BatteryPacket {
|
|
pub device_id: u64,
|
|
pub gauge_value: f32, // range [0, 1]
|
|
pub is_plugged: bool,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
|
|
pub enum ButtonValue {
|
|
Binary(bool),
|
|
Scalar(f32),
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct ButtonEntry {
|
|
pub path_id: u64,
|
|
pub value: ButtonValue,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub enum ClientControlPacket {
|
|
PlayspaceSync(Option<Vec2>),
|
|
RequestIdr,
|
|
KeepAlive,
|
|
StreamReady, // This flag notifies the server the client streaming socket is ready listening
|
|
ViewsConfig(ViewsConfig),
|
|
Battery(BatteryPacket),
|
|
VideoErrorReport, // legacy
|
|
Buttons(Vec<ButtonEntry>),
|
|
ActiveInteractionProfile { device_id: u64, profile_id: u64 },
|
|
Log { level: LogSeverity, message: String },
|
|
Reserved(String),
|
|
ReservedBuffer(Vec<u8>),
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Default)]
|
|
pub struct FaceData {
|
|
pub eye_gazes: [Option<Pose>; 2],
|
|
pub fb_face_expression: Option<Vec<f32>>, // issue: Serialize does not support [f32; 63]
|
|
pub htc_eye_expression: Option<Vec<f32>>,
|
|
pub htc_lip_expression: Option<Vec<f32>>, // issue: Serialize does not support [f32; 37]
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct VideoPacketHeader {
|
|
pub timestamp: Duration,
|
|
pub is_idr: bool,
|
|
}
|
|
|
|
// Note: face_data does not respect target_timestamp.
|
|
#[derive(Serialize, Deserialize, Default)]
|
|
pub struct Tracking {
|
|
pub target_timestamp: Duration,
|
|
pub device_motions: Vec<(u64, DeviceMotion)>,
|
|
pub hand_skeletons: [Option<[Pose; 26]>; 2],
|
|
pub face_data: FaceData,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
pub struct Haptics {
|
|
pub device_id: u64,
|
|
pub duration: Duration,
|
|
pub frequency: f32,
|
|
pub amplitude: f32,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
pub struct AudioDevicesList {
|
|
pub output: Vec<String>,
|
|
pub input: Vec<String>,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone)]
|
|
pub enum PathSegment {
|
|
Name(String),
|
|
Index(usize),
|
|
}
|
|
|
|
impl Debug for PathSegment {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
PathSegment::Name(name) => write!(f, "{}", name),
|
|
PathSegment::Index(index) => write!(f, "[{}]", index),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&str> for PathSegment {
|
|
fn from(value: &str) -> Self {
|
|
PathSegment::Name(value.to_owned())
|
|
}
|
|
}
|
|
|
|
impl From<String> for PathSegment {
|
|
fn from(value: String) -> Self {
|
|
PathSegment::Name(value)
|
|
}
|
|
}
|
|
|
|
impl From<usize> for PathSegment {
|
|
fn from(value: usize) -> Self {
|
|
PathSegment::Index(value)
|
|
}
|
|
}
|
|
|
|
// todo: support indices
|
|
pub fn parse_path(path: &str) -> Vec<PathSegment> {
|
|
path.split('.').map(|s| s.into()).collect()
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
pub enum ClientListAction {
|
|
AddIfMissing {
|
|
trusted: bool,
|
|
manual_ips: Vec<IpAddr>,
|
|
},
|
|
SetDisplayName(String),
|
|
Trust,
|
|
SetManualIps(Vec<IpAddr>),
|
|
RemoveEntry,
|
|
UpdateCurrentIp(Option<IpAddr>),
|
|
SetConnectionState(ConnectionState),
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Default, Clone)]
|
|
pub struct ClientStatistics {
|
|
pub target_timestamp: Duration, // identifies the frame
|
|
pub frame_interval: Duration,
|
|
pub video_decode: Duration,
|
|
pub video_decoder_queue: Duration,
|
|
pub rendering: Duration,
|
|
pub vsync_queue: Duration,
|
|
pub total_pipeline_latency: Duration,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
pub struct PathValuePair {
|
|
pub path: Vec<PathSegment>,
|
|
pub value: serde_json::Value,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
pub enum FirewallRulesAction {
|
|
Add,
|
|
Remove,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
pub enum ServerRequest {
|
|
Log(LogEntry),
|
|
GetSession,
|
|
UpdateSession(Box<SessionConfig>),
|
|
SetValues(Vec<PathValuePair>),
|
|
UpdateClientList {
|
|
hostname: String,
|
|
action: ClientListAction,
|
|
},
|
|
GetAudioDevices,
|
|
CaptureFrame,
|
|
InsertIdr,
|
|
StartRecording,
|
|
StopRecording,
|
|
FirewallRules(FirewallRulesAction),
|
|
RegisterAlvrDriver,
|
|
UnregisterDriver(PathBuf),
|
|
GetDriverList,
|
|
RestartSteamvr,
|
|
ShutdownSteamvr,
|
|
}
|