[OBS studio open source project from getting started to giving up] solutions for windows window collection and desktop collection

preface

obs series entry: https://blog.csdn.net/qq_33844311/article/details/121479224

Microsoft's window acquisition is mainly divided into the following four ways. obs's window acquisition and display acquisition use three of them. For details, please refer to the reference link at the end of the article.

  • GDI
  • DXGI
  • Magnification
  • Window Graphics Capturer

Here is a brief explanation. gdi window acquisition mode is the most compatible, not affected by the windows version, and is basically compatible with all versions of the system. The disadvantage is that it consumes a lot of CPU operation time by comparing CPU performance. If the mouse is not used alone, the mouse will flicker when gdi collection is used, and the specified window cannot be filtered. If a high-resolution window or screen is acquired, the acquisition frame rate may not be met on a poor device.

DXGI is a desktop acquisition method for win8 and win10 systems. Its advantage is that it uses GPU to process texture directly, with the highest efficiency. The disadvantage is that win7 system does not support.

WGC acquisition method is the fourth generation desktop acquisition technology only after win 10 1903. The advantages are the highest acquisition efficiency, high expansion screen acquisition support, and 1080p acquisition consumption of gpu reaches single digits. The disadvantage is poor compatibility. Only win10 version 1903 + can be used. The lower version cannot be used.

Registration of window collection source and desktop collection source

In win capture DLL contains the registration of the following four source s

struct obs_source_info duplicator_capture_info;  // Collecting desktops using DXGI or WGC
struct obs_source_info monitor_capture_info;  	 // Collect desktop data using GDI
struct obs_source_info window_capture_info;		 // Using the GDI or WGC collector window
struct obs_source_info game_capture_info;		 // Capture game screen through hook DirectX drawing api

Before registration, it will judge whether the Current windows system version supports DXGI or WGC high-performance window capture.

bool graphics_uses_d3d11 = false;
bool wgc_supported = false;

bool obs_module_load(void)
{
	struct win_version_info ver;
	bool win8_or_above = false;
	char *config_dir;

	struct win_version_info win1903 = {
		.major = 10, .minor = 0, .build = 18362, .revis = 0};

	config_dir = obs_module_config_path(NULL);
	if (config_dir) {
		os_mkdirs(config_dir);
		bfree(config_dir);
	}
	// Get the Current windows system version number
	get_win_ver(&ver);

	win8_or_above = ver.major > 6 || (ver.major == 6 && ver.minor >= 2);

	obs_enter_graphics();
	graphics_uses_d3d11 = gs_get_device_type() == GS_DEVICE_DIRECT3D_11;
	obs_leave_graphics();

	// Win10 version > = 10.0.18363.0 supports WGC window acquisition
	if (graphics_uses_d3d11)
		wgc_supported = win_version_compare(&ver, &win1903) >= 0;
	
	// GDI for win7 and DXGI or WGC for win8 and above
	if (win8_or_above && graphics_uses_d3d11)
		obs_register_source(&duplicator_capture_info);// High performance desktop acquisition using DXGI or WGC
	else
		obs_register_source(&monitor_capture_info);	  // Using GDI to collect desktop data has good compatibility and poor performance
	// Register window capture
	obs_register_source(&window_capture_info);

	char *config_path = obs_module_config_path(NULL);

	init_hook_files();
	init_hooks_thread =
		CreateThread(NULL, 0, init_hooks, config_path, 0, NULL);
	
	// Register Game Capture
	obs_register_source(&game_capture_info);

	return true;
}

Window acquisition

If the desktop source collection mode is automatically selected by the user, DXGI or WGC is specifically used, and there is an algorithm to select.

Refer to the submission log of obs

Submission: 7 e263ab77591e3582e49ab40418cda0b0ff7e357 [7e263ab]
Parent: c03320cfc2
 Author: jpark37 <jpark37@users.noreply.github.com>
Date: March 11, 2021:07:09
 Submitted by: Jim
 Submission time: March 12, 2021 20:59:31
win-capture: Better laptop test for auto-selection

Only auto-select WGC for desktop capture if a battery exists and
multiple GPU adapters are present. May false-positive on desktops with
a smart UPS attached, but we don't know of a better test.

Select desktop acquisition mode DXGI or WGC

If it is a desktop, select WGC's highest performance mode to collect desktop. If it is a notebook, select WGC only when the notebook has an independent graphics card

static enum display_capture_method
choose_method(enum display_capture_method method, bool wgc_supported,
	      HMONITOR monitor, int *dxgi_index)
{
	if (!wgc_supported)
		method = METHOD_DXGI;

	if (method != METHOD_WGC) {
		obs_enter_graphics();
		*dxgi_index = gs_duplicator_get_monitor_index(monitor);
		obs_leave_graphics();
	}

	if (method == METHOD_AUTO) {
		method = METHOD_DXGI;
		if (*dxgi_index == -1) {
			method = METHOD_WGC;
		} else {
			SYSTEM_POWER_STATUS status;
			// Get battery status (batteryflag = = 128 no battery)
			// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getsystempowerstatus
			// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-system_power_status
			// The WGC desktop acquisition mode is used only when the notebook has two display adapters (core display + independent display)
			if (GetSystemPowerStatus(&status) && status.BatteryFlag < 128) {
				obs_enter_graphics();
				const uint32_t count = gs_get_adapter_count();
				obs_leave_graphics();
				if (count >= 2)
					method = METHOD_WGC;
			}
		}
	}
	return method;
}

GDI window acquisition principle

GDI: Graph device interface, which is the interface for application programs to call graphics programming.
The core is to create a memory compatible DC, associate a bitmap resource, and then BitBlt calls can be copied from the video memory DC to the memory compatible DC.

DXGI window acquisition principle

After Windows 8, Microsoft introduced a new interface called "Desktop Duplication API". Because Desktop Duplication API provides desktop images through Microsoft DirectX Graphics Infrastructure (DXGI), it is very fast. Because it is through GPU, the cpu utilization is very low and the performance is very high.

  1. Create D3DDevice
  2. Get the path through a series of interfaces and get the IDXGIOutputDuplication interface
  3. Call AcquireNextFrame to obtain the current desktop data and save it in IDXGIResource
  4. Map data from GPU to memory
  5. Copy the required data to its own buffer

WGC window acquisition principle

Windows Graphics Capture is the interface provided by WinRT. obs provides the implementation of c + + call (libwinrt). You can check it yourself.
Starting with Windows 10 version 1803, windows Graphics. The capture namespace provides API s to obtain frames from display or application windows to create video streams or snapshots to build collaborative and interactive experiences.

Microsoft blog: New Ways to do Screen Capture https://blogs.windows.com/windowsdeveloper/2019/09/16/new-ways-to-do-screen-capture/

summary

obs has made a very good package for window acquisition and desktop acquisition under windows platform. If you want to understand this code, you must first have a certain understanding of GDI DXGI WGC technology.

First of all, we have to look at the official documents of Microsoft related technologies. There are no shortcuts and techniques.

The above are all personal understandings of OBS studio open source projects. It is inevitable that there are mistakes. If you have any, you are welcome to point out.

If it helps, I'm glad.

Technical reference

  1. Source of some technical points in this paper: Advanced development of FFmpeg/WebRTC/RTMP/NDK/Android audio and video streaming media
  2. Windows Desktop collection technology
  3. Webrtc screen sharing
  4. OBS principle analysis - windows window image frame capture
  5. windows - screen capture technology summary

Keywords: Windows obs

Added by dmb on Wed, 19 Jan 2022 21:30:09 +0200