From 8ad1c1069cb9bdffc82fd4eb43c29e9726d41e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=96R=C3=96K=20Attila?= Date: Thu, 12 Sep 2024 19:02:40 +0200 Subject: [PATCH] video/external: Make OpenH264 support optional by adding the `openh264` feature And enable it in desktop and tests. --- desktop/Cargo.toml | 2 +- desktop/src/player.rs | 9 ++++---- tests/framework/Cargo.toml | 2 +- tests/framework/src/options.rs | 2 +- video/external/Cargo.toml | 15 ++++++++------ video/external/src/backend.rs | 38 +++++++++++++++++++++++++--------- video/external/src/decoder.rs | 2 ++ 7 files changed, 46 insertions(+), 24 deletions(-) diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 0f8967131..23956aca1 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -23,7 +23,7 @@ ruffle_core = { path = "../core", features = ["audio", "clap", "mp3", "nellymose ruffle_render = { path = "../render", features = ["clap"] } ruffle_render_wgpu = { path = "../render/wgpu", features = ["clap"] } ruffle_video_software = { path = "../video/software", optional = true } -ruffle_video_external = { path = "../video/external", optional = true } +ruffle_video_external = { path = "../video/external", features = ["openh264"], optional = true } ruffle_frontend_utils = { path = "../frontend-utils", features = ["cpal"] } tracing = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/desktop/src/player.rs b/desktop/src/player.rs index da3384cbf..9f4b724e7 100644 --- a/desktop/src/player.rs +++ b/desktop/src/player.rs @@ -234,15 +234,14 @@ impl ActivePlayer { let openh264 = tokio::task::block_in_place(|| { OpenH264Codec::load(&opt.cache_directory.join("video")) }); - let openh264 = match openh264 { - Ok(codec) => Some(codec), + let backend = match openh264 { + Ok(codec) => ExternalVideoBackend::new_with_openh264(codec), Err(e) => { tracing::error!("Failed to load OpenH264: {}", e); - None + ExternalVideoBackend::new() } }; - - builder = builder.with_video(ExternalVideoBackend::new(openh264)); + builder = builder.with_video(backend); } } else { #[cfg(feature = "software_video")] diff --git a/tests/framework/Cargo.toml b/tests/framework/Cargo.toml index 63dbc2d4c..164726fdd 100644 --- a/tests/framework/Cargo.toml +++ b/tests/framework/Cargo.toml @@ -16,7 +16,7 @@ ruffle_render = { path = "../../render", features = ["serde"] } ruffle_input_format = { path = "../input-format" } ruffle_socket_format = { path = "../socket-format" } ruffle_video_software = { path = "../../video/software", optional = true } -ruffle_video_external = { path = "../../video/external", optional = true } +ruffle_video_external = { path = "../../video/external", features = ["openh264"], optional = true } image = { workspace = true, features = ["png"] } regex = "1.10.6" url = { workspace = true } diff --git a/tests/framework/src/options.rs b/tests/framework/src/options.rs index 0880ad415..44f1102bd 100644 --- a/tests/framework/src/options.rs +++ b/tests/framework/src/options.rs @@ -187,7 +187,7 @@ impl PlayerOptions { .map_err(|e| anyhow!("Couldn't load OpenH264: {}", e))?; player_builder = - player_builder.with_video(ExternalVideoBackend::new(Some(openh264))); + player_builder.with_video(ExternalVideoBackend::new_with_openh264(openh264)); } #[cfg(all( diff --git a/video/external/Cargo.toml b/video/external/Cargo.toml index 1af1d2866..ec20b89f1 100644 --- a/video/external/Cargo.toml +++ b/video/external/Cargo.toml @@ -17,9 +17,12 @@ ruffle_video_software = { path = "../software" } thiserror = { workspace = true } # Needed for OpenH264: -libloading = "0.8.5" -reqwest = { version = "0.12.7", default-features = false, features = ["blocking"] } -hex = "0.4.3" -bzip2 = { version = "0.4.4", features = ["static"] } -tempfile = "3.12.0" -sha2 = "0.10.8" +libloading = { version = "0.8.5", optional = true } +reqwest = { version = "0.12.7", default-features = false, features = ["blocking"], optional = true } +hex = { version = "0.4.3", optional = true } +bzip2 = { version = "0.4.4", features = ["static"], optional = true } +tempfile = { version = "3.12.0", optional = true } +sha2 = { version = "0.10.8", optional = true } + +[features] +openh264 = ["libloading", "reqwest", "hex", "bzip2", "tempfile", "sha2"] diff --git a/video/external/src/backend.rs b/video/external/src/backend.rs index 7908ad9c5..e20bb56dc 100644 --- a/video/external/src/backend.rs +++ b/video/external/src/backend.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "openh264")] use crate::decoder::openh264::OpenH264Codec; use crate::decoder::VideoDecoder; @@ -26,21 +27,42 @@ enum ProxyOrStream { /// except for H.264, for which it uses an external decoder. pub struct ExternalVideoBackend { streams: SlotMap, + #[cfg(feature = "openh264")] openh264_codec: Option, software: SoftwareVideoBackend, } impl Default for ExternalVideoBackend { fn default() -> Self { - Self::new(None) + Self::new() } } impl ExternalVideoBackend { - pub fn new(openh264_codec: Option) -> Self { + fn make_decoder(&mut self) -> Result, Error> { + #[cfg(feature = "openh264")] + if let Some(h264_codec) = self.openh264_codec.as_ref() { + let decoder = Box::new(crate::decoder::openh264::H264Decoder::new(h264_codec)); + return Ok(decoder); + } + + Err(Error::DecoderError("No OpenH264".into())) + } + + pub fn new() -> Self { Self { streams: SlotMap::with_key(), - openh264_codec, + #[cfg(feature = "openh264")] + openh264_codec: None, + software: SoftwareVideoBackend::new(), + } + } + + #[cfg(feature = "openh264")] + pub fn new_with_openh264(openh264_codec: OpenH264Codec) -> Self { + Self { + streams: SlotMap::with_key(), + openh264_codec: Some(openh264_codec), software: SoftwareVideoBackend::new(), } } @@ -57,13 +79,9 @@ impl VideoBackend for ExternalVideoBackend { filter: VideoDeblocking, ) -> Result { let proxy_or_stream = if codec == VideoCodec::H264 { - if let Some(h264_codec) = self.openh264_codec.as_ref() { - let decoder = Box::new(crate::decoder::openh264::H264Decoder::new(h264_codec)); - let stream = VideoStream::new(decoder); - ProxyOrStream::Owned(stream) - } else { - return Err(Error::DecoderError("No OpenH264".into())); - } + let decoder = self.make_decoder()?; + let stream = VideoStream::new(decoder); + ProxyOrStream::Owned(stream) } else { ProxyOrStream::Proxied( self.software diff --git a/video/external/src/decoder.rs b/video/external/src/decoder.rs index 7f62962e0..d7169e5b8 100644 --- a/video/external/src/decoder.rs +++ b/video/external/src/decoder.rs @@ -1,11 +1,13 @@ // bindgen ../openh264/codec/api/wels/codec_api.h --no-prepend-enum-name \ // --dynamic-loading OpenH264 -o openh264_sys.rs +#[cfg(feature = "openh264")] #[allow(non_upper_case_globals)] #[allow(non_camel_case_types)] #[allow(non_snake_case)] #[allow(dead_code)] mod openh264_sys; +#[cfg(feature = "openh264")] pub mod openh264; pub use ruffle_video_software::decoder::VideoDecoder;