From 9bdb07fdc5fc9e8d098079ca97616210b82f16fe Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Mon, 24 May 2021 23:38:06 +0200 Subject: [PATCH] Added doc comments --- ScreenCapture/DirectX/DX11ScreenCapture.cs | 22 +++- .../DirectX/DX11ScreenCaptureService.cs | 15 ++- .../Events/ScreenCaptureUpdatedEventArgs.cs | 16 ++- ScreenCapture/Helper/DPIAwareness.cs | 12 ++- ScreenCapture/IScreenCapture.cs | 35 ++++++ ScreenCapture/IScreenCaptureService.cs | 19 ++++ ScreenCapture/Model/BlackBarDetection.cs | 26 ++++- ScreenCapture/Model/CaptureZone.cs | 102 +++++++++++++++++- ScreenCapture/Model/Display.cs | 59 +++++++++- ScreenCapture/Model/GraphicsCard.cs | 54 +++++++++- .../ScreenCapture.csproj.DotSettings | 1 + 11 files changed, 346 insertions(+), 15 deletions(-) diff --git a/ScreenCapture/DirectX/DX11ScreenCapture.cs b/ScreenCapture/DirectX/DX11ScreenCapture.cs index 6cc0ce5..fb9ffdd 100644 --- a/ScreenCapture/DirectX/DX11ScreenCapture.cs +++ b/ScreenCapture/DirectX/DX11ScreenCapture.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Threading; -using ScreenCapture.Events; using SharpGen.Runtime; using Vortice.Direct3D; using Vortice.Direct3D11; @@ -15,6 +14,10 @@ using Usage = Vortice.Direct3D11.Usage; namespace ScreenCapture { + /// + /// Represents a ScreenCapture using DirectX 11 desktop duplicaton. + /// https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/desktop-dup-api + /// // ReSharper disable once InconsistentNaming public sealed class DX11ScreenCapture : IScreenCapture { @@ -36,8 +39,14 @@ namespace ScreenCapture private int _indexCounter = 0; + /// public Display Display { get; } + /// + /// Gets or sets the timeout in ms used for screen-capturing. (default 1000ms) + /// This is used in https://docs.microsoft.com/en-us/windows/win32/api/dxgi1_2/nf-dxgi1_2-idxgioutputduplication-acquirenextframe + /// + // ReSharper disable once MemberCanBePrivate.Global public int Timeout { get; set; } = 1000; private readonly IDXGIFactory1 _factory; @@ -54,12 +63,18 @@ namespace ScreenCapture #region Events + /// public event EventHandler? Updated; #endregion #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The used to create underlying objects. + /// The to duplicate. public DX11ScreenCapture(IDXGIFactory1 factory, Display display) { this._factory = factory; @@ -72,6 +87,7 @@ namespace ScreenCapture #region Methods + /// public bool CaptureScreen() { bool result = false; @@ -171,6 +187,7 @@ namespace ScreenCapture } } + /// public CaptureZone RegisterCaptureZone(int x, int y, int width, int height, int downscaleLevel = 0) { if (_device == null) throw new ApplicationException("ScreenCapture isn't initialized."); @@ -209,6 +226,7 @@ namespace ScreenCapture return captureZone; } + /// public bool UnregisterCaptureZone(CaptureZone captureZone) { lock (_captureZones) @@ -268,6 +286,7 @@ namespace ScreenCapture _captureZones[captureZone] = (stagingTexture, scalingTexture, scalingTextureView); } + /// public void Restart() { lock (_captureLock) @@ -312,6 +331,7 @@ namespace ScreenCapture } } + /// public void Dispose() => Dispose(true); private void Dispose(bool removeCaptureZones) diff --git a/ScreenCapture/DirectX/DX11ScreenCaptureService.cs b/ScreenCapture/DirectX/DX11ScreenCaptureService.cs index c24f82c..7f6080d 100644 --- a/ScreenCapture/DirectX/DX11ScreenCaptureService.cs +++ b/ScreenCapture/DirectX/DX11ScreenCaptureService.cs @@ -1,8 +1,12 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Vortice.DXGI; namespace ScreenCapture { + /// + /// + /// public class DX11ScreenCaptureService : IScreenCaptureService { #region Properties & Fields @@ -15,6 +19,9 @@ namespace ScreenCapture #region Constructors + /// + /// + /// public DX11ScreenCaptureService() { DXGI.CreateDXGIFactory1(out _factory).CheckError(); @@ -24,6 +31,7 @@ namespace ScreenCapture #region Methods + /// public IEnumerable GetGraphicsCards() { int i = 0; @@ -35,6 +43,7 @@ namespace ScreenCapture } } + /// public IEnumerable GetDisplays(GraphicsCard graphicsCard) { using IDXGIAdapter1? adapter = _factory.GetAdapter1(graphicsCard.Index); @@ -50,6 +59,7 @@ namespace ScreenCapture } } + /// public IScreenCapture GetScreenCapture(Display display) { if (!_screenCaptures.TryGetValue(display, out DX11ScreenCapture? screenCapture)) @@ -57,6 +67,7 @@ namespace ScreenCapture return screenCapture; } + /// public void Dispose() { foreach (DX11ScreenCapture screenCapture in _screenCaptures.Values) @@ -64,6 +75,8 @@ namespace ScreenCapture _screenCaptures.Clear(); _factory.Dispose(); + + GC.SuppressFinalize(this); } #endregion diff --git a/ScreenCapture/Events/ScreenCaptureUpdatedEventArgs.cs b/ScreenCapture/Events/ScreenCaptureUpdatedEventArgs.cs index f0a8d02..e9e0653 100644 --- a/ScreenCapture/Events/ScreenCaptureUpdatedEventArgs.cs +++ b/ScreenCapture/Events/ScreenCaptureUpdatedEventArgs.cs @@ -1,17 +1,29 @@ -using System; +// ReSharper disable MemberCanBePrivate.Global +using System; -namespace ScreenCapture.Events +namespace ScreenCapture { + /// + /// + /// Represents the information supplied with an -event. + /// public class ScreenCaptureUpdatedEventArgs : EventArgs { #region Properties & Fields + /// + /// true if the update was successful; otherwise, false. + /// public bool IsSuccessful { get; set; } #endregion #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// Indicates if the last update was successful. public ScreenCaptureUpdatedEventArgs(bool isSuccessful) { this.IsSuccessful = isSuccessful; diff --git a/ScreenCapture/Helper/DPIAwareness.cs b/ScreenCapture/Helper/DPIAwareness.cs index 4d8622d..4a10e3d 100644 --- a/ScreenCapture/Helper/DPIAwareness.cs +++ b/ScreenCapture/Helper/DPIAwareness.cs @@ -1,8 +1,12 @@ // ReSharper disable InconsistentNaming +// ReSharper disable MemberCanBePrivate.Global using System.Runtime.InteropServices; namespace ScreenCapture { + /// + /// Helper-class for DPI-related WIN-API calls. + /// public static class DPIAwareness { [DllImport("user32.dll", SetLastError = true)] @@ -29,9 +33,9 @@ namespace ScreenCapture DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 34 } - public static void Initalize() - { - SetProcessDpiAwarenessContext((int)DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - } + /// + /// Sets the DPI-Awareness-Context to V2. This is needed to prevent issues when using desktop duplication. + /// + public static void Initalize() => SetProcessDpiAwarenessContext((int)DPI_AWARENESS_CONTEXT.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); } } diff --git a/ScreenCapture/IScreenCapture.cs b/ScreenCapture/IScreenCapture.cs index d8f7b32..2a17399 100644 --- a/ScreenCapture/IScreenCapture.cs +++ b/ScreenCapture/IScreenCapture.cs @@ -2,13 +2,48 @@ namespace ScreenCapture { + /// + /// Represents the duplication of a single display. + /// public interface IScreenCapture : IDisposable { + /// + /// Gets the this capture is duplicating. + /// Display Display { get; } + /// + /// Occurs when the is updated. + /// + event EventHandler? Updated; + + /// + /// Attemts to capture the current frame showed on the . + /// + /// true if the current frame was captures successfully; otherwise, false. bool CaptureScreen(); + + /// + /// Creates a new for this . + /// + /// The x-location of the region to capture (must be >= 0 and < screen-width). + /// The x-location of the region to capture (must be >= 0 and < screen-height). + /// The width of the region to capture (must be >= 0 and this + x must be <= screen-width). + /// The height of the region to capture (must be >= 0 and this + y must be <= screen-height). + /// The level of downscaling applied to the image of this region before copying to local memory. The calculation is (width and height)/2^downscaleLevel. + /// The new . CaptureZone RegisterCaptureZone(int x, int y, int width, int height, int downscaleLevel = 0); + + /// + /// Removes the given from the . + /// + /// The previosly registered . + /// true if the was successfully removed; otherwise, false. bool UnregisterCaptureZone(CaptureZone captureZone); + + /// + /// Restarts the . + /// void Restart(); } } diff --git a/ScreenCapture/IScreenCaptureService.cs b/ScreenCapture/IScreenCaptureService.cs index 8e686ff..90ecbd8 100644 --- a/ScreenCapture/IScreenCaptureService.cs +++ b/ScreenCapture/IScreenCaptureService.cs @@ -3,10 +3,29 @@ using System.Collections.Generic; namespace ScreenCapture { + /// + /// + /// public interface IScreenCaptureService : IDisposable { + /// + /// Gets a enumerable of all available graphics-cards. + /// + /// A enumerable of all available graphics-cards. IEnumerable GetGraphicsCards(); + + /// + /// Gets a enumerable of all display connected to the given graphics-cards. + /// + /// The graphics-card to get the displays from. + /// A enumerable of all display connected to the given graphics-cards. IEnumerable GetDisplays(GraphicsCard graphicsCard); + + /// + /// Creates a for the given display. + /// + /// The display to duplicate. + /// The for the give display. IScreenCapture GetScreenCapture(Display display); } } diff --git a/ScreenCapture/Model/BlackBarDetection.cs b/ScreenCapture/Model/BlackBarDetection.cs index 58053ae..3cfa2cb 100644 --- a/ScreenCapture/Model/BlackBarDetection.cs +++ b/ScreenCapture/Model/BlackBarDetection.cs @@ -1,7 +1,11 @@ -using System; +// ReSharper disable MemberCanBePrivate.Global +using System; namespace ScreenCapture { + /// + /// Represents the configuration for the detection and removal of black bars around the screen image. + /// public sealed class BlackBarDetection { #region Properties & Fields @@ -9,18 +13,33 @@ namespace ScreenCapture private readonly CaptureZone _captureZone; private int? _top; + /// + /// Gets the size of the detected black bar at the top of the image. + /// public int Top => _top ??= CalculateTop(); private int? _bottom; + /// + /// Gets the size of the detected black bar at the bottom of the image. + /// public int Bottom => _bottom ??= CalculateBottom(); private int? _left; + /// + /// Gets the size of the detected black bar at the left of the image. + /// public int Left => _left ??= CalculateLeft(); private int? _right; + /// + /// Gets the size of the detected black bar at the right of the image. + /// public int Right => _right ??= CalculateRight(); private int _theshold = 0; + /// + /// Gets or sets the threshold of "blackness" used to detect black bars. (e. g. Threshold 5 will consider a pixel of color [5,5,5] as black.) (default 0) + /// public int Threshold { get => _theshold; @@ -35,7 +54,7 @@ namespace ScreenCapture #region Constructors - public BlackBarDetection(CaptureZone captureZone) + internal BlackBarDetection(CaptureZone captureZone) { this._captureZone = captureZone; } @@ -44,6 +63,9 @@ namespace ScreenCapture #region Methods + /// + /// Invalidates the cached values and recalculates , , and . + /// public void InvalidateCache() { _top = null; diff --git a/ScreenCapture/Model/CaptureZone.cs b/ScreenCapture/Model/CaptureZone.cs index 5f06d22..be5d8bc 100644 --- a/ScreenCapture/Model/CaptureZone.cs +++ b/ScreenCapture/Model/CaptureZone.cs @@ -1,45 +1,126 @@ -using System; +// ReSharper disable MemberCanBePrivate.Global +using System; namespace ScreenCapture { + /// + /// Represents a duplicated region on the screen. + /// public sealed class CaptureZone { #region Properties & Fields + /// + /// Gets the unique id of this . + /// public int Id { get; } + /// + /// Gets the x-location of the region on the screen. + /// public int X { get; } + + /// + /// Gets the y-location of the region on the screen. + /// public int Y { get; } + + /// + /// Gets the width of the region on the screen. + /// public int Width { get; } + + /// + /// Gets the height of the region on the screen. + /// public int Height { get; } + /// + /// Gets the level of downscaling applied to the image of this region before copying to local memory. The calculation is (width and height)/2^downscaleLevel. + /// public int DownscaleLevel { get; } + /// + /// Gets the original width of the region (this equals if is 0). + /// public int UnscaledWidth { get; } + + /// + /// Gets the original height of the region (this equals if is 0). + /// public int UnscaledHeight { get; } + /// + /// Gets the actually captured width of the region (this can be greated than due to size-constraints on the GPU). + /// public int CaptureWidth { get; } + + /// + /// Gets the actually captured height of the region (this can be greated than due to size-constraints on the GPU). + /// public int CaptureHeight { get; } + /// + /// Gets the width of the buffer the capture is saved to. + /// Equals most of the time but can be bigger. + /// public int BufferWidth { get; } + + /// + /// Gets the height of the buffer the capture is saved to. + /// Equals most of the time but can be bigger. + /// public int BufferHeight { get; } + + /// + /// Gets the buffer containing the image data. Format depends on the specific capture but is most likely BGRA32. + /// public byte[] Buffer { get; } + /// + /// Gets the config for black-bar detection. + /// public BlackBarDetection BlackBars { get; } + /// + /// Gets or sets if the should be automatically updated on every captured frame. + /// public bool AutoUpdate { get; set; } = true; + + /// + /// Gets if an update for the is requested on the next captured frame. + /// public bool IsUpdateRequested { get; private set; } #endregion #region Events + /// + /// Occurs when the is updated. + /// public event EventHandler? Updated; #endregion #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The unique id of this . + /// The x-location of the region on the screen. + /// The y-location of the region on the screen. + /// The width of the region on the screen. + /// The height of the region on the screen. + /// The level of downscaling applied to the image of this region before copying to local memory. + /// The original width of the region. + /// The original height of the region + /// The actually captured width of the region. + /// The actually captured height of the region. + /// The width of the buffer the capture is saved to. + /// The height of the buffer the capture is saved to. + /// The buffer containing the image data. public CaptureZone(int id, int x, int y, int width, int height, int downscaleLevel, int unscaledWidth, int unscaledHeight, int captureWidth, int captureHeight, int bufferWidth, int bufferHeight, byte[] buffer) { this.Id = id; @@ -63,8 +144,16 @@ namespace ScreenCapture #region Methods + /// + /// Requests to update this when the next frame is captured. + /// Only necessary if is set to false. + /// public void RequestUpdate() => IsUpdateRequested = true; + /// + /// Marks the as updated. + /// WARNING: This should not be called outside of an ! + /// public void SetUpdated() { IsUpdateRequested = false; @@ -73,10 +162,19 @@ namespace ScreenCapture Updated?.Invoke(this, new EventArgs()); } - public override int GetHashCode() => Id; + /// + /// Determines whether this equals the given one. + /// + /// The to compare. + /// true if the specified object is equal to the current object; otherwise, false. public bool Equals(CaptureZone other) => Id == other.Id; + + /// public override bool Equals(object? obj) => obj is CaptureZone other && Equals(other); + /// + public override int GetHashCode() => Id; + #endregion } } \ No newline at end of file diff --git a/ScreenCapture/Model/Display.cs b/ScreenCapture/Model/Display.cs index 4783081..95ab655 100644 --- a/ScreenCapture/Model/Display.cs +++ b/ScreenCapture/Model/Display.cs @@ -1,21 +1,51 @@ -namespace ScreenCapture +// ReSharper disable MemberCanBePrivate.Global + +namespace ScreenCapture { + /// + /// Represents a display connected to graphics-card. + /// public readonly struct Display { #region Properties & Fields + /// + /// Gets the index of the . + /// public int Index { get; } + + /// + /// Gets the name of the . + /// public string DeviceName { get; } + /// + /// Gets the with of the . + /// public int Width { get; } + + /// + /// Gets the height of the . + /// public int Height { get; } + /// + /// Gets the this is connected to. + /// public GraphicsCard GraphicsCard { get; } #endregion #region Constructors + /// + /// Initializes a new instance of the struct. + /// + /// The index of the . + /// The name of the . + /// The with of the . + /// The height of the . + /// The this is connected to. public Display(int index, string deviceName, int width, int height, GraphicsCard graphicsCard) { this.Index = index; @@ -28,11 +58,36 @@ #endregion #region Methods - + + /// + /// Determines whether this equals the given one. + /// + /// The to compare. + /// true if the specified object is equal to the current object; otherwise, false. public bool Equals(Display other) => Index == other.Index; + + /// public override bool Equals(object? obj) => obj is Display other && Equals(other); + + /// public override int GetHashCode() => Index; + /// + /// Determines whether two are equal. + /// + /// The first value. + /// The second value. + /// true if the two specified displays are equal; otherwise, false. + public static bool operator ==(Display left, Display right) => left.Equals(right); + + /// + /// Determines whether two are not equal. + /// + /// The first value. + /// The second value. + /// true if the two specified displays are not equal; otherwise, false. + public static bool operator !=(Display left, Display right) => !(left == right); + #endregion } } diff --git a/ScreenCapture/Model/GraphicsCard.cs b/ScreenCapture/Model/GraphicsCard.cs index 7b3fbad..12efc44 100644 --- a/ScreenCapture/Model/GraphicsCard.cs +++ b/ScreenCapture/Model/GraphicsCard.cs @@ -1,18 +1,45 @@ -namespace ScreenCapture +// ReSharper disable MemberCanBePrivate.Global + +namespace ScreenCapture { + /// + /// Represents a graphics-card. + /// public readonly struct GraphicsCard { #region Properties & Fields + /// + /// Gets the index of the . + /// public int Index { get; } + + /// + /// Gets the name of the . + /// public string Name { get; } + + /// + /// Gets the vendor-id of the . + /// public int VendorId { get; } + + /// + /// Gets the device-id of the . + /// public int DeviceId { get; } #endregion #region Constructors + /// + /// Initializes a new instance of the struct. + /// + /// The index of the . + /// The name of the . + /// The vendor-id of the . + /// The device-id of the . public GraphicsCard(int index, string name, int vendorId, int deviceId) { this.Index = index; @@ -25,10 +52,35 @@ #region Methods + /// + /// Determines whether this equals the given one. + /// + /// The to compare. + /// true if the specified object is equal to the current object; otherwise, false. public bool Equals(GraphicsCard other) => Index == other.Index; + + /// public override bool Equals(object? obj) => obj is GraphicsCard other && Equals(other); + + /// public override int GetHashCode() => Index; + /// + /// Determines whether two are equal. + /// + /// The first value. + /// The second value. + /// true if the two specified graphics-cards are equal; otherwise, false. + public static bool operator ==(GraphicsCard left, GraphicsCard right) => left.Equals(right); + + /// + /// Determines whether two are not equal. + /// + /// The first value. + /// The second value. + /// true if the two specified graphics-cards are not equal; otherwise, false. + public static bool operator !=(GraphicsCard left, GraphicsCard right) => !(left == right); + #endregion } } diff --git a/ScreenCapture/ScreenCapture.csproj.DotSettings b/ScreenCapture/ScreenCapture.csproj.DotSettings index 04cca5b..5cd2a56 100644 --- a/ScreenCapture/ScreenCapture.csproj.DotSettings +++ b/ScreenCapture/ScreenCapture.csproj.DotSettings @@ -1,4 +1,5 @@  True + True True True \ No newline at end of file