This commit is contained in:
mofeng-git
2025-12-28 18:19:16 +08:00
commit d143d158e4
771 changed files with 220548 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
[package]
name = "capture"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
log = "0.4"
[build-dependencies]
cc = "1.0"
bindgen = "0.59"

View File

@@ -0,0 +1,51 @@
use cc::Build;
use std::{
env,
path::{Path, PathBuf},
};
fn main() {
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let externals_dir = manifest_dir
.parent()
.unwrap()
.parent()
.unwrap()
.join("externals");
println!("cargo:rerun-if-changed=src");
println!("cargo:rerun-if-changed={}", externals_dir.display());
let ffi_header = "src/dxgi_ffi.h";
bindgen::builder()
.header(ffi_header)
.rustified_enum("*")
.generate()
.unwrap()
.write_to_file(Path::new(&env::var_os("OUT_DIR").unwrap()).join("capture_ffi.rs"))
.unwrap();
let mut builder = Build::new();
// system
#[cfg(windows)]
["d3d11", "dxgi"].map(|lib| println!("cargo:rustc-link-lib={}", lib));
#[cfg(target_os = "linux")]
println!("cargo:rustc-link-lib=stdc++");
#[cfg(windows)]
{
// dxgi
let dxgi_path = externals_dir.join("nvEncDXGIOutputDuplicationSample");
builder.include(&dxgi_path);
for f in vec!["DDAImpl.cpp"] {
builder.file(format!("{}/{}", dxgi_path.display(), f));
}
builder.file("src/dxgi.cpp");
}
// crate
builder
.cpp(false)
.static_crt(true)
.warnings(false)
.compile("capture");
}

View File

@@ -0,0 +1,42 @@
#include <DDA.h>
#include <Windows.h>
#include <string>
extern "C" void *dxgi_new_capturer(int64_t luid) {
DemoApplication *d = new DemoApplication(luid);
HRESULT hr = d->Init();
if (FAILED(hr)) {
delete d;
d = NULL;
return NULL;
}
return d;
}
extern "C" void *dxgi_device(void *capturer) {
DemoApplication *d = (DemoApplication *)capturer;
return d->Device();
}
extern "C" int dxgi_width(const void *capturer) {
DemoApplication *d = (DemoApplication *)capturer;
return d->width();
}
extern "C" int dxgi_height(const void *capturer) {
DemoApplication *d = (DemoApplication *)capturer;
return d->height();
}
extern "C" void *dxgi_capture(void *capturer, int wait_ms) {
DemoApplication *d = (DemoApplication *)capturer;
void *texture = d->Capture(wait_ms);
return texture;
}
extern "C" void destroy_dxgi_capturer(void *capturer) {
DemoApplication *d = (DemoApplication *)capturer;
if (d)
delete d;
}

View File

@@ -0,0 +1,42 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
use std::os::raw::c_void;
include!(concat!(env!("OUT_DIR"), "/capture_ffi.rs"));
pub struct Capturer {
inner: *mut c_void,
}
impl Capturer {
pub fn new(luid: i64) -> Result<Self, ()> {
let inner = unsafe { dxgi_new_capturer(luid) };
if inner.is_null() {
Err(())
} else {
Ok(Self { inner })
}
}
pub unsafe fn device(&mut self) -> *mut c_void {
dxgi_device(self.inner)
}
pub unsafe fn width(&self) -> i32 {
dxgi_width(self.inner)
}
pub unsafe fn height(&self) -> i32 {
dxgi_height(self.inner)
}
pub unsafe fn capture(&mut self, wait_ms: i32) -> *mut c_void {
dxgi_capture(self.inner, wait_ms)
}
pub unsafe fn drop(&mut self) {
destroy_dxgi_capturer(self.inner);
}
}

View File

@@ -0,0 +1,13 @@
#ifndef FFI_H
#define FFI_H
#include <stdint.h>
void *dxgi_new_capturer(int64_t luid);
void *dxgi_device(void *capturer);
int dxgi_width(const void *capturer);
int dxgi_height(const void *capturer);
void *dxgi_capture(void *capturer, int wait_ms);
void destroy_dxgi_capturer(void *capturer);
#endif // FFI_H

View File

@@ -0,0 +1,2 @@
#[cfg(windows)]
pub mod dxgi;