From 0f220752f94843e850f0503834298625fc0921f6 Mon Sep 17 00:00:00 2001 From: NiiightmareXD Date: Thu, 24 Oct 2024 17:46:05 +0330 Subject: [PATCH] =?UTF-8?q?Allow=20access=20to=20DirectX=20device=20?= =?UTF-8?q?=F0=9F=94=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 68 +++++++++++++-------------- Cargo.toml | 10 ++-- README.md | 8 ++-- examples/basic.rs | 6 +-- examples/cli.rs | 14 +++--- src/capture.rs | 61 +++++++++++++----------- src/frame.rs | 11 +++-- src/graphics_capture_api.rs | 8 +++- src/lib.rs | 8 ++-- windows-capture-python/Cargo.toml | 6 +-- windows-capture-python/pyproject.toml | 2 +- windows-capture-python/src/lib.rs | 13 ++--- 12 files changed, 114 insertions(+), 101 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8f9a90..8f6f131 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,9 +53,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bitflags" @@ -77,9 +77,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "clap" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -99,9 +99,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -182,9 +182,9 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "lock_api" @@ -219,9 +219,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "parking_lot" @@ -254,18 +254,18 @@ checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] [[package]] name = "pyo3" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831e8e819a138c36e212f3af3fd9eeffed6bf1510a805af35b0edee5ffa59433" +checksum = "3d922163ba1f79c04bc49073ba7b32fd5a8d3b76a87c955921234b8e77333c51" dependencies = [ "cfg-if", "indoc", @@ -281,9 +281,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8730e591b14492a8945cdff32f089250b05f5accecf74aeddf9e8272ce1fa8" +checksum = "bc38c5feeb496c8321091edf3d63e9a6829eab4b863b4a6a65f26f3e9cc6b179" dependencies = [ "once_cell", "target-lexicon", @@ -291,9 +291,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e97e919d2df92eb88ca80a037969f44e5e70356559654962cbb3316d00300c6" +checksum = "94845622d88ae274d2729fcefc850e63d7a3ddff5e3ce11bd88486db9f1d357d" dependencies = [ "libc", "pyo3-build-config", @@ -301,9 +301,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb57983022ad41f9e683a599f2fd13c3664d7063a3ac5714cae4b7bee7d3f206" +checksum = "e655aad15e09b94ffdb3ce3d217acf652e26bbc37697ef012f5e5e348c716e5e" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -313,9 +313,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.22.2" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec480c0c51ddec81019531705acac51bcdbeae563557c982aa8263bb96880372" +checksum = "ae1e3f09eecd94618f60a455a23def79f79eba4dc561a97324bf9ac8c6df30ce" dependencies = [ "heck", "proc-macro2", @@ -382,9 +382,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -399,18 +399,18 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", @@ -419,9 +419,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unindent" @@ -447,7 +447,7 @@ dependencies = [ [[package]] name = "windows-capture" -version = "1.3.6" +version = "1.4.0" dependencies = [ "clap", "ctrlc", @@ -459,7 +459,7 @@ dependencies = [ [[package]] name = "windows-capture-python" -version = "1.3.6" +version = "1.4.0" dependencies = [ "pyo3", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 228a7df..27af43a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "windows-capture" -version = "1.3.6" +version = "1.4.0" authors = ["NiiightmareXD"] edition = "2021" description = "Fastest Windows Screen Capture Library For Rust 🔥" @@ -52,8 +52,8 @@ parking_lot = "0.12.3" rayon = "1.10.0" # Error handling -thiserror = "1.0.63" -clap = { version = "4.5.17", features = ["derive"] } +thiserror = "1.0.65" +clap = { version = "4.5.20", features = ["derive"] } ctrlc = "3.4.5" [package.metadata.docs.rs] @@ -64,5 +64,9 @@ targets = ["x86_64-pc-windows-msvc"] name = "basic" doc-scrape-examples = false +[[example]] +name = "cli" +doc-scrape-examples = false + [workspace] members = ["windows-capture-python"] diff --git a/README.md b/README.md index 1c4be7a..f8c8c5d 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Add this library to your `Cargo.toml`: ```toml [dependencies] -windows-capture = "1.3.6" +windows-capture = "1.4.0" ``` or run this command @@ -42,7 +42,7 @@ use std::{ }; use windows_capture::{ - capture::GraphicsCaptureApiHandler, + capture::{Context, GraphicsCaptureApiHandler}, encoder::{AudioSettingsBuilder, ContainerSettingsBuilder, VideoEncoder, VideoSettingsBuilder}, frame::Frame, graphics_capture_api::InternalCaptureControl, @@ -66,8 +66,8 @@ impl GraphicsCaptureApiHandler for Capture { type Error = Box; // Function that will be called to create the struct. The flags can be passed from settings. - fn new(message: Self::Flags) -> Result { - println!("Got The Flag: {message}"); + fn new(ctx: Context) -> Result { + println!("Got The Flag: {}", ctx.flags); let encoder = VideoEncoder::new( VideoSettingsBuilder::new(1920, 1080), diff --git a/examples/basic.rs b/examples/basic.rs index 784685f..e6cc185 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -4,7 +4,7 @@ use std::{ }; use windows_capture::{ - capture::{GraphicsCaptureApiHandler, RawDirect3DDevice}, + capture::{Context, GraphicsCaptureApiHandler}, encoder::{AudioSettingsBuilder, ContainerSettingsBuilder, VideoEncoder, VideoSettingsBuilder}, frame::Frame, graphics_capture_api::InternalCaptureControl, @@ -28,8 +28,8 @@ impl GraphicsCaptureApiHandler for Capture { type Error = Box; // Function that will be called to create the struct. The flags can be passed from settings. - fn new(_: RawDirect3DDevice, message: Self::Flags) -> Result { - println!("Got The Flag: {message}"); + fn new(ctx: Context) -> Result { + println!("Got The Flag: {}", ctx.flags); let encoder = VideoEncoder::new( VideoSettingsBuilder::new(1920, 1080), diff --git a/examples/cli.rs b/examples/cli.rs index d888dd4..566beed 100644 --- a/examples/cli.rs +++ b/examples/cli.rs @@ -10,7 +10,7 @@ use std::{ use clap::Parser; use windows_capture::{ - capture::{GraphicsCaptureApiHandler, RawDirect3DDevice}, + capture::{Context, GraphicsCaptureApiHandler}, encoder::{AudioSettingsBuilder, ContainerSettingsBuilder, VideoEncoder, VideoSettingsBuilder}, frame::Frame, graphics_capture_api::InternalCaptureControl, @@ -53,18 +53,18 @@ impl GraphicsCaptureApiHandler for Capture { type Error = Box; // Function that will be called to create the struct. The flags can be passed from settings. - fn new(_: RawDirect3DDevice, settings: Self::Flags) -> Result { + fn new(ctx: Context) -> Result { println!("Capture started."); - let video_settings = VideoSettingsBuilder::new(settings.width, settings.height) - .bitrate(settings.bitrate) - .frame_rate(settings.frame_rate); + let video_settings = VideoSettingsBuilder::new(ctx.flags.width, ctx.flags.height) + .bitrate(ctx.flags.bitrate) + .frame_rate(ctx.flags.frame_rate); let encoder = VideoEncoder::new( video_settings, AudioSettingsBuilder::default().disabled(true), ContainerSettingsBuilder::default(), - &settings.path, + &ctx.flags.path, )?; Ok(Self { @@ -72,7 +72,7 @@ impl GraphicsCaptureApiHandler for Capture { start: Instant::now(), frame_count_since_reset: 0, last_reset: Instant::now(), - settings, + settings: ctx.flags, }) } diff --git a/src/capture.rs b/src/capture.rs index 1d4f6e4..d56b4f2 100644 --- a/src/capture.rs +++ b/src/capture.rs @@ -51,7 +51,7 @@ pub enum CaptureControlError { } /// Used to control the capture session -pub struct CaptureControl { +pub struct CaptureControl { thread_handle: Option>>>, halt_handle: Arc, callback: Arc>, @@ -71,7 +71,7 @@ impl CaptureControl { /// The newly created CaptureControl struct. #[must_use] #[inline] - pub fn new( + pub const fn new( thread_handle: JoinHandle>>, halt_handle: Arc, callback: Arc>, @@ -219,8 +219,17 @@ pub enum GraphicsCaptureApiError { FrameHandlerError(E), } -/// A trait representing a graphics capture handler. +/// A struct representing the context of the capture handler. +pub struct Context { + /// The flags that are gotten from the settings. + pub flags: Flags, + /// The direct3d device and context. + pub device: ID3D11Device, + /// The direct3d device context. + pub device_context: ID3D11DeviceContext, +} +/// A trait representing a graphics capture handler. pub trait GraphicsCaptureApiHandler: Sized { /// The type of flags used to get the values from the settings. type Flags; @@ -270,15 +279,15 @@ pub trait GraphicsCaptureApiHandler: Sized { // Start capture let result = Arc::new(Mutex::new(None)); + + let ctx = Context { + flags: settings.flags, + device: d3d_device.clone(), + device_context: d3d_device_context.clone(), + }; + let callback = Arc::new(Mutex::new( - Self::new( - RawDirect3DDevice { - device: d3d_device.clone(), - context: d3d_device_context.clone(), - }, - settings.flags, - ) - .map_err(GraphicsCaptureApiError::NewHandlerError)?, + Self::new(ctx).map_err(GraphicsCaptureApiError::NewHandlerError)?, )); let item = settings @@ -340,7 +349,8 @@ pub trait GraphicsCaptureApiHandler: Sized { unsafe { RoUninitialize() }; // Check handler result - if let Some(e) = result.lock().take() { + let result = result.lock().take(); + if let Some(e) = result { return Err(GraphicsCaptureApiError::FrameHandlerError(e)); } @@ -395,15 +405,15 @@ pub trait GraphicsCaptureApiHandler: Sized { // Start capture let result = Arc::new(Mutex::new(None)); + + let ctx = Context { + flags: settings.flags, + device: d3d_device.clone(), + device_context: d3d_device_context.clone(), + }; + let callback = Arc::new(Mutex::new( - Self::new( - RawDirect3DDevice { - device: d3d_device.clone(), - context: d3d_device_context.clone(), - }, - settings.flags, - ) - .map_err(GraphicsCaptureApiError::NewHandlerError)?, + Self::new(ctx).map_err(GraphicsCaptureApiError::NewHandlerError)?, )); let item = settings @@ -475,7 +485,8 @@ pub trait GraphicsCaptureApiHandler: Sized { unsafe { RoUninitialize() }; // Check handler result - if let Some(e) = result.lock().take() { + let result = result.lock().take(); + if let Some(e) = result { return Err(GraphicsCaptureApiError::FrameHandlerError(e)); } @@ -513,7 +524,7 @@ pub trait GraphicsCaptureApiHandler: Sized { /// # Returns /// /// Returns `Ok(Self)` if the struct creation was successful, otherwise returns an error of type `Self::Error`. - fn new(device: RawDirect3DDevice, flags: Self::Flags) -> Result; + fn new(ctx: Context) -> Result; /// Called every time a new frame is available. /// @@ -541,9 +552,3 @@ pub trait GraphicsCaptureApiHandler: Sized { Ok(()) } } - -#[derive(Clone)] -pub struct RawDirect3DDevice { - pub device: ID3D11Device, - pub context: ID3D11DeviceContext, -} diff --git a/src/frame.rs b/src/frame.rs index 81cd615..ee5d9e7 100644 --- a/src/frame.rs +++ b/src/frame.rs @@ -166,9 +166,10 @@ impl<'a> Frame<'a> { /// # Safety /// /// This method is unsafe because it returns a raw pointer to the IDirect3DSurface. + #[allow(clippy::missing_safety_doc)] #[must_use] #[inline] - pub unsafe fn as_raw_surface(&self) -> &IDirect3DSurface { + pub const unsafe fn as_raw_surface(&self) -> &IDirect3DSurface { &self.frame_surface } @@ -177,8 +178,10 @@ impl<'a> Frame<'a> { /// # Returns /// /// The ID3D11Texture2D representing the raw texture of the frame. + #[allow(clippy::missing_safety_doc)] + #[must_use] #[inline] - pub unsafe fn as_raw_texture(&self) -> &ID3D11Texture2D { + pub const unsafe fn as_raw_texture(&self) -> &ID3D11Texture2D { &self.frame_texture } @@ -492,7 +495,7 @@ impl<'a> FrameBuffer<'a> { /// /// A mutable reference to the buffer containing pixel data without padding. #[inline] - pub fn as_raw_nopadding_buffer(&mut self) -> Result<&mut [u8], Error> { + pub fn as_nopadding_buffer(&mut self) -> Result<&mut [u8], Error> { if !self.has_padding() { return Ok(self.raw_buffer); } @@ -546,7 +549,7 @@ impl<'a> FrameBuffer<'a> { let height = self.height; let bytes = ImageEncoder::new(format, self.color_format).encode( - self.as_raw_nopadding_buffer()?, + self.as_nopadding_buffer()?, width, height, )?; diff --git a/src/graphics_capture_api.rs b/src/graphics_capture_api.rs index b36305e..5e5e897 100644 --- a/src/graphics_capture_api.rs +++ b/src/graphics_capture_api.rs @@ -61,7 +61,7 @@ impl InternalCaptureControl { /// A new instance of `InternalCaptureControl`. #[must_use] #[inline] - pub fn new(stop: Arc) -> Self { + pub const fn new(stop: Arc) -> Self { Self { stop } } @@ -101,6 +101,8 @@ impl GraphicsCaptureApi { /// /// # Arguments /// + /// * `d3d_device` - The ID3D11Device to use for the capture. + /// * `d3d_device_context` - The ID3D11DeviceContext to use for the capture. /// * `item` - The graphics capture item to capture. /// * `callback` - The callback handler for capturing frames. /// * `capture_cursor` - Optional flag to capture the cursor. @@ -112,6 +114,7 @@ impl GraphicsCaptureApi { /// # Returns /// /// Returns a `Result` containing the new `GraphicsCaptureApi` struct if successful, or an `Error` if an error occurred. + #[allow(clippy::too_many_arguments)] #[inline] pub fn new< T: GraphicsCaptureApiHandler + Send + 'static, @@ -175,7 +178,8 @@ impl GraphicsCaptureApi { halt_closed.store(true, atomic::Ordering::Relaxed); // Notify the struct that the capture session is closed - if let Err(e) = callback_closed.lock().on_closed() { + let callback_closed = callback_closed.lock().on_closed(); + if let Err(e) = callback_closed { *result_closed.lock() = Some(e); } diff --git a/src/lib.rs b/src/lib.rs index 4d97202..979e61d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,7 @@ //! //! ```toml //! [dependencies] -//! windows-capture = "1.3.6" +//! windows-capture = "1.4.0" //! ``` //! or run this command //! @@ -39,7 +39,7 @@ //! }; //! //! use windows_capture::{ -//! capture::{GraphicsCaptureApiHandler, RawDirect3DDevice}, +//! capture::{Context, GraphicsCaptureApiHandler}, //! encoder::{AudioSettingsBuilder, ContainerSettingsBuilder, VideoEncoder, VideoSettingsBuilder}, //! frame::Frame, //! graphics_capture_api::InternalCaptureControl, @@ -63,8 +63,8 @@ //! type Error = Box; //! //! // Function that will be called to create the struct. The flags can be passed from settings. -//! fn new(_: RawDirect3DDevice, message: Self::Flags) -> Result { -//! println!("Got The Flag: {message}"); +//! fn new(ctx: Context) -> Result { +//! println!("Got The Flag: {}", ctx.flags); //! //! let encoder = VideoEncoder::new( //! VideoSettingsBuilder::new(1920, 1080), diff --git a/windows-capture-python/Cargo.toml b/windows-capture-python/Cargo.toml index 97d6ba5..5aa9d61 100644 --- a/windows-capture-python/Cargo.toml +++ b/windows-capture-python/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "windows-capture-python" -version = "1.3.6" +version = "1.4.0" authors = ["NiiightmareXD"] edition = "2021" description = "Fastest Windows Screen Capture Library For Python 🔥" @@ -21,11 +21,11 @@ name = "windows_capture" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.22.2", features = [ +pyo3 = { version = "0.22.5", features = [ "extension-module", "auto-initialize", "abi3", "abi3-py39", ] } -thiserror = "1.0.63" +thiserror = "1.0.65" windows-capture = { path = ".." } diff --git a/windows-capture-python/pyproject.toml b/windows-capture-python/pyproject.toml index 32e6c75..377e1df 100644 --- a/windows-capture-python/pyproject.toml +++ b/windows-capture-python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "windows-capture" -version = "1.3.6" +version = "1.4.0" description = "Fastest Windows Screen Capture Library For Python 🔥" readme = "README-Python.md" requires-python = ">=3.9" diff --git a/windows-capture-python/src/lib.rs b/windows-capture-python/src/lib.rs index 78b21bf..7964777 100644 --- a/windows-capture-python/src/lib.rs +++ b/windows-capture-python/src/lib.rs @@ -7,8 +7,8 @@ use std::sync::Arc; use ::windows_capture::{ capture::{ - CaptureControl, CaptureControlError, GraphicsCaptureApiError, GraphicsCaptureApiHandler, - RawDirect3DDevice, + CaptureControl, CaptureControlError, Context, GraphicsCaptureApiError, + GraphicsCaptureApiHandler, }, frame::{self, Frame}, graphics_capture_api::InternalCaptureControl, @@ -369,13 +369,10 @@ impl GraphicsCaptureApiHandler for InnerNativeWindowsCapture { type Error = InnerNativeWindowsCaptureError; #[inline] - fn new( - _: RawDirect3DDevice, - (on_frame_arrived_callback, on_closed): Self::Flags, - ) -> Result { + fn new(ctx: Context) -> Result { Ok(Self { - on_frame_arrived_callback, - on_closed, + on_frame_arrived_callback: ctx.flags.0, + on_closed: ctx.flags.1, }) }