当前位置: 首页 > web >正文

042-Windows抓屏-DXGI

Windows抓屏-DXGI

以下为基于DXGI的屏幕捕获技术调研与实现方案,结合流程图、代码框架及优化参数分析:

一、技术原理与架构

  1. DXGI抓屏核心机制

(流程图示意:初始化DXGI工厂→枚举适配器→获取输出复制接口→循环捕获帧→处理数据)

DXGI通过Desktop Duplication API直接访问显存中的桌面帧缓冲,避免传统GDI多次内存拷贝。其核心接口为

IDXGIOutputDuplication

,通过

AcquireNextFrame

获取变化区域数据。

D3D设备初始化
获取输出接口
帧数据捕获
内存映射
数据拷贝
  • 接口层级:
IDXGIDevice
IDXGIAdapter
IDXGIOutput
IDXGIOutput1
IDXGIOutputDuplication

需通过COM接口的QueryInterface逐级获取

  • 数据流特点:

仅当屏幕内容变化时触发捕获(Win10+特性),减少冗余数据处理
强制输出32位RGBA格式,避免色彩空间转换

局部截取原理

  • 通过桌面坐标系计算实现局部抓取:
RECT targetRect = {left, top, right, bottom}; 
// 计算相对于屏幕原点的偏移量
memcpy(pDestBuffer, pSrcData + (targetRect.top  * pitch) + targetRect.left  * 4, ...)

需注意内存对齐问题(RowPitch与Width*4可能不等),需逐行拷贝

架构示意图

D3D11设备初始化
枚举显示输出
是否主显示器?
创建OutputDuplication
跳过副屏处理
启动捕获线程
AcquireNextFrame
是否有新帧?
映射显存数据
拷贝到用户缓冲区
触发回调函数
视频编码/网络传输
  1. 性能优势对比
技术帧率(FPS)CPU占用率支持系统
GDI10-1515-25%WinXP+
DXGI60-1201-3%Win8+
Mirror驱动30-605-10%Win7及以下

二、代码实现框架

  1. 初始化阶段
// 创建D3D设备与DXGI工厂 
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, nullptr);IDXGIDevice* dxgiDevice = nullptr;
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);IDXGIAdapter* adapter = nullptr;
dxgiDevice->GetAdapter(&adapter);IDXGIOutput* output = nullptr;
adapter->EnumOutputs(0, &output); // 多屏需遍历输出 
  1. 帧捕获循环
IDXGIOutputDuplication* duplication = nullptr;
output->DuplicateOutput(d3dDevice, &duplication);while (true) {DXGI_OUTDUPL_FRAME_INFO frameInfo;IDXGIResource* screenResource = nullptr;HRESULT hr = duplication->AcquireNextFrame(500, &frameInfo, &screenResource);if (hr == DXGI_ERROR_WAIT_TIMEOUT) continue; // 无变化 // 处理鼠标指针 if (frameInfo.PointerPosition.Visible)ProcessMouseCursor(frameInfo.PointerPosition, frameInfo.PointerShapeBuffer);// 获取纹理数据 ID3D11Texture2D* screenTexture = nullptr;screenResource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&screenTexture);// 映射到CPU可读内存 D3D11_TEXTURE2D_DESC desc;screenTexture->GetDesc(&desc);ID3D11Texture2D* stagingTexture;CreateStagingTexture(desc, &stagingTexture);d3dDeviceContext->CopyResource(stagingTexture, screenTexture);// 处理数据(需处理RowPitch对齐)ProcessFrameData(stagingTexture);duplication->ReleaseFrame();
}

三、高级优化方案

  1. 局部捕获优化
// 设置捕获区域 
RECT captureRect = { left, top, right, bottom }; // 创建裁剪纹理 
D3D11_BOX box = { captureRect.left,  captureRect.top,  0,captureRect.right,  captureRect.bottom,  1 
};d3dDeviceContext->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, screenTexture, 0, &box);
  1. 性能调优参数
参数推荐值说明
AcquireTimeout33ms (30FPS)超时防止阻塞
StagingTexture格式DXGI_FORMAT_B8G8R8A8_UNORM兼容多数场景
FrameRetention3帧缓冲避免丢帧
多线程处理启用分离捕获与编码线程

3 性能优化参数

参数类型推荐值/方法作用说明
AcquireTimeout30-100ms避免长时间阻塞
数据拷贝多线程分段拷贝利用CPU多核优势
内存管理预分配环形缓冲区减少动态内存分配开销
GPU映射模式D3D11_MAP_READ_NO_OVERWRITE避免显存访问冲突

4 高级功能扩展

  • 鼠标光标集成
    通过DXGI_OUTDUPL_FRAME_INFO.PointerPosition获取位置,叠加绘制系统光标图标

  • 多显示器支持
    遍历所有IDXGIOutput,为每个显示器创建独立Duplication实例

  • 硬件编码集成
    结合NVIDIA NVENC或Intel QSV,实现RGB→YUV转换及H264硬编码:

libyuv::ARGBToNV12(src_rgb, dst_y, dst_uv, width, height); 
avcodec_send_frame(enc_ctx, yuv_frame);

四、错误处理关键点

switch (hr) {
case DXGI_ERROR_DEVICE_REMOVED:HandleDeviceLost(); // 重新初始化设备 break;
case DXGI_ERROR_ACCESS_LOST: duplication->Release();output->DuplicateOutput(...); // 重新获取复制接口 break;
case E_INVALIDARG:AdjustCaptureRect(); // 检查区域越界 break;
}

五、代码示例

参见GitHub仓库(基于上述原理实现):

  1. DXGI初始化与适配器枚举
  2. 多显示器支持实现
  3. 鼠标指针合成处理
  4. 局部区域捕获优化
  5. 帧数据对齐与格式转换
  6. 错误重试与资源释放

六、扩展应用场景

  • 游戏直播:结合NVENC硬编实现<5ms延迟
  • 远程桌面:差异区域检测降低带宽
  • 工业检测:ROI区域+OpenCV实时分析
  • 通过配置文件(.ini)可动态调整:
[Capture]
Width=1920
Height=1080
FPS=60 
Region=0,0,800,600 
Mouse=1 ; 是否捕获鼠标 

完整代码

Github

http://www.xdnf.cn/news/1593.html

相关文章:

  • 第三章:Transport Mechanisms
  • 单 例 模 式
  • 【前端】CSS 基础
  • 多维时序 | LightGBM多变量时序预测(Matlab完整源码和数据,适合基础小白研究)
  • CAS(Compare And Swap)
  • Ubuntu服务器上如何监控Oracle数据库
  • 电子削铅笔刀顺序图详解:从UML设计到PlantUML实现
  • 几种查看PyTorch、cuda 和 Python 版本方法
  • 关于Qt对Html/CSS的支持
  • 全链路数据仓建设指南:从构建流程到应用场景
  • Vue+Flask豆瓣LSTM影评+推荐算法大数据可视化平台深度学习系统源码
  • 文件上传--WAF绕过干货
  • 【网络入侵检测】基于Suricata源码分析NFQ IPS模式实现
  • Python torchvision.transforms 下常用图像处理方法
  • maven工程中引入外部jar
  • 数据分析之技术干货业务价值​​ powerquery 分组排序后取TOP
  • 《AI大模型应知应会100篇》 第36篇:RAG技术入门:检索增强生成原理及实现
  • 【hadoop】HBase分布式数据库安装部署
  • PyTorch生成式人工智能实战(2)——PyTorch基础
  • 13、性能优化:魔法的流畅之道——React 19 memo/lazy
  • Websocket自动发送消息客户端工具
  • LeetCode每日一题4.24
  • 硬核解析!电动汽车能耗预测与续驶里程的关键技术研究
  • 多模态大模型 Qwen2.5-VL 的学习之旅
  • 立錡科技优化 HDD、LPDDR、SoC 供电的高性能降压转换器
  • 6 种AI实用的方法,快速修复模糊照片
  • 负环-P3385-P2136
  • 让Docker端口映射受Firewall管理而非iptables
  • LVGL在VScode的WSL2中仿真
  • R 语言科研绘图第 41 期 --- 桑基图-基础