layout improvements
This commit is contained in:
@@ -677,12 +677,94 @@ fn specta_builder() -> Builder<tauri::Wry> {
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
/// Configure GStreamer (the media backend behind WebKitGTK's HTML5 `<video>`
|
||||
/// element on Linux) to prefer hardware-accelerated VAAPI decoding when the
|
||||
/// host provides it, falling back to software decoding otherwise.
|
||||
///
|
||||
/// All variables are only set if the user has not already exported them, so an
|
||||
/// explicit override (e.g. forcing software decode for debugging) is respected.
|
||||
/// They must be applied before WebKitGTK builds its GStreamer pipeline, hence the
|
||||
/// call at the very top of `run()`.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn enable_linux_hardware_video_decoding() {
|
||||
// Boost the rank of the modern stateless VAAPI decoders (gst-plugins-bad
|
||||
// `va` plugin) so GStreamer selects them ahead of the software decoders. The
|
||||
// `MAX` rank wins decoder autoplugging when the hardware/driver supports the
|
||||
// codec; unsupported codecs simply fall through to software.
|
||||
let rank_overrides = "vah264dec:MAX,vah265dec:MAX,vavp9dec:MAX,vaav1dec:MAX,\
|
||||
vampeg2dec:MAX,vavp8dec:MAX";
|
||||
|
||||
set_env_if_unset("GST_PLUGIN_FEATURE_RANK", rank_overrides);
|
||||
|
||||
// Ensure WebKit keeps GStreamer's hardware/DMABUF video path enabled. Setting
|
||||
// this to "0" would force software decoding, so only default it to "1".
|
||||
set_env_if_unset("WEBKIT_GST_ENABLE_HW_VIDEO_DECODER", "1");
|
||||
|
||||
info!("[INIT] Linux hardware video decoding (VAAPI) enabled where supported");
|
||||
|
||||
log_available_vaapi_decoders();
|
||||
}
|
||||
|
||||
/// Probe (via `gst-inspect-1.0`, which ships with GStreamer) which VAAPI hardware
|
||||
/// video decoders GStreamer can actually load on this host, and log the result so
|
||||
/// it is clear at startup whether hardware decoding is genuinely available or
|
||||
/// whether playback will fall back to software.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn log_available_vaapi_decoders() {
|
||||
const HW_DECODERS: &[&str] = &[
|
||||
"vah264dec", "vah265dec", "vavp9dec", "vaav1dec", "vampeg2dec", "vavp8dec",
|
||||
];
|
||||
|
||||
let available: Vec<&str> = HW_DECODERS
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|name| {
|
||||
std::process::Command::new("gst-inspect-1.0")
|
||||
.arg(name)
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.status()
|
||||
.map(|s| s.success())
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.collect();
|
||||
|
||||
if available.is_empty() {
|
||||
log::warn!(
|
||||
"[INIT] No VAAPI hardware video decoders found via gst-inspect-1.0; \
|
||||
video will use software decoding. Install the GStreamer 'va' plugin \
|
||||
(gst-plugins-bad) and a VAAPI driver to enable hardware decoding."
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
"[INIT] VAAPI hardware video decoders available to GStreamer: {}",
|
||||
available.join(", ")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn set_env_if_unset(key: &str, value: &str) {
|
||||
if std::env::var_os(key).is_none() {
|
||||
// SAFETY: called once at startup before any threads that read the
|
||||
// environment (WebKitGTK/GStreamer) are spawned.
|
||||
std::env::set_var(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
// Initialize logger
|
||||
env_logger::Builder::from_default_env()
|
||||
.filter_level(log::LevelFilter::Info)
|
||||
.init();
|
||||
|
||||
// On Linux, video plays through WebKitGTK's HTML5 <video> element, which uses
|
||||
// GStreamer as its media backend. Enable hardware-accelerated (VAAPI) decoding
|
||||
// when available so video transcoding/decoding does not fall back to the CPU.
|
||||
// These must be set before WebKitGTK initializes its GStreamer pipeline.
|
||||
#[cfg(target_os = "linux")]
|
||||
enable_linux_hardware_video_decoding();
|
||||
|
||||
// NOTE: TypeScript bindings are generated by the `export_typescript_bindings`
|
||||
// test (`cargo test export_typescript_bindings`), NOT at runtime. Calling
|
||||
// `.export()` here would try to write `../src/lib/api/bindings.ts` at app
|
||||
|
||||
Reference in New Issue
Block a user