#副本 #桌面 #dxgi #捕获 #directx #低延迟

win_desktop_duplication

简单高效的 DXGI 桌面复制 API

12 个版本

0.10.11 2024 年 8 月 5 日
0.10.10 2024 年 8 月 4 日
0.10.8 2024 年 6 月 8 日
0.10.7 2023 年 11 月 6 日
0.8.2 2022 年 7 月 20 日

#104图形 API

Download history 2/week @ 2024-05-06 7/week @ 2024-05-27 190/week @ 2024-06-03 24/week @ 2024-06-10 4/week @ 2024-06-17 164/week @ 2024-07-29 200/week @ 2024-08-05 7/week @ 2024-08-12

371 每月下载量
用于 dxfilter

MIT/Apache

68KB
1K SLoC

Windows 桌面复制

docs.rs Crates.io Crates.io

此库旨在为游戏流(例如 Google Stadia、Microsoft XCloud)等应用程序提供低延迟、低级别的桌面帧访问。

提供从 Windows 桌面复制 API 获取 GPU 纹理的方便包装器。该库包括一些源 API 没有提供的有用功能

异步示例

尽管此示例展示了使用 TextureReader,但为了最佳性能,您想直接使用纹理通过硬件编码器(如 nvenc 或 quick-sync)进行编码。

use win_desktop_duplication::*;
use win_desktop_duplication::{tex_reader::*, devices::*};

#[tokio::main(flavor = "current_thread")]
async fn main() {
    // this is required to be able to use desktop duplication api
    set_process_dpi_awareness();
    co_init();


    // select gpu and output you want to use.
    let adapter = AdapterFactory::new().get_adapter_by_idx(0).unwrap();
    let output = adapter.get_display_by_idx(0).unwrap();


    // get output duplication api
    let mut dupl = DesktopDuplicationApi::new(adapter, output).unwrap();

    // Optional: get TextureReader to read GPU textures into CPU.
    let (device, ctx) = dupl.get_device_and_ctx();
    let mut texture_reader = TextureReader::new(device, ctx);


    // create a vector to hold picture data;
    let mut pic_data: Vec<u8> = vec![0; 0];
    loop {
        // this api send one frame per vsync. the frame also has cursor pre drawn
        let tex = dupl.acquire_next_vsync_frame().await;
        if let Ok(tex) = tex {
            texture_reader.get_data(&mut pic_data, &tex);
            // use pic_data as necessary
        }
    }
}

同步示例

尽管此示例展示了使用 TextureReader,但为了最佳性能,您想直接使用纹理通过硬件编码器(如 nvenc 或 quick-sync)进行编码。

use win_desktop_duplication::*;
use win_desktop_duplication::{tex_reader::*, devices::*};

fn main() {
    // this is required to be able to use desktop duplication api
    set_process_dpi_awareness();
    co_init();

    // select gpu and output you want to use.
    let adapter = AdapterFactory::new().get_adapter_by_idx(0).unwrap();
    let output = adapter.get_display_by_idx(0).unwrap();

    // get output duplication api
    let mut dupl = DesktopDuplicationApi::new(adapter, output.clone()).unwrap();

    // Optional: get TextureReader to read GPU textures into CPU.
    let (device, ctx) = dupl.get_device_and_ctx();
    let mut texture_reader = TextureReader::new(device, ctx);


    // create a vector to hold picture data;
    let mut pic_data: Vec<u8> = vec![0; 0];
    loop {
        // this api send one frame per vsync. the frame also has cursor pre drawn
        output.wait_for_vsync().unwrap();
        let tex = dupl.acquire_next_frame_now();

        if let Ok(tex) = tex {
            texture_reader.get_data(&mut pic_data, &tex);
            // use pic_data as necessary
        }
    }
}

功能

  • 提供帧时 VSync
  • 自动将光标绘制到帧上
  • 自动处理桌面切换
  • 方便的函数以在 CPU 内存中复制像素数据
  • 缩放和颜色转换(查看 dxfilter-rs)。

依赖项

~132MB
~2M SLoC