Skip to content

Commit

Permalink
Performance Boost 🔥
Browse files Browse the repository at this point in the history
	modified:   Cargo.lock
	modified:   Cargo.toml
	modified:   README.md
	modified:   src/capture.rs
	modified:   src/frame.rs
	modified:   src/lib.rs
  • Loading branch information
NiiightmareXD committed Oct 12, 2023
1 parent 64a0431 commit 697b708
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 125 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 11 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "windows-capture"
version = "1.0.18"
version = "1.0.19"
authors = ["NiiightmareXD"]
edition = "2021"
description = "Windows Capture Simple Screen Capture for Windows 🔥"
Expand All @@ -20,19 +20,20 @@ categories = [
[dependencies]
log = "0.4.20"
parking_lot = "0.12.1"
thiserror = "1.0.48"
thiserror = "1.0.49"
windows = { version = "0.51.1", features = [
"Win32_System_WinRT_Graphics_Capture",
"Win32_Graphics_Direct3D11",
"Win32_Foundation",
"Graphics_Capture",
"Graphics",
"Foundation",
"Win32_System_WinRT_Direct3D11",
"Win32_System_Threading",
"Win32_Graphics_Direct3D",
"Graphics_Capture",
"Graphics_DirectX_Direct3D11",
"Win32_System_WinRT_Graphics_Capture",
"System",
"Win32_UI_WindowsAndMessaging",
"Win32_System_WinRT_Direct3D11",
"Win32_Graphics_Direct3D11",
"Win32_Graphics_Dxgi_Common",
"Win32_Foundation",
"Win32_Graphics_Direct3D",
"Win32_Graphics_Gdi",
"System",
"Graphics_DirectX_Direct3D11",
] }
9 changes: 2 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Add this library to your `Cargo.toml`:

```toml
[dependencies]
windows-capture = "1.0.17"
windows-capture = "1.0.19"
```
or run this command

Expand Down Expand Up @@ -65,12 +65,7 @@ impl WindowsCaptureHandler for Capture {
}

fn main() {
let settings = WindowsCaptureSettings {
item: Window::get_foreground().into(),
capture_cursor: false,
draw_border: true,
flags: (),
};
let settings = WindowsCaptureSettings::new(Monitor::get_primary(), true, false, ());

Capture::start(settings).unwrap();
}
Expand Down
119 changes: 65 additions & 54 deletions src/capture.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
use std::sync::Arc;

use log::{info, warn};
use log::info;
use parking_lot::Mutex;
use thiserror::Error;
use windows::{
core::{ComInterface, IInspectable},
core::IInspectable,
Foundation::{AsyncActionCompletedHandler, TypedEventHandler},
Graphics::{
Capture::{Direct3D11CaptureFramePool, GraphicsCaptureItem, GraphicsCaptureSession},
DirectX::DirectXPixelFormat,
},
Win32::{
Graphics::{
Direct3D11::{
ID3D11Texture2D, D3D11_CPU_ACCESS_READ, D3D11_TEXTURE2D_DESC, D3D11_USAGE_STAGING,
},
Dxgi::Common::DXGI_FORMAT_B8G8R8A8_UNORM,
},
System::WinRT::{
CreateDispatcherQueueController, Direct3D11::IDirect3DDxgiInterfaceAccess,
DispatcherQueueOptions, RoInitialize, RoUninitialize, DQTAT_COM_NONE,
DQTYPE_THREAD_CURRENT, RO_INIT_MULTITHREADED,
CreateDispatcherQueueController, DispatcherQueueOptions, RoInitialize, RoUninitialize,
DQTAT_COM_NONE, DQTYPE_THREAD_CURRENT, RO_INIT_MULTITHREADED,
},
UI::WindowsAndMessaging::{
DispatchMessageW, GetMessageW, PostQuitMessage, TranslateMessage, MSG,
Expand All @@ -47,15 +40,33 @@ pub enum WindowsCaptureError {
}

/// Capture Settings
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct WindowsCaptureSettings<Flags> {
/// Item That Can Be Created From Monitor Or Window
pub item: GraphicsCaptureItem,
item: GraphicsCaptureItem,
/// Capture Mouse Cursor
pub capture_cursor: bool,
capture_cursor: bool,
/// Draw Yellow Border Around Captured Window
pub draw_border: bool,
draw_border: bool,
/// Flags To Pass To The New Function
pub flags: Flags,
flags: Flags,
}

impl<Flags> WindowsCaptureSettings<Flags> {
/// Create Capture Settings
pub fn new<T: Into<GraphicsCaptureItem>>(
item: T,
capture_cursor: bool,
draw_border: bool,
flags: Flags,
) -> Self {
Self {
item: item.into(),
capture_cursor,
draw_border,
flags,
}
}
}

impl<Flags> Default for WindowsCaptureSettings<Flags>
Expand All @@ -73,30 +84,38 @@ where
}

/// Internal Capture Struct
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct WindowsCapture {
frame_pool: Option<Arc<Direct3D11CaptureFramePool>>,
session: Option<GraphicsCaptureSession>,
started: bool,
}

impl WindowsCapture {
pub fn new<T: WindowsCaptureHandler + std::marker::Send + 'static>(
item: GraphicsCaptureItem,
/// Create A New Internal Capture Item
pub fn new<
T: WindowsCaptureHandler + std::marker::Send + 'static,
U: Into<GraphicsCaptureItem>,
>(
item: U,
trigger: T,
) -> Result<Self, Box<dyn std::error::Error>> {
// Check Support
if !GraphicsCaptureSession::IsSupported()? {
return Err(Box::new(WindowsCaptureError::Unsupported));
}

// Init Item
let item = item.into();

// Create Device
let d3d_device = create_d3d_device()?;
let device = create_direct3d_device(&d3d_device)?;

// Create Frame Pool
let frame_pool = Direct3D11CaptureFramePool::Create(
&device,
DirectXPixelFormat::B8G8R8A8UIntNormalized,
DirectXPixelFormat::R8G8B8A8UIntNormalized,
2,
item.Size()?,
)?;
Expand Down Expand Up @@ -140,43 +159,33 @@ impl WindowsCapture {
// Get Frame Surface
let surface = frame.Surface()?;

// Convert Surface To Texture
let access = surface.cast::<IDirect3DDxgiInterfaceAccess>()?;
let texture = unsafe { access.GetInterface::<ID3D11Texture2D>()? };

// Texture Settings
let mut texture_desc = D3D11_TEXTURE2D_DESC::default();
unsafe { texture.GetDesc(&mut texture_desc) }
texture_desc.Usage = D3D11_USAGE_STAGING;
texture_desc.BindFlags = 0;
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ.0 as u32;
texture_desc.MiscFlags = 0;

if texture_desc.Format == DXGI_FORMAT_B8G8R8A8_UNORM {
// Check If The Size Has Been Changed
if frame_content_size.Width != last_size.Width
|| frame_content_size.Height != last_size.Height
{
info!("Size Changed Recreating Device");
let device = &device;
frame_pool
.Recreate(
&device.inner,
DirectXPixelFormat::B8G8R8A8UIntNormalized,
2,
frame_content_size,
)
.unwrap();

last_size = frame_content_size;
} else {
let frame = Frame::new(&surface, &d3d_device, &context);

// Send The Frame To Trigger Struct
trigger_frame_pool.lock().on_frame_arrived(&frame);
}
// Check If The Size Has Been Changed
if frame_content_size.Width != last_size.Width
|| frame_content_size.Height != last_size.Height
{
info!("Size Changed Recreating Device");
let device = &device;
frame_pool
.Recreate(
&device.inner,
DirectXPixelFormat::R8G8B8A8UIntNormalized,
2,
frame_content_size,
)
.unwrap();

last_size = frame_content_size;
} else {
warn!("Wrong Pixel Type");
let frame = Frame::new(
&surface,
&d3d_device,
&context,
frame_content_size.Width,
frame_content_size.Height,
);

// Send The Frame To Trigger Struct
trigger_frame_pool.lock().on_frame_arrived(&frame);
}

Result::Ok(())
Expand All @@ -191,6 +200,7 @@ impl WindowsCapture {
})
}

/// Start Internal Capture
pub fn start_capture(
&mut self,
capture_cursor: bool,
Expand All @@ -217,6 +227,7 @@ impl WindowsCapture {
Ok(())
}

/// Stop Internal Capture
pub fn stop_capture(mut self) {
// Stop Capturing
if let Some(frame_pool) = self.frame_pool.take() {
Expand Down
Loading

0 comments on commit 697b708

Please sign in to comment.