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

feat(dashboard): Client overrides for OLED-pertinent encoding settings (10-bit, encoding gamma, etc) #2442

Merged
merged 1 commit into from
Oct 15, 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
12 changes: 12 additions & 0 deletions alvr/client_core/src/c_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub struct AlvrClientCapabilities {
encoder_high_profile: bool,
encoder_10_bits: bool,
encoder_av1: bool,
prefer_10bit: bool,
prefer_full_range: bool,
preferred_encoding_gamma: f32,
prefer_hdr: bool,
}

#[repr(u8)]
Expand All @@ -57,7 +61,9 @@ pub enum AlvrEvent {
view_width: u32,
view_height: u32,
refresh_rate_hint: f32,
encoding_gamma: f32,
enable_foveated_encoding: bool,
enable_hdr: bool,
},
StreamingStopped,
Haptics {
Expand Down Expand Up @@ -283,6 +289,10 @@ pub unsafe extern "C" fn alvr_initialize(capabilities: AlvrClientCapabilities) {
encoder_high_profile: capabilities.encoder_high_profile,
encoder_10_bits: capabilities.encoder_10_bits,
encoder_av1: capabilities.encoder_av1,
prefer_10bit: capabilities.prefer_10bit,
prefer_full_range: capabilities.prefer_full_range,
preferred_encoding_gamma: capabilities.preferred_encoding_gamma,
prefer_hdr: capabilities.prefer_hdr,
};
*CLIENT_CORE_CONTEXT.lock() = Some(ClientCoreContext::new(capabilities));
}
Expand Down Expand Up @@ -328,9 +338,11 @@ pub extern "C" fn alvr_poll_event(out_event: *mut AlvrEvent) -> bool {
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,
encoding_gamma: stream_config.negotiated_config.encoding_gamma,
enable_foveated_encoding: stream_config
.negotiated_config
.enable_foveated_encoding,
enable_hdr: stream_config.negotiated_config.enable_hdr,
}
}
ClientCoreEvent::StreamingStopped => AlvrEvent::StreamingStopped,
Expand Down
4 changes: 4 additions & 0 deletions alvr/client_core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ fn connection_pipeline(
encoder_10_bits: capabilities.encoder_10_bits,
encoder_av1: capabilities.encoder_av1,
multimodal_protocol: true,
prefer_10bit: capabilities.prefer_10bit,
prefer_full_range: capabilities.prefer_full_range,
preferred_encoding_gamma: capabilities.preferred_encoding_gamma,
prefer_hdr: capabilities.prefer_hdr,
})
.to_con()?,
),
Expand Down
4 changes: 4 additions & 0 deletions alvr/client_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ pub struct ClientCapabilities {
pub encoder_high_profile: bool,
pub encoder_10_bits: bool,
pub encoder_av1: bool,
pub prefer_10bit: bool,
pub prefer_full_range: bool,
pub preferred_encoding_gamma: f32,
pub prefer_hdr: bool,
}

pub struct ClientCoreContext {
Expand Down
4 changes: 4 additions & 0 deletions alvr/client_mock/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ fn client_thread(
encoder_high_profile: false,
encoder_10_bits: false,
encoder_av1: false,
prefer_10bit: false,
prefer_full_range: true,
preferred_encoding_gamma: 1.0,
prefer_hdr: false,
};
let client_core_context = Arc::new(ClientCoreContext::new(capabilities));

Expand Down
4 changes: 4 additions & 0 deletions alvr/client_openxr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ pub fn entry_point() {
encoder_high_profile: platform != Platform::Unknown,
encoder_10_bits: platform != Platform::Unknown,
encoder_av1: matches!(platform, Platform::Quest3 | Platform::Quest3S),
prefer_10bit: false,
prefer_full_range: true,
preferred_encoding_gamma: 1.0,
prefer_hdr: false,
};
let core_context = Arc::new(ClientCoreContext::new(capabilities));

Expand Down
16 changes: 8 additions & 8 deletions alvr/client_openxr/src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ const DECODER_MAX_TIMEOUT_MULTIPLIER: f32 = 0.8;
pub struct ParsedStreamConfig {
pub view_resolution: UVec2,
pub refresh_rate_hint: f32,
pub encoding_gamma: f32,
pub enable_hdr: bool,
pub foveated_encoding_config: Option<FoveatedEncodingConfig>,
pub clientside_foveation_config: Option<ClientsideFoveationConfig>,
pub encoder_config: EncoderConfig,
pub face_sources_config: Option<FaceTrackingSourcesConfig>,
pub body_sources_config: Option<BodyTrackingSourcesConfig>,
pub prefers_multimodal_input: bool,
Expand All @@ -51,6 +52,8 @@ impl ParsedStreamConfig {
ParsedStreamConfig {
view_resolution: config.negotiated_config.view_resolution,
refresh_rate_hint: config.negotiated_config.refresh_rate_hint,
encoding_gamma: config.negotiated_config.encoding_gamma,
enable_hdr: config.negotiated_config.enable_hdr,
foveated_encoding_config: config
.negotiated_config
.enable_foveated_encoding
Expand All @@ -62,7 +65,6 @@ impl ParsedStreamConfig {
.clientside_foveation
.as_option()
.cloned(),
encoder_config: config.settings.video.encoder_config.clone(),
face_sources_config: config
.settings
.headset
Expand Down Expand Up @@ -153,8 +155,7 @@ impl StreamContext {
None
};

let format =
graphics::swapchain_format(&gfx_ctx, &xr_ctx.session, config.encoder_config.enable_hdr);
let format = graphics::swapchain_format(&gfx_ctx, &xr_ctx.session, config.enable_hdr);

let swapchains = [
graphics::create_swapchain(
Expand Down Expand Up @@ -192,10 +193,9 @@ impl StreamContext {
],
format,
config.foveated_encoding_config.clone(),
platform != Platform::Lynx
&& !((platform.is_pico()) && config.encoder_config.enable_hdr),
!config.encoder_config.enable_hdr,
config.encoder_config.encoding_gamma,
platform != Platform::Lynx && !((platform.is_pico()) && config.enable_hdr),
!config.enable_hdr,
config.encoding_gamma,
);

core_ctx.send_playspace(
Expand Down
16 changes: 16 additions & 0 deletions alvr/packets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub struct VideoStreamingCapabilities {
pub encoder_10_bits: bool,
pub encoder_av1: bool,
pub multimodal_protocol: bool,
pub prefer_10bit: bool,
pub prefer_full_range: bool,
pub preferred_encoding_gamma: f32,
pub prefer_hdr: bool,
}

// Nasty workaround to make the packet extensible, pushing the limits of protocol compatibility
Expand Down Expand Up @@ -95,6 +99,12 @@ pub fn decode_video_streaming_capabilities(
encoder_10_bits: caps_json["encoder_10_bits"].as_bool().unwrap_or(true),
encoder_av1: caps_json["encoder_av1"].as_bool().unwrap_or(true),
multimodal_protocol: caps_json["multimodal_protocol"].as_bool().unwrap_or(false),
prefer_10bit: caps_json["prefer_10bit"].as_bool().unwrap_or(false),
prefer_full_range: caps_json["prefer_full_range"].as_bool().unwrap_or(true),
preferred_encoding_gamma: caps_json["preferred_encoding_gamma"]
.as_f64()
.unwrap_or(1.0) as f32,
prefer_hdr: caps_json["prefer_hdr"].as_bool().unwrap_or(false),
})
}

Expand All @@ -119,6 +129,8 @@ pub struct NegotiatedStreamingConfig {
// This is needed to detect when to use SteamVR hand trackers. This does NOT imply if multimodal
// input is supported
pub use_multimodal_protocol: bool,
pub encoding_gamma: f32,
pub enable_hdr: bool,
}

#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -160,6 +172,8 @@ pub fn decode_stream_config(packet: &StreamConfigPacket) -> Result<StreamConfig>
.unwrap_or_else(|_| settings.video.foveated_encoding.enabled());
let use_multimodal_protocol =
json::from_value(negotiated_json["use_multimodal_protocol"].clone()).unwrap_or(false);
let encoding_gamma = json::from_value(negotiated_json["encoding_gamma"].clone()).unwrap_or(1.0);
let enable_hdr = json::from_value(negotiated_json["enable_hdr"].clone()).unwrap_or(false);

Ok(StreamConfig {
server_version: session_config.server_version,
Expand All @@ -170,6 +184,8 @@ pub fn decode_stream_config(packet: &StreamConfigPacket) -> Result<StreamConfig>
game_audio_sample_rate,
enable_foveated_encoding,
use_multimodal_protocol,
encoding_gamma,
enable_hdr,
},
})
}
Expand Down
52 changes: 45 additions & 7 deletions alvr/server_core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,16 +562,49 @@ fn connection_pipeline(
initial_settings.video.encoder_config.h264_profile
};

let enable_10_bits_encoding = if initial_settings.video.encoder_config.use_10bit {
let enable = streaming_caps.encoder_10_bits;
let mut enable_10_bits_encoding = if initial_settings
.video
.encoder_config
.server_overrides_use_10bit
{
initial_settings.video.encoder_config.use_10bit
} else {
streaming_caps.prefer_10bit
};

if !enable {
warn!("10 bits encoding is not supported by the client.");
}
if enable_10_bits_encoding && !streaming_caps.encoder_10_bits {
warn!("10 bits encoding is not supported by the client.");
enable_10_bits_encoding = false
}

enable
let use_full_range = if initial_settings
.video
.encoder_config
.server_overrides_use_full_range
{
initial_settings.video.encoder_config.use_full_range
} else {
false
streaming_caps.prefer_full_range
};

let enable_hdr = if initial_settings
.video
.encoder_config
.server_overrides_enable_hdr
{
initial_settings.video.encoder_config.enable_hdr
} else {
streaming_caps.prefer_hdr
};

let encoding_gamma = if initial_settings
.video
.encoder_config
.server_overrides_encoding_gamma
{
initial_settings.video.encoder_config.encoding_gamma
} else {
streaming_caps.preferred_encoding_gamma
};

let codec = if initial_settings.video.preferred_codec == CodecType::AV1 {
Expand Down Expand Up @@ -635,6 +668,8 @@ fn connection_pipeline(
game_audio_sample_rate,
enable_foveated_encoding,
use_multimodal_protocol: streaming_caps.multimodal_protocol,
encoding_gamma: encoding_gamma,
enable_hdr: enable_hdr,
},
)
.to_con()?;
Expand All @@ -652,6 +687,9 @@ fn connection_pipeline(
new_openvr_config.enable_foveated_encoding = enable_foveated_encoding;
new_openvr_config.h264_profile = encoder_profile as _;
new_openvr_config.use_10bit_encoder = enable_10_bits_encoding;
new_openvr_config.use_full_range_encoding = use_full_range;
new_openvr_config.enable_hdr = enable_hdr;
new_openvr_config.encoding_gamma = encoding_gamma;
new_openvr_config.codec = codec as _;

if session_manager_lock.session().openvr_config != new_openvr_config {
Expand Down
42 changes: 37 additions & 5 deletions alvr/session/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,33 +224,61 @@ CABAC produces better compression but it's significantly slower and may lead to
pub entropy_coding: EntropyCoding,

#[schema(strings(
display_name = "10 bit encoding",
help = "Sets the encoder to use 10 bits per channel instead of 8. Does not work on Linux with Nvidia"
display_name = "10-bit encoding",
help = "Sets the encoder to use 10 bits per channel instead of 8, if the client has no preference. Does not work on Linux with Nvidia"
))]
#[schema(flag = "steamvr-restart")]
pub use_10bit: bool,

#[schema(strings(
display_name = "Override headset's preference for 10-bit encoding",
help = "Override the headset client's preference for 10-bit encoding."
))]
#[schema(flag = "steamvr-restart")]
pub server_overrides_use_10bit: bool,

#[schema(strings(
display_name = "Full range color",
help = "Sets the encoder to encode full range RGB (0-255) instead of limited/video range RGB (16-235)"
help = "Sets the encoder to encode full range RGB (0-255) instead of limited/video range RGB (16-235), if the client has no preference"
))]
#[schema(flag = "steamvr-restart")]
pub use_full_range: bool,

#[schema(strings(
display_name = "Override headset's preference for full range color",
help = "The server will override the headset client's preference for full range color."
))]
#[schema(flag = "steamvr-restart")]
pub server_overrides_use_full_range: bool,

#[schema(strings(
display_name = "Encoding Gamma",
help = "To prioritize darker pixels at the expense of potentially additional banding in midtones, set to 2.2. To allow the encoder to decide priority on its own, set to 1.0."
))]
#[schema(flag = "steamvr-restart")]
pub encoding_gamma: f32,

#[schema(strings(
display_name = "Override headset's preference for encoding gamma",
help = "The server will override the headset client's preference for encoding gamma."
))]
#[schema(flag = "steamvr-restart")]
pub server_overrides_encoding_gamma: bool,

#[schema(strings(
display_name = "Enable HDR",
help = "Composite VR layers to an RGBA float16 framebuffer, and do sRGB/YUV conversions in shader code."
help = "If the client has no preference, enables compositing VR layers to an RGBA float16 framebuffer, and doing sRGB/YUV conversions in shader code."
))]
#[schema(flag = "steamvr-restart")]
pub enable_hdr: bool,

#[schema(strings(
display_name = "Override headset's preference for HDR",
help = "The server will override the headset client's preference for HDR."
))]
#[schema(flag = "steamvr-restart")]
pub server_overrides_enable_hdr: bool,

#[schema(strings(
display_name = "Force HDR sRGB Correction",
help = "Forces sRGB correction on all composited SteamVR layers. Useful if an HDR-injected game is too dark."
Expand Down Expand Up @@ -1332,9 +1360,13 @@ pub fn session_settings_default() -> SettingsDefault {
variant: EntropyCodingDefaultVariant::Cavlc,
},
use_10bit: false,
server_overrides_use_10bit: false,
use_full_range: true,
server_overrides_use_full_range: false,
encoding_gamma: 1.0,
server_overrides_encoding_gamma: false,
enable_hdr: false,
server_overrides_enable_hdr: false,
force_hdr_srgb_correction: false,
clamp_hdr_extended_range: false,
nvenc: NvencConfigDefault {
Expand Down Expand Up @@ -1443,7 +1475,7 @@ pub fn session_settings_default() -> SettingsDefault {
},
force_software_decoder: false,
color_correction: SwitchDefault {
enabled: true,
enabled: false,
content: ColorCorrectionConfigDefault {
brightness: 0.,
contrast: 0.,
Expand Down
Loading