Skip to content

Commit

Permalink
Allow selecting h264 profile with a bit more precision, migrate setti…
Browse files Browse the repository at this point in the history
…ng to OpenvrSettings
  • Loading branch information
20kdc committed Dec 22, 2023
1 parent c8b4358 commit 98855a9
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 24 deletions.
6 changes: 6 additions & 0 deletions alvr/server/cpp/ALVR-common/packet_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ enum ALVR_CODEC {
ALVR_CODEC_H265 = 1,
};

enum ALVR_H264_PROFILE {
ALVR_H264_PROFILE_HIGH = 0,
ALVR_H264_PROFILE_MAIN = 1,
ALVR_H264_PROFILE_BASELINE = 2,
};

enum ALVR_RATE_CONTROL_METHOD {
ALVR_CBR = 0,
ALVR_VBR = 1,
Expand Down
6 changes: 1 addition & 5 deletions alvr/server/cpp/alvr_server/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void Settings::Load() {
m_sharpening = (float)config.get("sharpening").get<double>();

m_codec = (int32_t)config.get("codec").get<int64_t>();
m_h264Profile = (int32_t)config.get("h264_profile").get<int64_t>();
m_rateControlMode = (uint32_t)config.get("rate_control_mode").get<int64_t>();
m_fillerData = config.get("filler_data").get<bool>();
m_entropyCoding = (uint32_t)config.get("entropy_coding").get<int64_t>();
Expand Down Expand Up @@ -105,11 +106,6 @@ void Settings::Load() {
m_enableControllers = config.get("controllers_enabled").get<bool>();
m_controllerIsTracker = config.get("controller_is_tracker").get<bool>();

auto sessionSettings = v.get("session_settings");
auto sessionVideo = sessionSettings.get("video");

m_h264UseBaselineProfile = sessionVideo.get("h264_use_baseline_profile").get<bool>();

Info("Render Target: %d %d\n", m_renderWidth, m_renderHeight);
Info("Refresh Rate: %d\n", m_refreshRate);
m_loaded = true;
Expand Down
2 changes: 1 addition & 1 deletion alvr/server/cpp/alvr_server/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Settings {
float m_sharpening;

int m_codec;
bool m_h264UseBaselineProfile;
int m_h264Profile;
bool m_use10bitEncoder;
bool m_enableVbaq;
bool m_usePreproc;
Expand Down
12 changes: 11 additions & 1 deletion alvr/server/cpp/platform/linux/EncodePipelineNvEnc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,18 @@ alvr::EncodePipelineNvEnc::EncodePipelineNvEnc(Renderer *render,
break;
}

if (settings.m_h264UseBaselineProfile)
switch (settings.m_h264Profile) {
case ALVR_H264_PROFILE_BASELINE:
av_opt_set(encoder_ctx->priv_data, "profile", "baseline", 0);
break;
case ALVR_H264_PROFILE_MAIN:
av_opt_set(encoder_ctx->priv_data, "profile", "main", 0);
break;
default:
case ALVR_H264_PROFILE_HIGH:
av_opt_set(encoder_ctx->priv_data, "profile", "high", 0);
break;
}

char preset[] = "p0";
// replace 0 with preset number
Expand Down
14 changes: 13 additions & 1 deletion alvr/server/cpp/platform/linux/EncodePipelineSW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ alvr::EncodePipelineSW::EncodePipelineSW(Renderer *render, uint32_t width, uint3
const auto& settings = Settings::Instance();

x264_param_default_preset(&param, "ultrafast", "zerolatency");
x264_param_apply_profile(&param, settings.m_h264UseBaselineProfile ? "baseline" : "high");

param.pf_log = x264_log;
param.i_log_level = X264_LOG_INFO;
Expand All @@ -51,6 +50,19 @@ alvr::EncodePipelineSW::EncodePipelineSW(Renderer *render, uint32_t width, uint3
param.i_height = height;
param.rc.i_rc_method = X264_RC_ABR;

switch (settings.m_h264Profile) {
case ALVR_H264_PROFILE_BASELINE:
x264_param_apply_profile(&param, "baseline");
break;
case ALVR_H264_PROFILE_MAIN:
x264_param_apply_profile(&param, "main");
break;
default:
case ALVR_H264_PROFILE_HIGH:
x264_param_apply_profile(&param, "high");
break;
}

auto params = FfiDynamicEncoderParams {};
params.updated = true;
params.bitrate_bps = 30'000'000;
Expand Down
13 changes: 12 additions & 1 deletion alvr/server/cpp/platform/linux/EncodePipelineVAAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,18 @@ alvr::EncodePipelineVAAPI::EncodePipelineVAAPI(Renderer *render, VkContext &vk_c
switch (codec_id)
{
case ALVR_CODEC_H264:
encoder_ctx->profile = settings.m_h264UseBaselineProfile ? FF_PROFILE_H264_CONSTRAINED_BASELINE : FF_PROFILE_H264_MAIN;
switch (settings.m_h264Profile) {
case ALVR_H264_PROFILE_BASELINE:
encoder_ctx->profile = FF_PROFILE_H264_BASELINE;
break;
case ALVR_H264_PROFILE_MAIN:
encoder_ctx->profile = FF_PROFILE_H264_MAIN;
break;
default:
case ALVR_H264_PROFILE_HIGH:
encoder_ctx->profile = FF_PROFILE_H264_HIGH;
break;
}

switch (settings.m_entropyCoding) {
case ALVR_CABAC:
Expand Down
19 changes: 13 additions & 6 deletions alvr/server/cpp/platform/win32/VideoEncoderAMF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,19 @@ amf::AMFComponentPtr VideoEncoderAMF::MakeEncoder(
if (codec == ALVR_CODEC_H264)
{
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_USAGE, AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY);
if (Settings::Instance().m_h264UseBaselineProfile) {
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_CONSTRAINED_BASELINE);
} else {
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_HIGH);
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE_LEVEL, 42);
}
switch (Settings::Instance().m_h264Profile) {
case ALVR_H264_PROFILE_BASELINE:
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_BASELINE);
break;
case ALVR_H264_PROFILE_MAIN:
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_MAIN);
break;
default:
case ALVR_H264_PROFILE_HIGH:
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_HIGH);
break;
}
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE_LEVEL, 42);
switch (Settings::Instance().m_rateControlMode) {
case ALVR_CBR:
amfEncoder->SetProperty(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR);
Expand Down
13 changes: 12 additions & 1 deletion alvr/server/cpp/platform/win32/VideoEncoderSW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,18 @@ void VideoEncoderSW::Initialize() {
av_dict_set(&opt, "preset", "ultrafast", 0);
av_dict_set(&opt, "tune", "zerolatency", 0);

m_codecContext->profile = settings.m_h264UseBaselineProfile ? FF_PROFILE_H264_CONSTRAINED_BASELINE : FF_PROFILE_H264_HIGH;
switch (settings.m_h264Profile) {
case ALVR_H264_PROFILE_BASELINE:
m_codecContext->profile = FF_PROFILE_H264_BASELINE;
break;
case ALVR_H264_PROFILE_MAIN:
m_codecContext->profile = FF_PROFILE_H264_MAIN;
break;
default:
case ALVR_H264_PROFILE_HIGH:
m_codecContext->profile = FF_PROFILE_H264_HIGH;
break;
}
switch (settings.m_entropyCoding) {
case ALVR_CABAC:
av_dict_set(&opt, "coder", "ac", 0);
Expand Down
1 change: 1 addition & 0 deletions alvr/server/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ pub fn contruct_openvr_config(session: &SessionConfig) -> OpenvrConfig {
aggressive_keyframe_resend: settings.connection.aggressive_keyframe_resend,
adapter_index: settings.video.adapter_index,
codec: matches!(settings.video.preferred_codec, CodecType::Hevc) as _,
h264_profile: settings.video.encoder_config.h264_profile as u32,
rate_control_mode: settings.video.encoder_config.rate_control_mode as u32,
filler_data: settings.video.encoder_config.filler_data,
entropy_coding: settings.video.encoder_config.entropy_coding as u32,
Expand Down
1 change: 1 addition & 0 deletions alvr/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub struct OpenvrConfig {
pub aggressive_keyframe_resend: bool,
pub adapter_index: u32,
pub codec: u32,
pub h264_profile: u32,
pub refresh_rate: u32,
pub use_10bit_encoder: bool,
pub enable_vbaq: bool,
Expand Down
30 changes: 22 additions & 8 deletions alvr/session/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ VBR: Variable BitRate mode. Not commended because it may throw off the adaptive
#[schema(flag = "steamvr-restart")]
pub filler_data: bool,

#[schema(strings(
display_name = "h264: Profile",
help = "Whenever possible, attempts to use this profile. May increase compatibility with varying mobile devices. Only has an effect for h264. Doesn't affect NVENC on Windows."
))]
#[schema(flag = "steamvr-restart")]
pub h264_profile: H264Profile,

#[schema(strings(help = r#"CAVLC algorithm is recommended.
CABAC produces better compression but it's significantly slower and may lead to runaway latency"#))]
#[schema(flag = "steamvr-restart")]
Expand Down Expand Up @@ -420,6 +427,18 @@ pub enum CodecType {
Hevc = 1,
}

#[repr(u8)]
#[derive(SettingsSchema, Serialize, Deserialize, Debug, Copy, Clone)]
#[schema(gui = "button_group")]
pub enum H264Profile {
#[schema(strings(display_name = "High"))]
High = 0,
#[schema(strings(display_name = "Main"))]
Main = 1,
#[schema(strings(display_name = "Baseline"))]
Baseline = 2,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
#[schema(collapsible)]
pub struct VideoConfig {
Expand Down Expand Up @@ -469,13 +488,6 @@ pub struct VideoConfig {
#[schema(flag = "steamvr-restart")]
pub preferred_codec: CodecType,

#[schema(strings(
display_name = "Use h264 baseline profile",
help = "Whenever possible, attempts to force the 'baseline profile' or the 'constrained baseline profile' to increase compatibility with varying mobile devices. Only has an effect for h264 and may not have an effect for some configurations."
))]
#[schema(flag = "steamvr-restart")]
pub h264_use_baseline_profile: bool,

#[schema(flag = "steamvr-restart")]
pub encoder_config: EncoderConfig,

Expand Down Expand Up @@ -1166,13 +1178,15 @@ pub fn session_settings_default() -> SettingsDefault {
preferred_codec: CodecTypeDefault {
variant: CodecTypeDefaultVariant::H264,
},
h264_use_baseline_profile: false,
encoder_config: EncoderConfigDefault {
gui_collapsed: true,
rate_control_mode: RateControlModeDefault {
variant: RateControlModeDefaultVariant::Cbr,
},
filler_data: false,
h264_profile: H264ProfileDefault {
variant: H264ProfileDefaultVariant::High,
},
entropy_coding: EntropyCodingDefault {
variant: EntropyCodingDefaultVariant::Cavlc,
},
Expand Down

0 comments on commit 98855a9

Please sign in to comment.