菜单

窗口与显示器捕获

相关源文件

本页面介绍了OBS Studio中窗口和显示器捕获功能的实现。这些功能允许用户捕获特定的窗口或整个显示器作为其直播或录制源。关于游戏特定捕获,请参阅游戏捕获

概述

OBS中的窗口和显示器捕获主要作为win-capture模块中的源插件来实现。它们提供了捕获以下内容的方法:

  • 单个应用程序窗口(窗口捕获)
  • 整个显示器/屏幕(显示器捕获)

两种捕获类型都支持多种捕获方法,这些方法具有不同的性能特征、兼容性和功能集。

来源:plugins/win-capture/window-capture.c66-70 plugins/win-capture/duplicator-monitor-capture.c65-69 plugins/win-capture/monitor-capture.c14-22

捕获方法

OBS实现了多种捕获窗口和显示器的方法,每种方法都有不同的能力

BitBlt (GDI) 方法

最古老且兼容性最好的捕获方法,使用Windows GDI API

  • 使用Windows BitBlt函数复制像素数据
  • 在旧版Windows上可用
  • 无法捕获某些应用程序(如浏览器和UWP应用)
  • 无法捕获HDR内容
  • 实现于dc-capture.c

Windows 图形捕获 (WGC)

Windows 10 1803+ 引入的现代捕获方法

  • 使用Windows.Graphics.Capture API
  • 对现代应用程序具有更好的兼容性
  • 可以捕获UWP应用和浏览器
  • 支持HDR内容
  • 在许多情况下CPU使用率较低
  • 实现于winrt-capture.cpp

DXGI 桌面复制

主要用于显示器捕获

  • 使用IDXGIOutputDuplication接口
  • 全屏显示器捕获性能良好
  • 支持HDR内容
  • 无法直接捕获单个窗口

捕获方法的选择是自动的(基于窗口类或显示器配置)或由用户手动指定。

来源:plugins/win-capture/window-capture.c138-167 plugins/win-capture/duplicator-monitor-capture.c247-275

窗口捕获实现

窗口捕获通过window_capture结构体和window-capture.c中的相应函数实现。

核心组件

来源:plugins/win-capture/window-capture.c76-111 plugins/win-capture/window-capture.c66-70

窗口选择过程

窗口选择过程如下

  1. 用户从下拉列表中选择一个窗口(列表中包含所有可见的窗口)
  2. OBS存储窗口的标题、类名和可执行文件名
  3. 捕获期间,OBS使用这些标识符来查找窗口
  4. 窗口匹配优先级可由用户设置
    • 按标题匹配
    • 按类名匹配
    • 按可执行文件名匹配

这种方法允许OBS在窗口句柄发生变化时(例如,如果应用程序被关闭并重新打开)继续捕获。

捕获流程

来源:plugins/win-capture/window-capture.c589-773

BitBlt 实现

BitBlt 方法使用以下方法:

  1. 创建用于捕获的设备上下文(DC)
  2. 使用BitBlt将窗口内容复制到DC
  3. 如果启用了光标捕获,则在顶部绘制光标
  4. 将捕获的数据转换为纹理供OBS渲染

BitBlt 捕获会处理不同窗口的 DPI 感知,以确保正确的缩放。

来源:plugins/win-capture/dc-capture.c151-181 plugins/win-capture/window-capture.c676-736

Windows 图形捕获实现

WGC 实现

  1. 初始化目标窗口的GraphicsCaptureItem
  2. 创建Direct3D11CaptureFramePool以接收帧
  3. 创建GraphicsCaptureSession来管理捕获
  4. 处理帧到达事件以将内容复制到OBS纹理
  5. 通过适当的像素格式处理支持HDR内容

源帧被处理并转换为具有适当颜色空间处理的OBS纹理。

来源:libobs-winrt/winrt-capture.cpp338-422 libobs-winrt/winrt-capture.cpp126-193

显示器捕获实现

OBS中有两种独立的显示器捕获实现

  1. 旧版基于GDI的显示器捕获(monitor-capture.c
  2. 现代基于复制器的捕获(duplicator-monitor-capture.c)——这是默认选项

复制器显示器捕获

较新的实现使用DXGI桌面复制或Windows图形捕获(WGC),具体取决于系统支持和用户选择。

来源:plugins/win-capture/duplicator-monitor-capture.c71-99 plugins/win-capture/duplicator-monitor-capture.c65-69

显示器选择

显示器通过以下方式识别:

  • 设备ID
  • 显示器名称
  • 显示器句柄(HMONITOR)
  • 矩形坐标

OBS显示可用显示器列表,包含其分辨率和位置,允许用户选择要捕获的显示器。

DXGI 桌面复制

使用DXGI时

  1. 从HMONITOR查找显示器索引
  2. 为显示器创建gs_duplicator
  3. 通过调用gs_duplicator_update_frame更新帧
  4. 处理显示器旋转和坐标转换
  5. 如果启用了光标捕获,则绘制光标叠加

来源:plugins/win-capture/duplicator-monitor-capture.c511-593 libobs-d3d11/d3d11-duplicator.cpp199-289

WGC 显示器捕获

与窗口捕获类似,但为显示器初始化WGC捕获

  1. 获取显示器的HMONITOR
  2. 使用winrt_capture_init_monitor初始化WGC捕获
  3. 处理帧更新
  4. 以正确的颜色空间处理帧渲染

来源:plugins/win-capture/duplicator-monitor-capture.c511-593 libobs-winrt/winrt-capture.cpp424-433

颜色空间和HDR处理

通过WGC和DXGI方法,窗口和显示器捕获都支持HDR内容

来源:plugins/win-capture/window-capture.c798-816 plugins/win-capture/duplicator-monitor-capture.c823-846 libobs-winrt/winrt-capture.cpp511-514

HDR处理的关键方面

  1. 可用时,HDR内容以RGBA16F格式捕获
  2. 用户可以强制进入SDR模式,以避免HDR显示器出现问题
  3. 捕获与输出之间的正确颜色空间转换
  4. SDR白点调整以获得正确的亮度级别

技术限制与注意事项

窗口捕获限制

  • 某些应用程序无法使用BitBlt方法捕获(浏览器、UWP应用)
  • 权限级别较低的窗口可能无法捕获
  • 图形密集型应用程序可能通过游戏捕获获得更好的性能
  • WGC需要Windows 10 1803或更高版本

显示器捕获限制

  • 随着分辨率的增加,性能影响也会增加
  • HDR捕获需要更多的系统资源
  • DXGI捕获可能与某些全屏独占模式下的游戏冲突
  • 某些图形驱动程序可能在特定捕获方法上存在问题

DPI 感知

窗口捕获通过以下方式处理不同的DPI感知模式:

  1. 获取目标窗口的DPI感知上下文
  2. 设置线程的DPI感知以匹配
  3. 适当调整坐标和尺寸
  4. 捕获后重置DPI感知

来源:plugins/win-capture/window-capture.c676-736

用户界面和选择

窗口选择UI

窗口列表通过以下方式填充:

  1. 使用EnumWindows枚举所有顶层窗口
  2. 如果需要,过滤掉最小化的窗口
  3. 获取窗口标题、类名和可执行文件名
  4. 在下拉列表中显示所有符合条件的窗口

来源:plugins/win-capture/window-capture.c514-565

显示器选择UI

显示器列表显示

  1. 显示器索引
  2. 分辨率和位置
  3. 主监视器指示符
  4. 可用时显示友好的监视器名称

每个监视器都通过设备 ID 进行标识,以便可靠跟踪。

来源: plugins/win-capture/duplicator-monitor-capture.c724-760

性能考量

  • WGC(窗口图形捕获)通常比 BitBlt(位块传输)具有更低的 CPU 使用率
  • DXGI 桌面重复捕获已针对全屏捕获进行了优化
  • 在具有多个 GPU 的笔记本电脑上,WGC 可能会提供更长的电池续航时间
  • 以原生分辨率捕获效率最高
  • 光标捕获只会增加极小的开销
  • HDR 捕获需要更多的处理能力和内存