From ae70ce3b67f6510b57729bd7ef54caf3d48e8894 Mon Sep 17 00:00:00 2001 From: NiiightmareXD Date: Sun, 21 Apr 2024 19:14:07 +0330 Subject: [PATCH] =?UTF-8?q?Update=20Dependencies=20=E2=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 1 + src/encoder.rs | 98 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7c03fc6..65d07c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ windows = { version = "0.54.0", features = [ "Media_MediaProperties", "Media_Core", "Media_Transcoding", + "Security_Cryptography", ] } # Mutex optimization diff --git a/src/encoder.rs b/src/encoder.rs index c55e236..0b18b49 100644 --- a/src/encoder.rs +++ b/src/encoder.rs @@ -1,6 +1,7 @@ use std::{ fs::{self, File}, path::Path, + slice, sync::{ atomic::{self, AtomicBool}, mpsc, Arc, @@ -27,6 +28,7 @@ use windows::{ }, Transcoding::MediaTranscoder, }, + Security::Cryptography::CryptographicBuffer, Storage::{ FileAccessMode, StorageFile, Streams::{ @@ -143,7 +145,7 @@ pub enum VideoEncoderError { #[error("Windows API Error: {0}")] WindowsError(#[from] windows::core::Error), #[error("Frame send error")] - FrameSendError(#[from] mpsc::SendError, TimeSpan)>>), + FrameSendError(#[from] mpsc::SendError>), #[error("IO Error: {0}")] IoError(#[from] std::io::Error), } @@ -173,10 +175,16 @@ pub enum VideoEncoderQuality { Uhd4320p = 9, } +/// The `VideoEncoderSource` struct represents all the types that can be send to the encoder. +pub enum VideoEncoderSource { + DirectX(SendDirectX), + Buffer((SendDirectX<*mut u8>, usize)), +} + /// The `VideoEncoder` struct represents a video encoder that can be used to encode video frames and save them to a specified file path. pub struct VideoEncoder { first_timespan: Option, - frame_sender: mpsc::Sender, TimeSpan)>>, + frame_sender: mpsc::Sender>, sample_requested: EventRegistrationToken, media_stream_source: MediaStreamSource, starting: EventRegistrationToken, @@ -237,7 +245,7 @@ impl VideoEncoder { media_stream_source.SetBufferTime(TimeSpan::default())?; let (frame_sender, frame_receiver) = - mpsc::channel::, TimeSpan)>>(); + mpsc::channel::>(); let starting = media_stream_source.Starting(&TypedEventHandler::< MediaStreamSource, @@ -273,9 +281,22 @@ impl VideoEncoder { }; match frame { - Some((surface, timespan)) => { - let sample = - MediaStreamSample::CreateFromDirect3D11Surface(&surface.0, timespan)?; + Some((source, timespan)) => { + let sample = match source { + VideoEncoderSource::DirectX(surface) => { + MediaStreamSample::CreateFromDirect3D11Surface( + &surface.0, timespan, + )? + } + VideoEncoderSource::Buffer(buffer_data) => { + let buffer = buffer_data.0; + let buffer = + unsafe { slice::from_raw_parts(buffer.0, buffer_data.1) }; + let buffer = CryptographicBuffer::CreateFromByteArray(buffer)?; + MediaStreamSample::CreateFromBuffer(&buffer, timespan)? + } + }; + sample_requested.Request()?.SetSample(&sample)?; } None => { @@ -391,7 +412,7 @@ impl VideoEncoder { media_stream_source.SetBufferTime(TimeSpan::default())?; let (frame_sender, frame_receiver) = - mpsc::channel::, TimeSpan)>>(); + mpsc::channel::>(); let starting = media_stream_source.Starting(&TypedEventHandler::< MediaStreamSource, @@ -427,9 +448,22 @@ impl VideoEncoder { }; match frame { - Some((surface, timespan)) => { - let sample = - MediaStreamSample::CreateFromDirect3D11Surface(&surface.0, timespan)?; + Some((source, timespan)) => { + let sample = match source { + VideoEncoderSource::DirectX(surface) => { + MediaStreamSample::CreateFromDirect3D11Surface( + &surface.0, timespan, + )? + } + VideoEncoderSource::Buffer(buffer_data) => { + let buffer = buffer_data.0; + let buffer = + unsafe { slice::from_raw_parts(buffer.0, buffer_data.1) }; + let buffer = CryptographicBuffer::CreateFromByteArray(buffer)?; + MediaStreamSample::CreateFromBuffer(&buffer, timespan)? + } + }; + sample_requested.Request()?.SetSample(&sample)?; } None => { @@ -511,7 +545,8 @@ impl VideoEncoder { let surface = SendDirectX(unsafe { frame.as_raw_surface() }); - self.frame_sender.send(Some((surface, timespan)))?; + self.frame_sender + .send(Some((VideoEncoderSource::DirectX(surface), timespan)))?; let (lock, cvar) = &*self.frame_notify; let mut processed = lock.lock(); @@ -532,6 +567,47 @@ impl VideoEncoder { Ok(()) } + // /// Sends a video frame to the video encoder for encoding. + // /// + // /// # Arguments + // /// + // /// * `frame` - A mutable reference to the `Frame` to be encoded. + // /// + // /// # Returns + // /// + // /// Returns `Ok(())` if the frame is successfully sent for encoding, or a `VideoEncoderError` + // /// if an error occurs. + // pub fn send_frame_buffer( + // &mut self, + // frame: &mut Frame, + // timespan: i64, + // ) -> Result<(), VideoEncoderError> { + // let timespan = TimeSpan { Duration: timespan }; + + // let surface = SendDirectX(unsafe { frame.as_raw_surface() }); + + // self.frame_sender + // .send(Some((VideoEncoderSource::DirectX(surface), timespan)))?; + + // let (lock, cvar) = &*self.frame_notify; + // let mut processed = lock.lock(); + // if !*processed { + // cvar.wait(&mut processed); + // } + // *processed = false; + // drop(processed); + + // if self.error_notify.load(atomic::Ordering::Relaxed) { + // if let Some(transcode_thread) = self.transcode_thread.take() { + // transcode_thread + // .join() + // .expect("Failed to join transcode thread")?; + // } + // } + + // Ok(()) + // } + /// Finishes encoding the video and performs any necessary cleanup. /// /// # Returns