mirror of
https://gitlab.com/gabmus/envision.git
synced 2025-07-31 13:18:46 +00:00
feat: encoder presets for wivrn
This commit is contained in:
parent
1e4648b021
commit
c58d9560e7
6 changed files with 247 additions and 2 deletions
|
@ -2,3 +2,4 @@ pub mod active_runtime_json;
|
||||||
pub mod monado_autorun;
|
pub mod monado_autorun;
|
||||||
pub mod openvrpaths_vrpath;
|
pub mod openvrpaths_vrpath;
|
||||||
pub mod wivrn_config;
|
pub mod wivrn_config;
|
||||||
|
pub mod wivrn_encoder_presets;
|
||||||
|
|
|
@ -95,7 +95,7 @@ pub struct WivrnConfEncoder {
|
||||||
pub group: Option<i32>,
|
pub group: Option<i32>,
|
||||||
/// contains unknown fields
|
/// contains unknown fields
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
other: Map<String, Value>,
|
pub other: Map<String, Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WivrnConfEncoder {
|
impl Default for WivrnConfEncoder {
|
||||||
|
@ -128,6 +128,7 @@ pub struct WivrnConfig {
|
||||||
pub scale: Option<[f32; 2]>,
|
pub scale: Option<[f32; 2]>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub bitrate: Option<u32>,
|
pub bitrate: Option<u32>,
|
||||||
|
#[serde(default)]
|
||||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
pub encoders: Vec<WivrnConfEncoder>,
|
pub encoders: Vec<WivrnConfEncoder>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
|
84
src/file_builders/wivrn_encoder_presets.rs
Normal file
84
src/file_builders/wivrn_encoder_presets.rs
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
use super::wivrn_config::{Codec, Encoder, WivrnConfEncoder};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
fn wivrn_encoder_presets() -> Vec<(&'static str, &'static str, Vec<WivrnConfEncoder>)> {
|
||||||
|
vec![
|
||||||
|
(
|
||||||
|
"3x VAAPI",
|
||||||
|
"Use 3 hardware accelerated encoders using VAAPI and the H265 codec.",
|
||||||
|
vec![
|
||||||
|
WivrnConfEncoder {
|
||||||
|
encoder: Encoder::Vaapi,
|
||||||
|
width: Some(0.5),
|
||||||
|
height: Some(0.25),
|
||||||
|
offset_x: Some(0.0),
|
||||||
|
offset_y: Some(0.0),
|
||||||
|
group: Some(0),
|
||||||
|
codec: Codec::H265,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
WivrnConfEncoder {
|
||||||
|
encoder: Encoder::Vaapi,
|
||||||
|
width: Some(0.5),
|
||||||
|
height: Some(0.75),
|
||||||
|
offset_x: Some(0.0),
|
||||||
|
offset_y: Some(0.25),
|
||||||
|
group: Some(0),
|
||||||
|
codec: Codec::H265,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
WivrnConfEncoder {
|
||||||
|
encoder: Encoder::Vaapi,
|
||||||
|
width: Some(0.5),
|
||||||
|
height: Some(1.0),
|
||||||
|
offset_x: Some(0.5),
|
||||||
|
offset_y: Some(0.0),
|
||||||
|
group: Some(1),
|
||||||
|
codec: Codec::H265,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2x VAAPI + 1 Software",
|
||||||
|
"Use 2 hardware accelerated encoders using VAAPI and a third one using software encoding. The hardware encoders use the H265 codec, while the software encoder uses H264.",
|
||||||
|
vec![
|
||||||
|
WivrnConfEncoder {
|
||||||
|
encoder: Encoder::Vaapi,
|
||||||
|
width: Some(0.5),
|
||||||
|
height: Some(0.25),
|
||||||
|
offset_x: Some(0.0),
|
||||||
|
offset_y: Some(0.0),
|
||||||
|
group: Some(0),
|
||||||
|
codec: Codec::H265,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
WivrnConfEncoder {
|
||||||
|
encoder: Encoder::Vaapi,
|
||||||
|
width: Some(0.5),
|
||||||
|
height: Some(0.75),
|
||||||
|
offset_x: Some(0.0),
|
||||||
|
offset_y: Some(0.25),
|
||||||
|
group: Some(0),
|
||||||
|
codec: Codec::H265,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
WivrnConfEncoder {
|
||||||
|
encoder: Encoder::X264,
|
||||||
|
width: Some(0.5),
|
||||||
|
height: Some(1.0),
|
||||||
|
offset_x: Some(0.5),
|
||||||
|
offset_y: Some(0.0),
|
||||||
|
group: Some(1),
|
||||||
|
codec: Codec::H264,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref WIVRN_ENCODER_PRESETS: Vec<(&'static str, &'static str, Vec<WivrnConfEncoder>)> =
|
||||||
|
wivrn_encoder_presets();
|
||||||
|
}
|
|
@ -19,5 +19,6 @@ mod steamvr_calibration_box;
|
||||||
mod term_widget;
|
mod term_widget;
|
||||||
mod util;
|
mod util;
|
||||||
mod wivrn_conf_editor;
|
mod wivrn_conf_editor;
|
||||||
|
pub mod wivrn_encoder_presets_win;
|
||||||
|
|
||||||
pub const SENDER_IO_ERR_MSG: &str = "relm4 sender i/o failed";
|
pub const SENDER_IO_ERR_MSG: &str = "relm4 sender i/o failed";
|
||||||
|
|
|
@ -3,12 +3,18 @@ use super::{
|
||||||
WivrnEncoderModel, WivrnEncoderModelInit, WivrnEncoderModelOutMsg,
|
WivrnEncoderModel, WivrnEncoderModelInit, WivrnEncoderModelOutMsg,
|
||||||
},
|
},
|
||||||
util::bits_from_mbits,
|
util::bits_from_mbits,
|
||||||
|
wivrn_encoder_presets_win::{
|
||||||
|
WivrnEncoderPresetsWin, WivrnEncoderPresetsWinMsg, WivrnEncoderPresetsWinOutMsg,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
file_builders::wivrn_config::{dump_wivrn_config, get_wivrn_config, WivrnConfig},
|
file_builders::wivrn_config::{
|
||||||
|
dump_wivrn_config, get_wivrn_config, WivrnConfEncoder, WivrnConfig,
|
||||||
|
},
|
||||||
ui::{
|
ui::{
|
||||||
preference_rows::{number_entry_row, spin_row, switch_row},
|
preference_rows::{number_entry_row, spin_row, switch_row},
|
||||||
util::bits_to_mbits,
|
util::bits_to_mbits,
|
||||||
|
wivrn_encoder_presets_win::WivrnEncoderPresetsWinInit,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
|
@ -28,6 +34,8 @@ pub struct WivrnConfEditor {
|
||||||
pub scaley_row: Option<adw::SpinRow>,
|
pub scaley_row: Option<adw::SpinRow>,
|
||||||
#[tracker::do_not_track]
|
#[tracker::do_not_track]
|
||||||
bitrate_row: Option<adw::EntryRow>,
|
bitrate_row: Option<adw::EntryRow>,
|
||||||
|
#[tracker::do_not_track]
|
||||||
|
wivrn_encoder_presets_win: Option<Controller<WivrnEncoderPresetsWin>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -37,6 +45,8 @@ pub enum WivrnConfEditorMsg {
|
||||||
AddEncoder,
|
AddEncoder,
|
||||||
DeleteEncoder(String),
|
DeleteEncoder(String),
|
||||||
TcpOnlyChanged(bool),
|
TcpOnlyChanged(bool),
|
||||||
|
OpenEncoderPresetsWin,
|
||||||
|
SetEncoderPreset(Vec<WivrnConfEncoder>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WivrnConfEditorInit {
|
pub struct WivrnConfEditorInit {
|
||||||
|
@ -145,6 +155,13 @@ impl SimpleComponent for WivrnConfEditor {
|
||||||
set_title: "Encoders",
|
set_title: "Encoders",
|
||||||
adw::ActionRow {
|
adw::ActionRow {
|
||||||
set_title: "Add encoder",
|
set_title: "Add encoder",
|
||||||
|
add_suffix: presets_btn = >k::Button {
|
||||||
|
set_valign: gtk::Align::Center,
|
||||||
|
set_label: "Use Preset",
|
||||||
|
connect_clicked[sender] => move |_| {
|
||||||
|
sender.input(Self::Input::OpenEncoderPresetsWin)
|
||||||
|
}
|
||||||
|
},
|
||||||
add_suffix: add_encoder_btn = >k::Button {
|
add_suffix: add_encoder_btn = >k::Button {
|
||||||
set_halign: gtk::Align::Center,
|
set_halign: gtk::Align::Center,
|
||||||
set_valign: gtk::Align::Center,
|
set_valign: gtk::Align::Center,
|
||||||
|
@ -170,6 +187,23 @@ impl SimpleComponent for WivrnConfEditor {
|
||||||
self.set_conf(get_wivrn_config());
|
self.set_conf(get_wivrn_config());
|
||||||
self.win.as_ref().unwrap().present();
|
self.win.as_ref().unwrap().present();
|
||||||
}
|
}
|
||||||
|
Self::Input::OpenEncoderPresetsWin => {
|
||||||
|
self.wivrn_encoder_presets_win
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.sender()
|
||||||
|
.emit(WivrnEncoderPresetsWinMsg::Present);
|
||||||
|
}
|
||||||
|
Self::Input::SetEncoderPreset(preset) => {
|
||||||
|
self.encoder_models.as_mut().unwrap().guard().clear();
|
||||||
|
preset.iter().for_each(|enc| {
|
||||||
|
self.encoder_models.as_mut().unwrap().guard().push_back(
|
||||||
|
WivrnEncoderModelInit {
|
||||||
|
encoder_conf: Some(enc.clone()),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
Self::Input::Save => {
|
Self::Input::Save => {
|
||||||
let x = self.scalex_row.as_ref().unwrap().adjustment().value();
|
let x = self.scalex_row.as_ref().unwrap().adjustment().value();
|
||||||
let y = self.scaley_row.as_ref().unwrap().adjustment().value();
|
let y = self.scaley_row.as_ref().unwrap().adjustment().value();
|
||||||
|
@ -234,6 +268,7 @@ impl SimpleComponent for WivrnConfEditor {
|
||||||
scalex_row: None,
|
scalex_row: None,
|
||||||
scaley_row: None,
|
scaley_row: None,
|
||||||
bitrate_row: None,
|
bitrate_row: None,
|
||||||
|
wivrn_encoder_presets_win: None,
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -258,6 +293,18 @@ impl SimpleComponent for WivrnConfEditor {
|
||||||
|
|
||||||
model.win = Some(widgets.win.clone());
|
model.win = Some(widgets.win.clone());
|
||||||
|
|
||||||
|
model.wivrn_encoder_presets_win = Some(
|
||||||
|
WivrnEncoderPresetsWin::builder()
|
||||||
|
.launch(WivrnEncoderPresetsWinInit {
|
||||||
|
parent_win: widgets.win.clone().upcast(),
|
||||||
|
})
|
||||||
|
.forward(sender.input_sender(), move |msg| match msg {
|
||||||
|
WivrnEncoderPresetsWinOutMsg::Selected(preset) => {
|
||||||
|
Self::Input::SetEncoderPreset(preset)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
ComponentParts { model, widgets }
|
ComponentParts { model, widgets }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
111
src/ui/wivrn_encoder_presets_win.rs
Normal file
111
src/ui/wivrn_encoder_presets_win.rs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
use adw::prelude::*;
|
||||||
|
use relm4::prelude::*;
|
||||||
|
|
||||||
|
use crate::file_builders::{
|
||||||
|
wivrn_config::WivrnConfEncoder, wivrn_encoder_presets::WIVRN_ENCODER_PRESETS,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::SENDER_IO_ERR_MSG;
|
||||||
|
|
||||||
|
#[tracker::track]
|
||||||
|
pub struct WivrnEncoderPresetsWin {
|
||||||
|
win: Option<adw::Window>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum WivrnEncoderPresetsWinMsg {
|
||||||
|
Present,
|
||||||
|
Selected(Vec<WivrnConfEncoder>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum WivrnEncoderPresetsWinOutMsg {
|
||||||
|
Selected(Vec<WivrnConfEncoder>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WivrnEncoderPresetsWinInit {
|
||||||
|
pub parent_win: gtk::Window,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub)]
|
||||||
|
impl SimpleComponent for WivrnEncoderPresetsWin {
|
||||||
|
type Init = WivrnEncoderPresetsWinInit;
|
||||||
|
type Input = WivrnEncoderPresetsWinMsg;
|
||||||
|
type Output = WivrnEncoderPresetsWinOutMsg;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
#[name(win)]
|
||||||
|
adw::Window {
|
||||||
|
set_modal: true,
|
||||||
|
set_hide_on_close: true,
|
||||||
|
set_transient_for: Some(&init.parent_win),
|
||||||
|
set_title: Some("WiVRn Encoder Presets"),
|
||||||
|
set_default_height: 400,
|
||||||
|
set_default_width: 300,
|
||||||
|
adw::ToolbarView {
|
||||||
|
set_top_bar_style: adw::ToolbarStyle::Flat,
|
||||||
|
set_hexpand: true,
|
||||||
|
set_vexpand: true,
|
||||||
|
add_top_bar: top_bar = &adw::HeaderBar {
|
||||||
|
set_vexpand: false,
|
||||||
|
},
|
||||||
|
#[wrap(Some)]
|
||||||
|
set_content: prefpage = &adw::PreferencesPage {
|
||||||
|
set_title: "Encoder Presets",
|
||||||
|
add: prefgrp = &adw::PreferencesGroup {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
|
||||||
|
self.reset();
|
||||||
|
|
||||||
|
match message {
|
||||||
|
Self::Input::Present => {
|
||||||
|
self.win.as_ref().unwrap().present();
|
||||||
|
}
|
||||||
|
Self::Input::Selected(preset) => {
|
||||||
|
sender
|
||||||
|
.output(Self::Output::Selected(preset))
|
||||||
|
.expect(SENDER_IO_ERR_MSG);
|
||||||
|
self.win.as_ref().unwrap().close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: ComponentSender<Self>,
|
||||||
|
) -> ComponentParts<Self> {
|
||||||
|
let mut model = Self {
|
||||||
|
win: None,
|
||||||
|
tracker: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
model.win = Some(widgets.win.clone());
|
||||||
|
|
||||||
|
WIVRN_ENCODER_PRESETS
|
||||||
|
.iter()
|
||||||
|
.for_each(|(name, desc, enc_preset)| {
|
||||||
|
let row = adw::ActionRow::builder()
|
||||||
|
.title(*name)
|
||||||
|
.subtitle_lines(0)
|
||||||
|
.subtitle(*desc)
|
||||||
|
.activatable(true)
|
||||||
|
.build();
|
||||||
|
let sndr = sender.clone();
|
||||||
|
row.connect_activated(move |_| {
|
||||||
|
sndr.input(Self::Input::Selected(enc_preset.clone()))
|
||||||
|
});
|
||||||
|
widgets.prefgrp.add(&row);
|
||||||
|
});
|
||||||
|
|
||||||
|
ComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue