Ctrl K
ComunidadGuías…

server/tools/sunshine_wgc_capture.cpp

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * @file sunshine_wgc_capture.cpp
 * @brief Windows Graphics Capture helper process for Sunshine.
 *
 * This standalone executable provides Windows Graphics Capture functionality
 * for the main Sunshine streaming process. It runs as a separate process to
 * isolate WGC operations and handle secure desktop scenarios. The helper
 * communicates with the main process via a control pipe, shared D3D11 texture,
 * shared frame metadata, and a frame-ready event.
 */

#define WIN32_LEAN_AND_MEAN

// standard includes
#include <atomic>
#include <algorithm>
#include <array>
#include <chrono>
#include <condition_variable>
#include <deque>
#include <filesystem>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <system_error>
#include <thread>
#include <utility>

// local includes
#include "src/logging.h"
#include "src/platform/windows/ipc/misc_utils.h"
#include "src/platform/windows/ipc/pipes.h"
#include "src/platform/windows/wgc_capture_policy.h"
#include "src/utility.h"  // For RAII utilities

// platform includes
#include <d3d11.h>
#include <dxgi1_2.h>
#include <inspectable.h>  // For IInspectable
#include <KnownFolders.h>
#include <ShellScalingApi.h>  // For DPI awareness
#include <ShlObj.h>
#include <Windows.Graphics.Capture.Interop.h>
#include <Windows.h>
#include <winrt/base.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Metadata.h>  // For ApiInformation
#include <winrt/Windows.Graphics.Capture.h>
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>

// Manual declaration for CreateDirect3D11DeviceFromDXGIDevice if missing
extern "C" {
  HRESULT __stdcall CreateDirect3D11DeviceFromDXGIDevice(::IDXGIDevice *dxgiDevice, ::IInspectable **graphicsDevice);
}

/**
 * Windows structures sometimes have compile-time GUIDs. GCC supports this, but in a roundabout way.
 * If WINRT_IMPL_HAS_DECLSPEC_UUID is true, then the compiler supports adding this attribute to a struct. For example, Visual Studio.
 * If not, then MinGW GCC has a workaround to assign a GUID to a structure.
 */
struct
#if WINRT_IMPL_HAS_DECLSPEC_UUID
  __declspec(uuid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1"))
#endif
  IDirect3DDxgiInterfaceAccess: ::IUnknown {
  virtual HRESULT __stdcall GetInterface(REFIID id, IUnknown **object) = 0;
};

#if !WINRT_IMPL_HAS_DECLSPEC_UUID
static constexpr GUID GUID__IDirect3DDxgiInterfaceAccess = {
  0xA9B3D012,
  0x3DF2,
  0x4EE3,
  {0xB8, 0xD1, 0x86, 0x95, 0xF4, 0x57, 0xD3, 0xC1}
};

template<>
constexpr auto __mingw_uuidof<IDirect3DDxgiInterfaceAccess>() -> GUID const & {
  return GUID__IDirect3DDxgiInterfaceAccess;
}

static constexpr GUID GUID__IDirect3DSurface = {
  0x0BF4A146,
  0x13C1,
  0x4694,
  {0xBE, 0xE3, 0x7A, 0xBF, 0x15, 0xEA, 0xF5, 0x86}
};

template<>
constexpr auto __mingw_uuidof<winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface>() -> GUID const & {
  return GUID__IDirect3DSurface;
}
#endif

using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Graphics;
using namespace winrt::Windows::Graphics::Capture;
using namespace winrt::Windows::Graphics::DirectX;
using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
using namespace platf::dxgi;

// GPU scheduling priority definitions for optimal capture performance under high GPU load
enum class D3DKMT_SchedulingPriorityClass : LONG {
  IDLE = 0,
  BELOW_NORMAL = 1,
  NORMAL = 2,
  ABOVE_NORMAL = 3,
  HIGH = 4,
  REALTIME = 5
};

using PD3DKMTSetProcessSchedulingPriorityClass = LONG(__stdcall *)(HANDLE, LONG);

/**
 * @brief D3D11 device creation flags for the WGC helper process.
 *
 * NOTE: This constant is NOT shared with the main process. It is defined here separately
 * because including display.h would pull in too many dependencies for this standalone helper.
 * If you change this flag, you MUST update it in both this file and src/platform/windows/display.h.
 */
constexpr UINT D3D11_CREATE_DEVICE_FLAGS = 0;

/**
 * @brief Initial log level for the helper process.
 */
const int INITIAL_LOG_LEVEL = 2;

/**
 * @brief Global configuration data received from the main process.
 */
constexpr uint32_t DEFAULT_WGC_IPC_FLAGS =
  platf::dxgi::WGC_IPC_FLAG_DRAIN_TO_LATEST |
  platf::dxgi::WGC_IPC_FLAG_ALLOW_BUFFER_DECREASE;
static platf::dxgi::config_data_t g_config = {0, 0, 0, L"", {0, 0}, 10000, 60, 1, 2, DEFAULT_WGC_IPC_FLAGS, 120};
static std::mutex g_config_mutex;
static std::condition_variable g_config_cv;
static std::atomic<int32_t> g_activity_admission_fps {120};
static std::atomic<uint32_t> g_activity_admission_generation {0};

/**
 * @brief Flag indicating whether configuration data has been received from main process.
 */
static bool g_config_received = false;

/**
 * @brief Global communication pipe for sending session closed notifications.
 */
static std::weak_ptr<AsyncNamedPipe> g_communication_pipe_weak;

/**
 * @brief Global Windows event hook for desktop switch detection.
 */
static safe_winevent_hook g_desktop_switch_hook = nullptr;

/**
 * @brief Flag indicating if a secure desktop has been detected.
 */
static bool g_secure_desktop_detected = false;

/**
 * @brief Set when the GraphicsCaptureItem reports it was closed (display mode change,
 * DWM restart, monitor removal). FrameArrived never fires again after this, so the
 * helper must exit and let the main process reinitialize capture.
 */
static std::atomic<bool> g_capture_item_closed {false};

/**
 * @brief Pending verification deadline for desktop switches that were not immediately secure.
 */
static std::optional<std::chrono::steady_clock::time_point> g_pending_secure_desktop_check_deadline;

/**
 * @brief Grace window for confirming secure desktop after a desktop switch event.
 *
 * EVENT_SYSTEM_DESKTOPSWITCH can fire before OpenInputDesktop reflects the final target desktop.
 * Keep a short follow-up probe window so we still notify the main process when the switch settles
 * onto secure desktop, without forcing a reinit for ordinary non-secure desktop churn.
 */
constexpr auto SECURE_DESKTOP_CONFIRMATION_WINDOW = std::chrono::seconds(1);

void notify_main_process_about_secure_desktop() {
  if (g_secure_desktop_detected) {
    return;
  }

  g_secure_desktop_detected = true;
  g_pending_secure_desktop_check_deadline.reset();
  BOOST_LOG(info) << "Secure desktop detected - sending notification to main process";

  if (auto pipe = g_communication_pipe_weak.lock(); pipe && pipe->is_connected()) {
    uint8_t msg = SECURE_DESKTOP_MSG;
    pipe->send(std::span<const uint8_t>(&msg, 1));
    BOOST_LOG(info) << "Queued desktop switch reinit notification to main process";
  } else {
    BOOST_LOG(warning) << "Desktop switch detected, but the main process pipe is not connected";
  }
}

void poll_pending_secure_desktop_transition() {
  if (!g_pending_secure_desktop_check_deadline) {
    return;
  }

  if (platf::dxgi::is_secure_desktop_active()) {
    BOOST_LOG(info) << "Secure desktop became active shortly after desktop switch";
    notify_main_process_about_secure_desktop();
    return;
  }

  if (std::chrono::steady_clock::now() >= *g_pending_secure_desktop_check_deadline) {
    BOOST_LOG(debug) << "Desktop switch settled without entering secure desktop; ignoring reinit";
    g_pending_secure_desktop_check_deadline.reset();
  }
}

/**
 * @brief System initialization class to handle DPI, threading, and MMCSS setup.
 *
 * This class manages critical system-level initialization for optimal capture performance:
 * - Sets DPI awareness to handle high-DPI displays correctly
 * - Elevates thread priority for better capture timing
 * - Configures MMCSS (Multimedia Class Scheduler Service) for audio/video workloads
 * - Initializes WinRT apartment for Windows Graphics Capture APIs
 */
class SystemInitializer {
private:
  safe_mmcss_handle _mmcss_handle = nullptr;  ///< Handle for MMCSS thread characteristics
  bool _dpi_awareness_set = false;  ///< Flag indicating if DPI awareness was successfully set
  bool _thread_priority_set = false;  ///< Flag indicating if thread priority was elevated
  bool _mmcss_characteristics_set = false;  ///< Flag indicating if MMCSS characteristics were set
  bool _gpu_priority_set = false;  ///< Flag indicating if GPU scheduling priority was set

public:
  /**
   * @brief Initializes DPI awareness for the process.
   *
   * Attempts to set per-monitor DPI awareness to handle high-DPI displays correctly.
   * First tries the newer SetProcessDpiAwarenessContext API, then falls back to
   * SetProcessDpiAwareness if the newer API is not available.
   *
   * @return true if DPI awareness was successfully set, false otherwise.
   */
  bool initialize_dpi_awareness() {
    // Try newer API first
    if (HMODULE user32_module = GetModuleHandleA("user32.dll")) {
      using set_process_dpi_awareness_context_fn = BOOL(WINAPI *)(DPI_AWARENESS_CONTEXT);
      auto set_process_dpi_awareness_context =
        reinterpret_cast<set_process_dpi_awareness_context_fn>(
          GetProcAddress(user32_module, "SetProcessDpiAwarenessContext")
        );

      if (set_process_dpi_awareness_context &&
          set_process_dpi_awareness_context(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) {
        _dpi_awareness_set = true;
        return true;
      }
    }

    // Fallback to older API (Win 8.1+)
    if (SUCCEEDED(SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE))) {
      _dpi_awareness_set = true;
      return true;
    }

    BOOST_LOG(warning) << "Failed to set DPI awareness, display scaling issues may occur";
    return false;
  }

  /**
   * @brief Elevates the current thread priority for better capture performance.
   *
   * Sets the thread priority to THREAD_PRIORITY_HIGHEST to reduce latency
   * and improve capture frame timing consistency.
   *
   * @return true if thread priority was successfully elevated, false otherwise.
   */
  bool initialize_thread_priority() {
    if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
      BOOST_LOG(error) << "Failed to set thread priority: " << GetLastError();
      return false;
    }
    _thread_priority_set = true;
    return true;
  }

  /**
   * @brief Configures MMCSS (Multimedia Class Scheduler Service) characteristics.
   *
   * Registers the thread with MMCSS for multimedia workload scheduling.
   * First attempts "Pro Audio" task profile, then falls back to "Games" profile.
   * This helps ensure consistent timing for capture operations.
   * Additionally sets MMCSS thread relative priority to maximum for best performance.
   *
   * @return true if MMCSS characteristics were successfully set, false otherwise.
   */
  bool initialize_mmcss_characteristics() {
    DWORD task_idx = 0;
    HANDLE raw_handle = AvSetMmThreadCharacteristicsW(L"Pro Audio", &task_idx);
    if (!raw_handle) {
      raw_handle = AvSetMmThreadCharacteristicsW(L"Games", &task_idx);
      if (!raw_handle) {
        BOOST_LOG(error) << "Failed to set MMCSS characteristics: " << GetLastError();
        return false;
      }
    }

    // Set MMCSS thread relative priority to maximum (AVRT_PRIORITY_HIGH = 2)
    if (!AvSetMmThreadPriority(raw_handle, AVRT_PRIORITY_HIGH)) {
      BOOST_LOG(warning) << "Failed to set MMCSS thread priority: " << GetLastError();
      // Don't fail completely as the basic MMCSS registration still works
    }

    _mmcss_handle.reset(raw_handle);
    _mmcss_characteristics_set = true;
    return true;
  }

  /**
   * @brief Sets GPU scheduling priority for optimal capture performance under high GPU load.
   *
   * Configures the process GPU scheduling priority to REALTIME. This is critical for maintaining
   * capture performance when the GPU is under heavy load from games or other applications.
   *
   * @return true if GPU priority was successfully set, false otherwise.
   */
  bool initialize_gpu_scheduling_priority() {
    HMODULE gdi32 = GetModuleHandleA("gdi32.dll");
    if (!gdi32) {
      BOOST_LOG(warning) << "Failed to get gdi32.dll handle for GPU priority adjustment";
      return false;
    }

    auto d3dkmt_set_process_priority = reinterpret_cast<PD3DKMTSetProcessSchedulingPriorityClass>(GetProcAddress(gdi32, "D3DKMTSetProcessSchedulingPriorityClass"));
    if (!d3dkmt_set_process_priority) {
      BOOST_LOG(warning) << "D3DKMTSetProcessSchedulingPriorityClass not available, GPU priority not set";
      return false;
    }

    auto priority = static_cast<LONG>(D3DKMT_SchedulingPriorityClass::REALTIME);

    HRESULT hr = d3dkmt_set_process_priority(GetCurrentProcess(), priority);
    if (FAILED(hr)) {
      BOOST_LOG(warning) << "Failed to set GPU scheduling priority to REALTIME: " << hr
                         << " (may require administrator privileges for optimal performance)";
      return false;
    }

    BOOST_LOG(info) << "GPU scheduling priority set to REALTIME for optimal capture performance";
    _gpu_priority_set = true;
    return true;
  }

  /**
   * @brief Initializes WinRT apartment for Windows Graphics Capture APIs.
   *
   * Sets up the WinRT apartment as multi-threaded to support Windows Graphics
   * Capture operations from background threads.
   *
   * @return true always (WinRT initialization typically succeeds).
   */
  bool initialize_winrt_apartment() const {
    winrt::init_apartment(winrt::apartment_type::multi_threaded);
    return true;
  }

  /**
   * @brief Initializes all system components for optimal capture performance.
   *
   * Calls all initialization methods in sequence:
   * - DPI awareness configuration
   * - Thread priority elevation
   * - GPU scheduling priority setup
   * - MMCSS characteristics setup
   * - WinRT apartment initialization
   *
   * DPI awareness is best-effort because Windows may have already selected it for the process.
   * @return true if all required initialization steps succeeded, false if any required step failed.
   */
  bool initialize_all() {
    bool success = true;
    initialize_dpi_awareness();
    success &= initialize_thread_priority();
    success &= initialize_gpu_scheduling_priority();
    success &= initialize_mmcss_characteristics();
    success &= initialize_winrt_apartment();
    return success;
  }

  /**
   * @brief Checks if DPI awareness was successfully set.
   * @return true if DPI awareness is configured, false otherwise.
   */
  bool is_dpi_awareness_set() const {
    return _dpi_awareness_set;
  }

  /**
   * @brief Checks if thread priority was successfully elevated.
   * @return true if thread priority is elevated, false otherwise.
   */
  bool is_thread_priority_set() const {
    return _thread_priority_set;
  }

  /**
   * @brief Checks if MMCSS characteristics were successfully set.
   * @return true if MMCSS characteristics are configured, false otherwise.
   */
  bool is_mmcss_characteristics_set() const {
    return _mmcss_characteristics_set;
  }

  /**
   * @brief Checks if GPU scheduling priority was successfully set.
   * @return true if GPU scheduling priority is configured, false otherwise.
   */
  bool is_gpu_priority_set() const {
    return _gpu_priority_set;
  }

  /**
   * @brief Destructor for SystemInitializer.
   *
   * RAII automatically releases MMCSS resources.
   */
  ~SystemInitializer() noexcept = default;
};

/**
 * @brief D3D11 device management class to handle device creation and WinRT interop.
 *
 * This class manages D3D11 device and context creation, as well as the WinRT
 * interop device required for Windows Graphics Capture. It handles the complex
 * process of bridging between traditional D3D11 APIs and WinRT capture APIs.
 */
class D3D11DeviceManager {
private:
  winrt::com_ptr<ID3D11Device> _device;  ///< D3D11 device for graphics operations
  winrt::com_ptr<ID3D11DeviceContext> _context;  ///< D3D11 device context for rendering
  D3D_FEATURE_LEVEL _feature_level;  ///< D3D feature level supported by the device
  winrt::com_ptr<IDXGIDevice> _dxgi_device;  ///< DXGI device interface for WinRT interop
  winrt::com_ptr<::IDirect3DDevice> _interop_device;  ///< Intermediate interop device
  IDirect3DDevice _winrt_device = nullptr;  ///< WinRT Direct3D device for capture integration

public:
  /**
   * @brief Creates a D3D11 device and context for graphics operations.
   *
   * Creates a hardware-accelerated D3D11 device using the specified adapter.
   * The device is used for texture operations and WinRT interop.
   * Also sets GPU thread priority to 7 for optimal capture performance.
   * Uses the same D3D11_CREATE_DEVICE_FLAGS as the main Sunshine process.
   *
   * @param adapter_luid LUID of the adapter to use, or all zeros for default adapter.
   * @return true if device creation succeeded, false otherwise.
   */
  bool create_device(const LUID &adapter_luid) {
    // Feature levels to try, matching the main process
    D3D_FEATURE_LEVEL featureLevels[] {
      D3D_FEATURE_LEVEL_11_1,
      D3D_FEATURE_LEVEL_11_0,
      D3D_FEATURE_LEVEL_10_1,
      D3D_FEATURE_LEVEL_10_0,
      D3D_FEATURE_LEVEL_9_3,
      D3D_FEATURE_LEVEL_9_2,
      D3D_FEATURE_LEVEL_9_1
    };

    // Find the adapter matching the LUID
    winrt::com_ptr<IDXGIAdapter1> adapter;
    if (adapter_luid.HighPart != 0 || adapter_luid.LowPart != 0) {
      // Non-zero LUID provided, find the matching adapter
      winrt::com_ptr<IDXGIFactory1> factory;
      HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), factory.put_void());
      if (FAILED(hr)) {
        BOOST_LOG(error) << "Failed to create DXGI factory for adapter lookup";
        return false;
      }

      IDXGIAdapter1 *raw_adapter = nullptr;
      for (UINT i = 0; factory->EnumAdapters1(i, &raw_adapter) != DXGI_ERROR_NOT_FOUND; ++i) {
        winrt::com_ptr<IDXGIAdapter1> test_adapter;
        test_adapter.attach(raw_adapter);
        DXGI_ADAPTER_DESC1 desc;
        if (SUCCEEDED(test_adapter->GetDesc1(&desc))) {
          if (desc.AdapterLuid.HighPart == adapter_luid.HighPart &&
              desc.AdapterLuid.LowPart == adapter_luid.LowPart) {
            adapter = test_adapter;
            BOOST_LOG(info) << "Found matching adapter: " << wide_to_utf8(desc.Description);
            break;
          }
        }
      }

      if (!adapter) {
        BOOST_LOG(warning) << "Could not find adapter with LUID "
                           << std::hex << adapter_luid.HighPart << ":" << adapter_luid.LowPart
                           << std::dec << ", using default adapter";
      }
    } else {
      BOOST_LOG(info) << "Using default adapter (no LUID specified)";
    }

    // Create the D3D11 device using the same flags as the main process
    HRESULT hr = D3D11CreateDevice(
      adapter.get(),  // nullptr if no specific adapter found
      adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE,
      nullptr,
      D3D11_CREATE_DEVICE_FLAGS,
      featureLevels,
      ARRAYSIZE(featureLevels),
      D3D11_SDK_VERSION,
      _device.put(),
      &_feature_level,
      _context.put()
    );

    if (FAILED(hr)) {
      BOOST_LOG(error) << "Failed to create D3D11 device: " << std::hex << hr << std::dec;
      return false;
    }

    // Set GPU thread priority to 7 for optimal capture performance under high GPU load
    _dxgi_device = _device.try_as<IDXGIDevice>();
    if (_dxgi_device) {
      hr = _dxgi_device->SetGPUThreadPriority(7);
      if (FAILED(hr)) {
        BOOST_LOG(warning) << "Failed to set GPU thread priority to 7: " << hr
                           << " (may require administrator privileges for optimal performance)";
      } else {
        BOOST_LOG(info) << "GPU thread priority set to 7 for optimal capture performance";
      }
    } else {
      BOOST_LOG(warning) << "Failed to query DXGI device for GPU thread priority setting";
    }

    return true;
  }

  /**
   * @brief Creates WinRT interop device from the D3D11 device.
   *
   * Bridges the D3D11 device to WinRT APIs required for Windows Graphics Capture.
   * This involves:
   * - Querying DXGI device interface from D3D11 device
   * - Creating Direct3D interop device using WinRT factory
   * - Converting to WinRT IDirect3DDevice interface
   *
   * @return true if WinRT interop device creation succeeded, false otherwise.
   */
  bool create_winrt_interop() {
    if (!_device) {
      return false;
    }

    _dxgi_device = _device.try_as<IDXGIDevice>();
    if (!_dxgi_device) {
      BOOST_LOG(error) << "Failed to get DXGI device";
      return false;
    }

    HRESULT hr = CreateDirect3D11DeviceFromDXGIDevice(_dxgi_device.get(), reinterpret_cast<::IInspectable **>(winrt::put_abi(_interop_device)));
    if (FAILED(hr)) {
      BOOST_LOG(error) << "Failed to create interop device";
      return false;
    }

    _winrt_device = _interop_device.try_as<IDirect3DDevice>();
    if (!_winrt_device) {
      BOOST_LOG(error) << "Failed to query IDirect3DDevice from interop device";
      return false;
    }
    return true;
  }

  /**
   * @brief Initializes the D3D11 device and WinRT interop device.
   *
   * Calls create_device() with the specified adapter LUID, then create_winrt_interop() to create the WinRT interop device.
   *
   * @param adapter_luid LUID of the adapter to use, or all zeros for default adapter.
   * @return true if both device and interop device are successfully created, false otherwise.
   */
  bool initialize_all(const LUID &adapter_luid) {
    return create_device(adapter_luid) && create_winrt_interop();
  }

  /**
   * @brief Gets the underlying D3D11 device com_ptr.
   *
   * @return Pointer to the managed ID3D11Device, or empty if not initialized.
   */
  const winrt::com_ptr<ID3D11Device> &get_device() const {
    return _device;
  }

  /**
   * @brief Gets the underlying D3D11 device context com_ptr.
   *
   * @return Pointer to the managed ID3D11DeviceContext, or empty if not initialized.
   */
  const winrt::com_ptr<ID3D11DeviceContext> &get_context() const {
    return _context;
  }

  /**
   * @brief Gets the WinRT IDirect3DDevice for Windows Graphics Capture interop.
   *
   * @return The WinRT IDirect3DDevice, or nullptr if not initialized.
   */
  IDirect3DDevice get_winrt_device() const {
    return _winrt_device;
  }

  /**
   * @brief Destructor for D3D11DeviceManager.
   *
   * RAII automatically releases device and context resources.
   */
  ~D3D11DeviceManager() noexcept = default;
};

/**
 * @brief Monitor and display management class to handle monitor enumeration and selection.
 *
 * This class manages monitor detection, selection, and configuration for capture operations.
 * It handles scenarios with multiple monitors and provides resolution configuration based
 * on monitor capabilities and user preferences.
 */
class DisplayManager {
private:
  HMONITOR _selected_monitor = nullptr;  ///< Handle to the selected monitor for capture
  MONITORINFO _monitor_info = {sizeof(MONITORINFO)};  ///< Information about the selected monitor
  UINT _width = 0;  ///< Final capture width in pixels
  UINT _height = 0;  ///< Final capture height in pixels

public:
  /**
   * @brief Selects a monitor for capture based on the provided configuration.
   *
   * If a display name is specified, waits briefly for that monitor to appear.
   * Selects the primary monitor only when no display name is provided.
   *
   * @param config The configuration data containing the desired display name (if any).
   * @return true if a monitor was successfully selected; false if monitor selection failed.
   */
  bool select_monitor(const platf::dxgi::config_data_t &config) {
    auto find_requested_monitor = [&]() -> HMONITOR {
      struct EnumData {
        const wchar_t *target_name;
        HMONITOR found_monitor;
      };

      EnumData enum_data = {config.display_name, nullptr};

      auto enum_proc = +[](HMONITOR h_mon, HDC /*hdc*/, RECT * /*rc*/, LPARAM l_param) {
        auto *data = static_cast<EnumData *>(reinterpret_cast<void *>(l_param));
        if (MONITORINFOEXW m_info = {sizeof(MONITORINFOEXW)}; GetMonitorInfoW(h_mon, &m_info) && wcsncmp(m_info.szDevice, data->target_name, 32) == 0) {
          data->found_monitor = h_mon;
          return FALSE;  // Stop enumeration
        }
        return TRUE;
      };

      EnumDisplayMonitors(nullptr, nullptr, enum_proc, static_cast<LPARAM>(reinterpret_cast<std::uintptr_t>(&enum_data)));
      return enum_data.found_monitor;
    };

    // Monitor enumeration can lag during virtual display topology transitions.
    // If the bounded wait expires, let the host reinitialize capture instead of
    // streaming another display with the intended target's input coordinates.
    const bool has_requested_monitor = config.display_name[0] != L'\0';
    const auto deadline = std::chrono::steady_clock::now() + std::chrono::milliseconds(1500);
    _selected_monitor = platf::dxgi::wgc_policy::select_monitor(
      has_requested_monitor,
      find_requested_monitor,
      [] { return MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTOPRIMARY); },
      [&] {
        if (std::chrono::steady_clock::now() >= deadline) {
          return false;
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        return true;
      }
    );

    if (!_selected_monitor) {
      if (has_requested_monitor) {
        BOOST_LOG(warning) << "Could not find requested monitor '" << winrt::to_string(config.display_name)
                           << "'; capture must be reinitialized when the target is available.";
      } else {
        BOOST_LOG(error) << "Failed to get primary monitor";
      }
      return false;
    }
    return true;
  }

  /**
   * @brief Retrieves information about the currently selected monitor.
   *
   * This function queries the Windows API to obtain monitor information for the selected monitor,
   * including its dimensions. The width and height are stored as fallback values for later use.
   *
   * @return true if monitor information was successfully retrieved; false otherwise.
   */
  bool get_monitor_info() {
    if (!_selected_monitor) {
      return false;
    }

    if (!GetMonitorInfo(_selected_monitor, &_monitor_info)) {
      BOOST_LOG(error) << "Failed to get monitor info";
      return false;
    }

    return true;
  }

  /**
   * @brief Creates a Windows Graphics Capture item for the selected monitor.
   *
   * Uses the IGraphicsCaptureItemInterop interface to create a GraphicsCaptureItem
   * corresponding to the currently selected monitor. This item is required for
   * initiating Windows Graphics Capture sessions.
   *
   * @param[out] item Reference to a GraphicsCaptureItem that will be set on success.
   * @return true if the GraphicsCaptureItem was successfully created; false otherwise.
   */
  bool create_graphics_capture_item(GraphicsCaptureItem &item) {
    if (!_selected_monitor) {
      return false;
    }

    auto activation_factory = winrt::get_activation_factory<GraphicsCaptureItem, IGraphicsCaptureItemInterop>();
    HRESULT hr = activation_factory->CreateForMonitor(_selected_monitor, winrt::guid_of<GraphicsCaptureItem>(), winrt::put_abi(item));
    if (FAILED(hr)) {
      BOOST_LOG(error) << "Failed to create GraphicsCaptureItem for monitor: " << hr;
      return false;
    }
    return true;
  }

  /**
   * @brief Calculates the final capture resolution based on config, monitor info, and WGC item size.
   *
   * Chooses resolution in this order:
   *
   * - Uses config width/height if valid.
   *
   * - Otherwise uses monitor logical size.
   *
   * - If WGC item size differs significantly (DPI scaling), uses WGC physical size to avoid cropping/zoom.
   *
   * @param config The configuration data with requested width/height.
   * @param config_received True if config data was received.
   * @param item The GraphicsCaptureItem for the selected monitor.
   */
  void configure_capture_resolution(const GraphicsCaptureItem &item) {
    // Get actual WGC item size to ensure we capture full desktop (fixes zoomed display issue)
    auto item_size = item.Size();
    _height = item_size.Height;
    _width = item_size.Width;
  }

  /**
   * @brief Gets the handle to the selected monitor.
   * @return HMONITOR handle of the selected monitor, or nullptr if none selected.
   */
  HMONITOR get_selected_monitor() const {
    return _selected_monitor;
  }

  /**
   * @brief Gets the configured capture width.
   * @return Capture width in pixels.
   */
  UINT get_width() const {
    return _width;
  }

  /**
   * @brief Gets the configured capture height.
   * @return Capture height in pixels.
   */
  UINT get_height() const {
    return _height;
  }
};

/**
 * @brief Shared resource management class to handle texture, memory mapping, and events.
 *
 * This class manages shared D3D11 resources for inter-process communication with the main
 * Sunshine process. It creates a shared texture with a keyed mutex plus a shared metadata
 * view and frame-ready event for realtime cross-process delivery.
 */
class SharedResourceManager {
private:
  winrt::com_ptr<ID3D11Texture2D> _shared_texture;  ///< Shared D3D11 texture for frame data
  winrt::com_ptr<IDXGIKeyedMutex> _keyed_mutex;  ///< Keyed mutex for synchronization
  winrt::handle _shared_handle;  ///< Shared handle for cross-process sharing
  winrt::handle _frame_ready_event;  ///< Auto-reset event signaled after each published frame
  winrt::handle _frame_metadata_mapping;  ///< Shared memory containing latest frame metadata
  platf::dxgi::frame_metadata_t *_frame_metadata = nullptr;  ///< Mapped frame metadata view
  UINT _width = 0;  ///< Texture width in pixels
  UINT _height = 0;  ///< Texture height in pixels

public:
  /**
   * @brief Default constructor for SharedResourceManager.
   */
  SharedResourceManager() = default;

  /**
   * @brief Deleted copy constructor to prevent resource duplication.
   */
  SharedResourceManager(const SharedResourceManager &) = delete;

  /**
   * @brief Deleted copy assignment operator to prevent resource duplication.
   */
  SharedResourceManager &operator=(const SharedResourceManager &) = delete;

  /**
   * @brief Deleted move constructor to prevent resource transfer issues.
   */
  SharedResourceManager(SharedResourceManager &&) = delete;

  /**
   * @brief Deleted move assignment operator to prevent resource transfer issues.
   */
  SharedResourceManager &operator=(SharedResourceManager &&) = delete;

  /**
   * @brief Creates a shared D3D11 texture with keyed mutex for inter-process sharing.
   *
   * @param device Pointer to the D3D11 device used for texture creation.
   * @param texture_width Width of the texture in pixels.
   * @param texture_height Height of the texture in pixels.
   * @param format DXGI format for the texture.
   * @return true if the texture was successfully created; false otherwise.
   */
  bool create_shared_texture(const winrt::com_ptr<ID3D11Device> &device, UINT texture_width, UINT texture_height, DXGI_FORMAT format) {
    _width = texture_width;
    _height = texture_height;

    D3D11_TEXTURE2D_DESC tex_desc = {};
    tex_desc.Width = _width;
    tex_desc.Height = _height;
    tex_desc.MipLevels = 1;
    tex_desc.ArraySize = 1;
    tex_desc.Format = format;
    tex_desc.SampleDesc.Count = 1;
    tex_desc.Usage = D3D11_USAGE_DEFAULT;
    tex_desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
    // Use NT shared handles exclusively
    tex_desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;

    HRESULT hr = device->CreateTexture2D(&tex_desc, nullptr, _shared_texture.put());
    if (FAILED(hr)) {
      BOOST_LOG(error) << "Failed to create NT shared texture: " << hr;
      return false;
    }
    return true;
  }

  /**
   * @brief Acquires a keyed mutex interface from the shared texture for synchronization.
   * @return true if the keyed mutex was successfully acquired; false otherwise.
   */
  bool create_keyed_mutex() {
    if (!_shared_texture) {
      return false;
    }

    _keyed_mutex = _shared_texture.try_as<IDXGIKeyedMutex>();
    if (!_keyed_mutex) {
      BOOST_LOG(error) << "Failed to get keyed mutex";
      return false;
    }
    return true;
  }

  /**
   * @brief Creates a shared handle for the texture resource.
   *
   * @return true if the handle was successfully created; false otherwise.
   */
  bool create_shared_handle() {
    if (!_shared_texture) {
      BOOST_LOG(error) << "Cannot create shared handle - no shared texture available";
      return false;
    }

    winrt::com_ptr<IDXGIResource1> dxgi_resource1 = _shared_texture.try_as<IDXGIResource1>();
    if (!dxgi_resource1) {
      BOOST_LOG(error) << "Failed to query DXGI resource1 interface";
      return false;
    }

    // Create the shared handle
    HRESULT hr = dxgi_resource1->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr, _shared_handle.put());
    if (FAILED(hr)) {
      BOOST_LOG(error) << "Failed to create shared handle: " << hr;
      return false;
    }
    return true;
  }

  bool create_frame_signal() {
    _frame_ready_event = winrt::handle(CreateEventW(nullptr, FALSE, FALSE, nullptr));
    if (!_frame_ready_event) {
      BOOST_LOG(error) << "Failed to create frame-ready event: " << GetLastError();
      return false;
    }

    _frame_metadata_mapping = winrt::handle(CreateFileMappingW(
      INVALID_HANDLE_VALUE,
      nullptr,
      PAGE_READWRITE,
      0,
      static_cast<DWORD>(sizeof(platf::dxgi::frame_metadata_t)),
      nullptr
    ));
    if (!_frame_metadata_mapping) {
      BOOST_LOG(error) << "Failed to create frame metadata mapping: " << GetLastError();
      return false;
    }

    _frame_metadata = static_cast<platf::dxgi::frame_metadata_t *>(MapViewOfFile(
      _frame_metadata_mapping.get(),
      FILE_MAP_READ | FILE_MAP_WRITE,
      0,
      0,
      sizeof(platf::dxgi::frame_metadata_t)
    ));
    if (!_frame_metadata) {
      BOOST_LOG(error) << "Failed to map frame metadata view: " << GetLastError();
      return false;
    }

    _frame_metadata->sequence = 0;
    _frame_metadata->frame_id = 0;
    _frame_metadata->frame_qpc = 0;
    return true;
  }

  /**
   * @brief Initializes all shared resource components: texture, keyed mutex, and handle.
   *
   * @param device Pointer to the D3D11 device used for resource creation.
   * @param texture_width Width of the texture in pixels.
   * @param texture_height Height of the texture in pixels.
   * @param format DXGI format for the texture.
   * @return true if all resources were successfully initialized; false otherwise.
   */
  bool initialize_all(const winrt::com_ptr<ID3D11Device> &device, UINT texture_width, UINT texture_height, DXGI_FORMAT format) {
    return create_shared_texture(device, texture_width, texture_height, format) &&
           create_keyed_mutex() &&
           create_shared_handle() &&
           create_frame_signal();
  }

  /**
   * @brief Gets the shared handle data for inter-process sharing.
   * @return shared_handle_data_t struct containing the shared handle and texture dimensions.
   */
  platf::dxgi::shared_handle_data_t get_shared_handle_data() const {
    platf::dxgi::shared_handle_data_t data = {};
    data.texture_handle = const_cast<HANDLE>(_shared_handle.get());
    data.frame_event_handle = const_cast<HANDLE>(_frame_ready_event.get());
    data.frame_metadata_handle = const_cast<HANDLE>(_frame_metadata_mapping.get());
    data.width = _width;
    data.height = _height;
    return data;
  }

  void publish_frame_metadata(uint64_t frame_qpc) {
    if (!_frame_metadata) {
      return;
    }

    InterlockedIncrement64(&_frame_metadata->sequence);
    InterlockedExchange64(&_frame_metadata->frame_qpc, static_cast<LONG64>(frame_qpc));
    InterlockedIncrement64(&_frame_metadata->frame_id);
    InterlockedIncrement64(&_frame_metadata->sequence);
  }

  void signal_frame_ready() {
    if (!_frame_ready_event) {
      return;
    }

    SetEvent(_frame_ready_event.get());
  }

  /**
   * @brief Gets the underlying shared D3D11 texture pointer.
   * @return Pointer to the managed ID3D11Texture2D, or nullptr if not initialized.
   */
  const winrt::com_ptr<ID3D11Texture2D> &get_shared_texture() const {
    return _shared_texture;
  }

  /**
   * @brief Gets the keyed mutex interface com_ptr for the shared texture.
   * @return const winrt::com_ptr<IDXGIKeyedMutex>& (may be empty if not initialized).
   */
  const winrt::com_ptr<IDXGIKeyedMutex> &get_keyed_mutex() const {
    return _keyed_mutex;
  }

  /**
   * @brief Destructor for SharedResourceManager.
   * Uses RAII to automatically dispose resources
   */
  ~SharedResourceManager() {
    if (_frame_metadata) {
      UnmapViewOfFile(_frame_metadata);
      _frame_metadata = nullptr;
    }
  }
};

/**
 * @brief WGC capture management class to handle frame pool, capture session, and frame processing.
 *
 * This class manages the core Windows Graphics Capture functionality including:
 * - Frame pool creation and management with dynamic buffer sizing
 * - Capture session lifecycle management
 * - Frame arrival event handling and processing
 * - Frame rate optimization and adaptive buffering
 * - Integration with shared texture resources and event signaling for inter-process communication
 */
struct WgcCaptureDependencies {
  // Required devices/resources
  IDirect3DDevice winrt_device;  // WinRT Direct3D device (value-type COM handle)
  GraphicsCaptureItem graphics_item;  // Target capture item
  SharedResourceManager &resource_manager;  // Shared inter-process texture/mutex manager
  winrt::com_ptr<ID3D11DeviceContext> d3d_context;  // D3D11 context for copies
};

class WgcCaptureManager {
private:
  enum class scratch_state_e {
    free,
    reserved,
    pending,
    delivering
  };

  struct scratch_texture_t {
    winrt::com_ptr<ID3D11Texture2D> texture;
    scratch_state_e state = scratch_state_e::free;
  };

  struct delivery_frame_t {
    winrt::com_ptr<ID3D11Texture2D> texture;
    size_t scratch_index = 0;
    uint64_t frame_qpc = 0;
  };

  static constexpr auto WGC_DIAGNOSTICS_LOG_INTERVAL = std::chrono::seconds(15);
  static constexpr auto WGC_DRAIN_LOG_INTERVAL = std::chrono::seconds(5);

  std::atomic<bool> _shutting_down {false};
  Direct3D11CaptureFramePool _frame_pool = nullptr;  ///< WinRT frame pool for capture operations
  GraphicsCaptureSession _capture_session = nullptr;  ///< WinRT capture session for monitor/window capture
  winrt::event_token _frame_arrived_token {};  ///< Event token for frame arrival notifications
  std::optional<WgcCaptureDependencies> _deps;  ///< Dependencies for frame processing

  uint32_t _initial_buffer_size = 1;  ///< Minimum steady-state frame buffer size for this stream
  uint32_t _current_buffer_size = 1;  ///< Current frame buffer size for dynamic adjustment
  uint32_t _max_buffer_size = 4;  ///< Maximum allowed buffer size for adaptive growth
  static constexpr uint32_t ABSOLUTE_MAX_BUFFER_SIZE = 4;  ///< Hard cap to bound latency/VRAM

  std::deque<std::chrono::steady_clock::time_point> _drop_timestamps;  ///< Timestamps of recent frame drops for analysis
  std::atomic<int> _outstanding_frames {0};  ///< Number of frames currently being processed
  std::atomic<int> _peak_outstanding {0};  ///< Peak number of outstanding frames (for monitoring)
  std::atomic<int64_t> _last_frame_pool_pressure_us {0};  ///< Last source drop/drain pressure signal
  std::atomic<int64_t> _last_drain_log_us {0};  ///< Last rate-limited drain log timestamp
  std::atomic<int64_t> _last_diagnostics_log_us {0};  ///< Last aggregate diagnostics log timestamp
  std::chrono::steady_clock::time_point _last_quiet_start = std::chrono::steady_clock::now();  ///< Last time frame processing became quiet
  std::chrono::steady_clock::time_point _last_buffer_check = std::chrono::steady_clock::now();  ///< Last time buffer size was checked
  std::atomic<uint64_t> _captured_frames {0};
  std::atomic<uint64_t> _frame_pool_empty_drops {0};
  std::atomic<uint64_t> _drained_pool_frames {0};
  std::atomic<uint64_t> _slow_context_waits {0};
  std::atomic<uint64_t> _slow_mutex_waits {0};
  std::atomic<uint64_t> _slow_shared_mutex_holds {0};
  std::atomic<uint64_t> _slow_copy_submissions {0};
  std::atomic<uint64_t> _published_frames {0};
  std::atomic<uint64_t> _activity_rate_limited_frames {0};
  uint64_t _last_diagnostics_captured_frames = 0;
  uint64_t _last_diagnostics_published_frames = 0;
  uint64_t _last_diagnostics_empty_drops = 0;
  uint64_t _last_diagnostics_drained_frames = 0;
  uint64_t _last_diagnostics_replaced_frames = 0;
  uint64_t _last_diagnostics_scratch_dropped = 0;
  uint64_t _last_diagnostics_slow_context = 0;
  uint64_t _last_diagnostics_slow_mutex = 0;
  uint64_t _last_diagnostics_slow_hold = 0;
  uint64_t _last_diagnostics_slow_copy = 0;
  uint64_t _last_diagnostics_activity_rate_limited = 0;
  uint32_t _activity_admission_generation = 0;
  std::chrono::steady_clock::time_point _last_activity_admitted {};
  std::mutex _delivery_mutex;
  std::condition_variable _delivery_cv;
  std::jthread _delivery_thread;
  std::optional<delivery_frame_t> _pending_delivery_frame;
  bool _delivery_stop = false;
  std::mutex _d3d_context_mutex;
  std::array<scratch_texture_t, 3> _scratch_textures;
  std::atomic<uint64_t> _delivery_backpressure_waits {0};
  std::atomic<uint64_t> _delivery_replaced_frames {0};
  std::atomic<uint64_t> _scratch_dropped_frames {0};
  DXGI_FORMAT _capture_format = DXGI_FORMAT_UNKNOWN;  ///< DXGI format for captured frames
  UINT _height = 0;  ///< Capture height in pixels
  UINT _width = 0;  ///< Capture width in pixels

public:
  /**
   * @brief Constructor for WgcCaptureManager.
   *
   * Initializes the capture manager for the given dimensions and capture format and
   * stores the dependencies bundle used during capture operations.
   *
   * @param capture_format DXGI format for captured frames.
   * @param width Capture width in pixels.
   * @param height Capture height in pixels.
   * @param deps Bundle of dependencies: winrt IDirect3DDevice, GraphicsCaptureItem,
   *             reference to SharedResourceManager and D3D11 context com_ptr.
   */
  WgcCaptureManager(DXGI_FORMAT capture_format, UINT width, UINT height, WgcCaptureDependencies deps):
      _deps(std::move(deps)),
      _capture_format(capture_format),
      _height(height),
      _width(width) {
    _max_buffer_size = std::clamp<uint32_t>(
      g_config.max_frame_buffer_size ? g_config.max_frame_buffer_size : ABSOLUTE_MAX_BUFFER_SIZE,
      1,
      ABSOLUTE_MAX_BUFFER_SIZE
    );
    _initial_buffer_size = std::clamp<uint32_t>(
      g_config.initial_frame_buffer_size ? g_config.initial_frame_buffer_size : 1,
      1,
      _max_buffer_size
    );
    _current_buffer_size = _initial_buffer_size;

    const auto now = std::chrono::steady_clock::now();
    _last_quiet_start = now;
    _last_buffer_check = now;
    _last_diagnostics_log_us = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();

    _delivery_thread = std::jthread([this](std::stop_token stop_token) {
      delivery_thread_proc(stop_token);
    });
  }

  /**
   * @brief Destructor for WgcCaptureManager.
   *
   * Automatically cleans up capture session and frame pool resources.
   */
  ~WgcCaptureManager() noexcept {
    shutdown();
  }

  void shutdown() noexcept {
    if (_shutting_down.exchange(true, std::memory_order_acq_rel)) {
      return;
    }

    cleanup_capture_session();
    cleanup_frame_pool();

    // Ensure any in-flight FrameArrived callbacks have finished before destructing.
    // This avoids use-after-free on shutdown paths triggered by display reinit/HDR changes.
    auto last_log = std::chrono::steady_clock::now();
    while (_outstanding_frames.load(std::memory_order_acquire) > 0) {
      auto now = std::chrono::steady_clock::now();
      if (now - last_log > std::chrono::seconds(2)) {
        last_log = now;
        BOOST_LOG(warning) << "Waiting for " << _outstanding_frames.load(std::memory_order_relaxed)
                           << " in-flight frame(s) to finish before shutdown...";
      }
      std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }

    stop_delivery_thread();
  }

private:
  void stop_delivery_thread() noexcept {
    {
      std::lock_guard lock(_delivery_mutex);
      _delivery_stop = true;
      _pending_delivery_frame.reset();
      for (auto &scratch: _scratch_textures) {
        scratch.state = scratch_state_e::free;
      }
    }

    _delivery_cv.notify_all();
    if (_delivery_thread.joinable()) {
      _delivery_thread.request_stop();
      _delivery_thread.join();
    }
  }

  void cleanup_capture_session() noexcept {
    try {
      if (_capture_session) {
        _capture_session.Close();
        _capture_session = nullptr;
      }
    } catch (const winrt::hresult_error &ex) {
      BOOST_LOG(error) << "Exception during _capture_session.Close(): " << ex.code() << " - " << winrt::to_string(ex.message());
    } catch (...) {
      BOOST_LOG(error) << "Unknown exception during _capture_session.Close()";
    }
  }

  void cleanup_frame_pool() noexcept {
    try {
      if (_frame_pool) {
        if (_frame_arrived_token.value != 0) {
          _frame_pool.FrameArrived(_frame_arrived_token);  // Remove handler
          _frame_arrived_token.value = 0;
        }
        _frame_pool.Close();
        _frame_pool = nullptr;
      }
    } catch (const winrt::hresult_error &ex) {
      BOOST_LOG(error) << "Exception during _frame_pool.Close(): " << ex.code() << " - " << winrt::to_string(ex.message());
    } catch (...) {
      BOOST_LOG(error) << "Unknown exception during _frame_pool.Close()";
    }
  }

public:
  /**
   * @brief Deleted copy constructor to prevent resource duplication.
   */
  WgcCaptureManager(const WgcCaptureManager &) = delete;

  /**
   * @brief Deleted copy assignment operator to prevent resource duplication.
   */
  WgcCaptureManager &operator=(const WgcCaptureManager &) = delete;

  /**
   * @brief Deleted move constructor to prevent resource transfer issues.
   */
  WgcCaptureManager(WgcCaptureManager &&) = delete;
  WgcCaptureManager &operator=(WgcCaptureManager &&) = delete;

  /**
   * @brief Recreates the frame pool with a new buffer size for dynamic adjustment.
   * @param buffer_size The number of frames to buffer.
   * @returns true if the frame pool was recreated successfully, false otherwise.
   */
  bool create_or_adjust_frame_pool(uint32_t buffer_size) {
    if (!_deps || !_deps->winrt_device || _capture_format == DXGI_FORMAT_UNKNOWN) {
      return false;
    }

    if (_frame_pool) {
      // Use the proper Recreate method instead of closing and re-creating
      try {
        _frame_pool.Recreate(
          _deps->winrt_device,
          (_capture_format == DXGI_FORMAT_R16G16B16A16_FLOAT) ? DirectXPixelFormat::R16G16B16A16Float : DirectXPixelFormat::B8G8R8A8UIntNormalized,
          buffer_size,
          SizeInt32 {static_cast<int32_t>(_width), static_cast<int32_t>(_height)}
        );

        _current_buffer_size = buffer_size;
        BOOST_LOG(info) << "Frame pool recreated with buffer size: " << buffer_size;
        return true;
      } catch (const winrt::hresult_error &ex) {
        BOOST_LOG(error) << "Failed to recreate frame pool: " << ex.code() << " - " << winrt::to_string(ex.message());
        return false;
      }
    } else {
      // Initial creation case - create new frame pool
      _frame_pool = Direct3D11CaptureFramePool::CreateFreeThreaded(
        _deps->winrt_device,
        (_capture_format == DXGI_FORMAT_R16G16B16A16_FLOAT) ? DirectXPixelFormat::R16G16B16A16Float : DirectXPixelFormat::B8G8R8A8UIntNormalized,
        buffer_size,
        SizeInt32 {static_cast<int32_t>(_width), static_cast<int32_t>(_height)}
      );

      if (_frame_pool) {
        _current_buffer_size = buffer_size;
        BOOST_LOG(info) << "Frame pool created with buffer size: " << buffer_size;
        return true;
      }
    }

    return false;
  }

  /**
   * @brief Processes a frame when the frame arrived event is triggered.
   * @param sender The frame pool that triggered the event.
   */
  void process_frame(Direct3D11CaptureFramePool const &sender) {
    // Track callback invocations
    static std::atomic<uint64_t> callback_count {0};
    auto cc = ++callback_count;
    if (cc == 1) {
      BOOST_LOG(info) << "First FrameArrived callback invoked";
    }

    Direct3D11CaptureFrame frame = nullptr;
    uint32_t drained_frames = 0;

    try {
      if (drain_to_latest()) {
        while (auto next_frame = sender.TryGetNextFrame()) {
          if (frame) {
            ++drained_frames;
          }
          frame = std::move(next_frame);
        }
      } else {
        frame = sender.TryGetNextFrame();
      }
    } catch (const winrt::hresult_error &ex) {
      BOOST_LOG(error) << "WinRT error retrieving WGC frame: " << ex.code() << " - " << winrt::to_string(ex.message());
      return;
    }

    if (!frame) {
      // Frame drop detected - record timestamp for sliding window analysis
      auto now = std::chrono::steady_clock::now();
      _drop_timestamps.push_back(now);
      record_frame_pool_pressure(now);

      const auto total_empty_drops = _frame_pool_empty_drops.fetch_add(1, std::memory_order_relaxed) + 1;
      if (total_empty_drops <= 5 || total_empty_drops % 120 == 0) {
        BOOST_LOG(info) << "WGC frame pool returned no frame"
                        << " (recent drops in 5s window=" << _drop_timestamps.size()
                        << ", total=" << total_empty_drops << ")";
      }
    } else {
      // Frame successfully retrieved
      try {
        auto surface = frame.Surface();

        // Get frame timing information from the WGC frame. The consumer treats
        // it as QPC ticks, so convert from the TimeSpan's 100 ns units.
        static const int64_t qpc_frequency = [] {
          LARGE_INTEGER frequency {};
          QueryPerformanceFrequency(&frequency);
          return static_cast<int64_t>(frequency.QuadPart);
        }();
        uint64_t frame_qpc = platf::dxgi::wgc_policy::system_relative_time_to_qpc(
          frame.SystemRelativeTime().count(),
          qpc_frequency
        );
        record_frame_arrival(drained_frames);
        if (admit_activity_frame()) {
          queue_frame_for_delivery(std::move(frame), surface, frame_qpc);
        }
      } catch (const winrt::hresult_error &ex) {
        // Log error
        BOOST_LOG(error) << "WinRT error in frame processing: " << ex.code() << " - " << winrt::to_string(ex.message());
      }
    }

    // Check if we need to adjust frame buffer size
    check_and_adjust_frame_buffer();
  }

private:
  bool drain_to_latest() const {
    return (g_config.flags & platf::dxgi::WGC_IPC_FLAG_DRAIN_TO_LATEST) != 0;
  }

  bool allow_buffer_decrease() const {
    return (g_config.flags & platf::dxgi::WGC_IPC_FLAG_ALLOW_BUFFER_DECREASE) != 0;
  }

  static int64_t steady_time_us(const std::chrono::steady_clock::time_point &time) {
    return std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count();
  }

  void record_frame_pool_pressure(const std::chrono::steady_clock::time_point &now) {
    _last_frame_pool_pressure_us.store(steady_time_us(now), std::memory_order_relaxed);
  }

  static bool should_log_rate_limited(std::atomic<int64_t> &last_log_us, const std::chrono::steady_clock::time_point &now, std::chrono::microseconds interval) {
    const auto now_us = steady_time_us(now);
    auto last_us = last_log_us.load(std::memory_order_relaxed);
    while (last_us == 0 || now_us - last_us >= interval.count()) {
      if (last_log_us.compare_exchange_weak(last_us, now_us, std::memory_order_acq_rel, std::memory_order_relaxed)) {
        return true;
      }
    }
    return false;
  }

  double expected_frame_ms() const {
    return 1000.0 / static_cast<double>(std::max(1, g_config.target_fps));
  }

  double approximate_extra_pool_latency_ms(uint32_t buffer_size) const {
    return buffer_size > _initial_buffer_size ?
             static_cast<double>(buffer_size - _initial_buffer_size) * expected_frame_ms() :
             0.0;
  }

  void record_frame_arrival(uint32_t drained_frames) {
    _captured_frames.fetch_add(1, std::memory_order_relaxed);

    if (drained_frames > 0) {
      const auto now = std::chrono::steady_clock::now();
      record_frame_pool_pressure(now);
      const auto total_drained = _drained_pool_frames.fetch_add(drained_frames, std::memory_order_relaxed) + drained_frames;
      if (should_log_rate_limited(_last_drain_log_us, now, std::chrono::duration_cast<std::chrono::microseconds>(WGC_DRAIN_LOG_INTERVAL))) {
        BOOST_LOG(info) << "WGC drained " << drained_frames << " queued frame(s) from frame pool"
                        << " (total_drained=" << total_drained
                        << ", buffer=" << _current_buffer_size << "/" << _max_buffer_size
                        << ", approx_extra_pool_latency_ms=" << approximate_extra_pool_latency_ms(_current_buffer_size) << ")";
      }
    }
  }

  void maybe_log_capture_diagnostics(const std::chrono::steady_clock::time_point &now) {
    const auto now_us = steady_time_us(now);
    auto last_log_us = _last_diagnostics_log_us.load(std::memory_order_relaxed);
    const auto interval_us = std::chrono::duration_cast<std::chrono::microseconds>(WGC_DIAGNOSTICS_LOG_INTERVAL).count();

    while (now_us - last_log_us >= interval_us) {
      if (!_last_diagnostics_log_us.compare_exchange_weak(last_log_us, now_us, std::memory_order_acq_rel, std::memory_order_relaxed)) {
        continue;
      }

      const double interval_s = static_cast<double>(now_us - last_log_us) / 1000000.0;
      if (interval_s <= 0.0) {
        return;
      }

      const auto captured = _captured_frames.load(std::memory_order_relaxed);
      const auto published = _published_frames.load(std::memory_order_relaxed);
      const auto empty_drops = _frame_pool_empty_drops.load(std::memory_order_relaxed);
      const auto drained = _drained_pool_frames.load(std::memory_order_relaxed);
      const auto replaced = _delivery_replaced_frames.load(std::memory_order_relaxed);
      const auto scratch_dropped = _scratch_dropped_frames.load(std::memory_order_relaxed);
      const auto slow_context = _slow_context_waits.load(std::memory_order_relaxed);
      const auto slow_mutex = _slow_mutex_waits.load(std::memory_order_relaxed);
      const auto slow_hold = _slow_shared_mutex_holds.load(std::memory_order_relaxed);
      const auto slow_copy = _slow_copy_submissions.load(std::memory_order_relaxed);
      const auto activity_rate_limited = _activity_rate_limited_frames.load(std::memory_order_relaxed);

      const auto captured_delta = captured - _last_diagnostics_captured_frames;
      const auto published_delta = published - _last_diagnostics_published_frames;
      const auto empty_drop_delta = empty_drops - _last_diagnostics_empty_drops;
      const auto drained_delta = drained - _last_diagnostics_drained_frames;
      const auto replaced_delta = replaced - _last_diagnostics_replaced_frames;
      const auto scratch_dropped_delta = scratch_dropped - _last_diagnostics_scratch_dropped;
      const auto slow_context_delta = slow_context - _last_diagnostics_slow_context;
      const auto slow_mutex_delta = slow_mutex - _last_diagnostics_slow_mutex;
      const auto slow_hold_delta = slow_hold - _last_diagnostics_slow_hold;
      const auto slow_copy_delta = slow_copy - _last_diagnostics_slow_copy;
      const auto activity_rate_limited_delta = activity_rate_limited - _last_diagnostics_activity_rate_limited;

      _last_diagnostics_captured_frames = captured;
      _last_diagnostics_published_frames = published;
      _last_diagnostics_empty_drops = empty_drops;
      _last_diagnostics_drained_frames = drained;
      _last_diagnostics_replaced_frames = replaced;
      _last_diagnostics_scratch_dropped = scratch_dropped;
      _last_diagnostics_slow_context = slow_context;
      _last_diagnostics_slow_mutex = slow_mutex;
      _last_diagnostics_slow_hold = slow_hold;
      _last_diagnostics_slow_copy = slow_copy;
      _last_diagnostics_activity_rate_limited = activity_rate_limited;

      BOOST_LOG(info) << "WGC capture diagnostics: interval_s=" << interval_s
                      << " buffer=" << _current_buffer_size << "/" << _max_buffer_size
                      << " approx_extra_pool_latency_ms=" << approximate_extra_pool_latency_ms(_current_buffer_size)
                      << " capture_fps=" << (static_cast<double>(captured_delta) / interval_s)
                      << " publish_fps=" << (static_cast<double>(published_delta) / interval_s)
                      << " drained=" << drained_delta
                      << " activity_rate_limited=" << activity_rate_limited_delta
                      << " empty_drops=" << empty_drop_delta
                      << " delivery_replaced=" << replaced_delta
                      << " scratch_dropped=" << scratch_dropped_delta
                      << " slow_context=" << slow_context_delta
                      << " slow_mutex=" << slow_mutex_delta
                      << " slow_shared_hold=" << slow_hold_delta
                      << " slow_copy=" << slow_copy_delta;
      return;
    }
  }

  bool admit_activity_frame() {
    const auto generation = g_activity_admission_generation.load(std::memory_order_acquire);
    if (generation != _activity_admission_generation) {
      _activity_admission_generation = generation;
      _last_activity_admitted = {};
    }

    const auto admission_fps = g_activity_admission_fps.load(std::memory_order_relaxed);
    if (admission_fps <= 0) {
      return true;
    }

    const auto now = std::chrono::steady_clock::now();
    const auto minimum_interval = std::chrono::nanoseconds(std::chrono::seconds(1)) / admission_fps;
    if (_last_activity_admitted.time_since_epoch().count() != 0 &&
        now - _last_activity_admitted < minimum_interval) {
      _activity_rate_limited_frames.fetch_add(1, std::memory_order_relaxed);
      return false;
    }

    _last_activity_admitted = now;
    return true;
  }

  /**
   * @brief Prunes old frame drop timestamps from the sliding window.
   * @param now Current timestamp for comparison.
   */
  void prune_old_drop_timestamps(const std::chrono::steady_clock::time_point &now) {
    while (!_drop_timestamps.empty() && now - _drop_timestamps.front() > std::chrono::seconds(5)) {
      _drop_timestamps.pop_front();
    }
  }

  /**
   * @brief Checks if buffer size should be increased due to recent frame drops.
   * @param now Current timestamp.
   * @return true if buffer was increased, false otherwise.
   */
  bool try_increase_buffer_size(const std::chrono::steady_clock::time_point &now) {
    if (_drop_timestamps.size() >= 2 && _current_buffer_size < _max_buffer_size) {
      uint32_t new_buffer_size = _current_buffer_size + 1;
      BOOST_LOG(info) << "Detected " << _drop_timestamps.size() << " frame drops in 5s window, increasing buffer from "
                      << _current_buffer_size << " to " << new_buffer_size
                      << " (approx_extra_pool_latency_ms=" << approximate_extra_pool_latency_ms(new_buffer_size) << ")";
      create_or_adjust_frame_pool(new_buffer_size);
      _drop_timestamps.clear();  // Reset after adjustment
      _peak_outstanding = 0;  // Reset peak tracking
      _last_quiet_start = now;  // Reset quiet timer
      return true;
    }
    return false;
  }

  /**
   * @brief Checks if buffer size should be decreased due to sustained quiet period.
   * @param now Current timestamp.
   * @return true if buffer was decreased, false otherwise.
   */
  bool try_decrease_buffer_size(const std::chrono::steady_clock::time_point &now) {
    if (!allow_buffer_decrease()) {
      return false;
    }

    constexpr auto quiet_period = std::chrono::seconds(30);
    const auto last_pressure_us = _last_frame_pool_pressure_us.load(std::memory_order_relaxed);
    const auto quiet_period_us = std::chrono::duration_cast<std::chrono::microseconds>(quiet_period).count();
    const bool recent_pool_pressure = last_pressure_us > 0 &&
                                      steady_time_us(now) - last_pressure_us < quiet_period_us;
    const bool is_quiet = platf::dxgi::wgc_policy::buffer_pool_is_quiet(
      allow_buffer_decrease(),
      !_drop_timestamps.empty(),
      recent_pool_pressure,
      _peak_outstanding.load(),
      _current_buffer_size
    );

    if (!is_quiet) {
      _last_quiet_start = now;  // Reset quiet timer
      return false;
    }

    // Check if we've been quiet for 30 seconds
    if (now - _last_quiet_start >= quiet_period && _current_buffer_size > _initial_buffer_size) {
      uint32_t new_buffer_size = _current_buffer_size - 1;
      BOOST_LOG(info) << "Sustained quiet period (30s) with peak occupancy " << _peak_outstanding.load()
                      << " <= " << (_current_buffer_size - 1) << ", decreasing buffer from "
                      << _current_buffer_size << " to " << new_buffer_size
                      << " (approx_extra_pool_latency_ms=" << approximate_extra_pool_latency_ms(new_buffer_size) << ")";
      create_or_adjust_frame_pool(new_buffer_size);
      _peak_outstanding = 0;  // Reset peak tracking
      _last_quiet_start = now;  // Reset quiet timer
      return true;
    }

    return false;
  }

  bool ensure_scratch_texture(size_t index) {
    if (!_deps || index >= _scratch_textures.size()) {
      return false;
    }

    auto &scratch = _scratch_textures[index];
    if (scratch.texture) {
      return true;
    }

    winrt::com_ptr<ID3D11Device> device;
    _deps->d3d_context->GetDevice(device.put());
    if (!device) {
      BOOST_LOG(error) << "Failed to get D3D11 device for WGC scratch texture";
      return false;
    }

    D3D11_TEXTURE2D_DESC desc = {};
    desc.Width = _width;
    desc.Height = _height;
    desc.MipLevels = 1;
    desc.ArraySize = 1;
    desc.Format = _capture_format;
    desc.SampleDesc.Count = 1;
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;

    HRESULT hr = device->CreateTexture2D(&desc, nullptr, scratch.texture.put());
    if (FAILED(hr)) {
      BOOST_LOG(error) << "Failed to create WGC scratch texture: " << std::format(": 0x{:08X}", hr);
      return false;
    }

    return true;
  }

  std::optional<size_t> reserve_scratch_texture() {
    std::lock_guard lock(_delivery_mutex);

    if (_delivery_stop || _shutting_down.load(std::memory_order_acquire)) {
      return std::nullopt;
    }

    for (size_t i = 0; i < _scratch_textures.size(); ++i) {
      if (_scratch_textures[i].state == scratch_state_e::free) {
        _scratch_textures[i].state = scratch_state_e::reserved;
        return i;
      }
    }

    if (_pending_delivery_frame) {
      const auto stale_index = _pending_delivery_frame->scratch_index;
      if (stale_index >= _scratch_textures.size()) {
        _pending_delivery_frame.reset();
        return std::nullopt;
      }

      _pending_delivery_frame.reset();
      _scratch_textures[stale_index].state = scratch_state_e::reserved;

      const auto replaced = _delivery_replaced_frames.fetch_add(1, std::memory_order_relaxed) + 1;
      if (replaced <= 5 || replaced % 120 == 0) {
        BOOST_LOG(debug) << "WGC delivery replaced stale queued scratch frame"
                         << " (count=" << replaced << ")";
      }
      return stale_index;
    }

    const auto dropped = _scratch_dropped_frames.fetch_add(1, std::memory_order_relaxed) + 1;
    if (dropped <= 5 || dropped % 120 == 0) {
      BOOST_LOG(debug) << "WGC scratch handoff had no free texture; dropping frame"
                       << " (count=" << dropped << ")";
    }
    return std::nullopt;
  }

  void release_reserved_scratch_texture(size_t index) {
    std::lock_guard lock(_delivery_mutex);
    if (index < _scratch_textures.size() && _scratch_textures[index].state == scratch_state_e::reserved) {
      _scratch_textures[index].state = scratch_state_e::free;
    }
  }

  bool enqueue_scratch_texture(size_t index, uint64_t frame_qpc) {
    std::lock_guard lock(_delivery_mutex);

    if (index >= _scratch_textures.size() || !_scratch_textures[index].texture) {
      return false;
    }

    if (_delivery_stop || _shutting_down.load(std::memory_order_acquire)) {
      _scratch_textures[index].state = scratch_state_e::free;
      return false;
    }

    if (_pending_delivery_frame) {
      const auto stale_index = _pending_delivery_frame->scratch_index;
      _pending_delivery_frame.reset();
      if (stale_index < _scratch_textures.size()) {
        _scratch_textures[stale_index].state = scratch_state_e::free;
      }

      const auto replaced = _delivery_replaced_frames.fetch_add(1, std::memory_order_relaxed) + 1;
      if (replaced <= 5 || replaced % 120 == 0) {
        BOOST_LOG(debug) << "WGC delivery replaced stale queued scratch frame"
                         << " (count=" << replaced << ")";
      }
    }

    _scratch_textures[index].state = scratch_state_e::pending;
    _pending_delivery_frame = delivery_frame_t {
      .texture = _scratch_textures[index].texture,
      .scratch_index = index,
      .frame_qpc = frame_qpc
    };
    return true;
  }

  /**
   * @brief Copies the next WGC frame into helper-owned scratch storage and queues it for delivery.
   * @param frame The WGC frame object; it is released before the shared IPC mutex can block.
   * @param surface The captured D3D11 surface.
   * @param frame_qpc The QPC timestamp from when the frame was captured.
   */
  void queue_frame_for_delivery(Direct3D11CaptureFrame frame, winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface surface, uint64_t frame_qpc) {
    if (!_deps) {
      return;
    }

    // Get DXGI access
    winrt::com_ptr<IDirect3DDxgiInterfaceAccess> ia;
    if (FAILED(winrt::get_unknown(surface)->QueryInterface(__uuidof(IDirect3DDxgiInterfaceAccess), ia.put_void()))) {
      BOOST_LOG(error) << "Failed to query IDirect3DDxgiInterfaceAccess";
      return;
    }

    // Get underlying texture
    winrt::com_ptr<ID3D11Texture2D> frame_tex;
    if (FAILED(ia->GetInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<::IUnknown **>(frame_tex.put_void())))) {
      BOOST_LOG(error) << "Failed to get ID3D11Texture2D from interface";
      return;
    }

    auto scratch_index = reserve_scratch_texture();
    if (!scratch_index) {
      return;
    }

    if (!ensure_scratch_texture(*scratch_index)) {
      release_reserved_scratch_texture(*scratch_index);
      return;
    }

    {
      std::lock_guard context_lock(_d3d_context_mutex);
      _deps->d3d_context->CopyResource(_scratch_textures[*scratch_index].texture.get(), frame_tex.get());
    }

    // From here on the delivery thread owns only the helper scratch texture, not
    // the Direct3D11CaptureFrame/WGC frame-pool buffer. The helper can wait for
    // the main process' shared keyed mutex without starving WGC FrameArrived.
    frame = nullptr;

    if (!enqueue_scratch_texture(*scratch_index, frame_qpc)) {
      return;
    }
    _delivery_cv.notify_one();
  }

  void delivery_thread_proc(std::stop_token stop_token) noexcept {
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    DWORD task_idx = 0;
    safe_mmcss_handle mmcss_handle = nullptr;
    HANDLE raw_mmcss_handle = AvSetMmThreadCharacteristicsW(L"Pro Audio", &task_idx);
    if (!raw_mmcss_handle) {
      raw_mmcss_handle = AvSetMmThreadCharacteristicsW(L"Games", &task_idx);
    }
    if (raw_mmcss_handle) {
      mmcss_handle.reset(raw_mmcss_handle);
      AvSetMmThreadPriority(mmcss_handle.get(), AVRT_PRIORITY_HIGH);
    } else {
      BOOST_LOG(warning) << "Failed to set WGC delivery thread MMCSS characteristics: " << GetLastError();
    }

    for (;;) {
      std::optional<delivery_frame_t> frame;
      {
        std::unique_lock lock(_delivery_mutex);
        _delivery_cv.wait(lock, [&]() {
          return _delivery_stop || stop_token.stop_requested() || _pending_delivery_frame.has_value();
        });

        if (_delivery_stop || stop_token.stop_requested()) {
          break;
        }

        frame = std::move(_pending_delivery_frame);
        _pending_delivery_frame.reset();
        if (frame && frame->scratch_index < _scratch_textures.size()) {
          _scratch_textures[frame->scratch_index].state = scratch_state_e::delivering;
        }
      }
      _delivery_cv.notify_all();

      if (!frame || !frame->texture) {
        continue;
      }

      try {
        copy_frame_to_shared_texture(frame->texture, frame->frame_qpc);
      } catch (const winrt::hresult_error &ex) {
        BOOST_LOG(error) << "WinRT error in WGC delivery thread: " << ex.code() << " - " << winrt::to_string(ex.message());
      } catch (...) {
        BOOST_LOG(error) << "Unknown error in WGC delivery thread";
      }

      {
        std::lock_guard lock(_delivery_mutex);
        if (frame->scratch_index < _scratch_textures.size() &&
            _scratch_textures[frame->scratch_index].state == scratch_state_e::delivering) {
          _scratch_textures[frame->scratch_index].state = scratch_state_e::free;
        }
      }
    }
  }

  /**
   * @brief Copies the captured texture to the shared texture and signals the main process.
   * @param frame_tex The captured D3D11 texture.
   * @param frame_qpc The QPC timestamp from when the frame was captured.
   */
  void copy_frame_to_shared_texture(const winrt::com_ptr<ID3D11Texture2D> &frame_tex, uint64_t frame_qpc) {
    if (!_deps || !frame_tex) {
      return;
    }

    // Take the helper-local D3D context lock before the cross-process keyed
    // mutex. The callback thread also uses this context for scratch copies; if
    // GPU load makes that copy slow, waiting here must not block Sunshine from
    // acquiring the shared WGC texture.
    const auto context_wait_start = std::chrono::steady_clock::now();
    std::unique_lock context_lock(_d3d_context_mutex);
    const auto context_wait = std::chrono::steady_clock::now() - context_wait_start;

    const auto mutex_wait_start = std::chrono::steady_clock::now();
    HRESULT hr = _deps->resource_manager.get_keyed_mutex()->AcquireSync(0, 200);
    const auto mutex_wait = std::chrono::steady_clock::now() - mutex_wait_start;
    if (hr == WAIT_TIMEOUT) {
      const auto slow_mutex_count = _slow_mutex_waits.fetch_add(1, std::memory_order_relaxed) + 1;
      if (slow_mutex_count <= 5 || slow_mutex_count % 120 == 0) {
        BOOST_LOG(debug) << "Timed out acquiring keyed mutex for WGC frame copy; dropping frame"
                         << " (count=" << slow_mutex_count << ")";
      }
      return;
    }
    if (hr != S_OK && hr != WAIT_ABANDONED) {
      BOOST_LOG(error) << "Failed to acquire mutex key 0: " << std::format(": 0x{:08X}", hr);
      return;
    }
    if (hr == WAIT_ABANDONED) {
      BOOST_LOG(error) << "Keyed mutex was abandoned; continuing with lock held";
    }

    const auto shared_mutex_hold_start = std::chrono::steady_clock::now();
    auto release_shared_mutex = util::fail_guard([&]() {
      const HRESULT rel_hr = _deps->resource_manager.get_keyed_mutex()->ReleaseSync(0);
      if (FAILED(rel_hr)) {
        BOOST_LOG(warning) << "Failed to release mutex key 0: " << std::format(": 0x{:08X}", rel_hr);
      }
    });

    // Copy frame data while holding the keyed mutex. The main process acquires
    // the same mutex before snapshotting this shared texture into a pool-owned frame.
    const auto copy_start = std::chrono::steady_clock::now();
    _deps->d3d_context->CopyResource(_deps->resource_manager.get_shared_texture().get(), frame_tex.get());
    const auto copy_submit = std::chrono::steady_clock::now() - copy_start;

    // Publish the metadata while still holding the shared keyed mutex so the
    // consumer can never lock a newer texture while reading an older frame id.
    _deps->resource_manager.publish_frame_metadata(frame_qpc);

    const HRESULT rel_hr = _deps->resource_manager.get_keyed_mutex()->ReleaseSync(0);
    release_shared_mutex.disable();
    if (FAILED(rel_hr)) {
      BOOST_LOG(warning) << "Failed to release mutex key 0: " << std::format(": 0x{:08X}", rel_hr);
      return;
    }
    const auto shared_mutex_hold = std::chrono::steady_clock::now() - shared_mutex_hold_start;
    context_lock.unlock();

    // Signal only after releasing the mutex so a woken consumer can acquire the
    // frame without waiting on the producer's normal release path.
    _deps->resource_manager.signal_frame_ready();
    _published_frames.fetch_add(1, std::memory_order_relaxed);

    const auto context_wait_ms = std::chrono::duration<double, std::milli>(context_wait).count();
    const auto mutex_wait_ms = std::chrono::duration<double, std::milli>(mutex_wait).count();
    const auto shared_mutex_hold_ms = std::chrono::duration<double, std::milli>(shared_mutex_hold).count();
    const auto copy_submit_ms = std::chrono::duration<double, std::milli>(copy_submit).count();
    const bool slow_context = context_wait_ms > 1.0;
    const bool slow_mutex = mutex_wait_ms > 1.0;
    const bool slow_shared_hold = shared_mutex_hold_ms > 1.0;
    const bool slow_copy = copy_submit_ms > 1.0;
    if (slow_context || slow_mutex || slow_shared_hold || slow_copy) {
      const auto slow_context_count = slow_context ? (_slow_context_waits.fetch_add(1, std::memory_order_relaxed) + 1) : _slow_context_waits.load(std::memory_order_relaxed);
      const auto slow_mutex_count = slow_mutex ? (_slow_mutex_waits.fetch_add(1, std::memory_order_relaxed) + 1) : _slow_mutex_waits.load(std::memory_order_relaxed);
      const auto slow_hold_count = slow_shared_hold ? (_slow_shared_mutex_holds.fetch_add(1, std::memory_order_relaxed) + 1) : _slow_shared_mutex_holds.load(std::memory_order_relaxed);
      const auto slow_copy_count = slow_copy ? (_slow_copy_submissions.fetch_add(1, std::memory_order_relaxed) + 1) : _slow_copy_submissions.load(std::memory_order_relaxed);
      const bool should_log_slow_context = slow_context && (slow_context_count <= 5 || slow_context_count % 120 == 0);
      const bool should_log_slow_mutex = slow_mutex && (slow_mutex_count <= 5 || slow_mutex_count % 120 == 0);
      const bool should_log_slow_hold = slow_shared_hold && (slow_hold_count <= 5 || slow_hold_count % 120 == 0);
      const bool should_log_slow_copy = slow_copy && (slow_copy_count <= 5 || slow_copy_count % 120 == 0);
      if (should_log_slow_context || should_log_slow_mutex || should_log_slow_hold || should_log_slow_copy) {
        BOOST_LOG(debug) << "WGC helper copy timing: context_wait_ms=" << context_wait_ms
                         << " mutex_wait_ms=" << mutex_wait_ms
                         << " shared_mutex_hold_ms=" << shared_mutex_hold_ms
                         << " copy_submit_ms=" << copy_submit_ms
                         << " slow_context_count=" << slow_context_count
                         << " slow_mutex_count=" << slow_mutex_count
                         << " slow_shared_hold_count=" << slow_hold_count
                         << " slow_copy_count=" << slow_copy_count;
      }
    }

    // Log first frame and frame 100 for quick sanity checks, but avoid long-running spam.
    static std::atomic<uint64_t> frame_count {0};
    const auto count = ++frame_count;
    if (count == 1 || count == 100) {
      BOOST_LOG(info) << "Published frame " << count << " to main process";
    }
  }

public:
  /**
   * @brief Creates a capture session for the specified capture item.
   * @returns true if the session was created successfully, false otherwise.
   */
  bool create_capture_session() {
    if (!_frame_pool) {
      return false;
    }

    if (!_deps || !_deps->graphics_item) {
      BOOST_LOG(error) << "Cannot create capture session: missing capture item";
      return false;
    }

    _frame_arrived_token = _frame_pool.FrameArrived([this](Direct3D11CaptureFramePool const &sender, winrt::Windows::Foundation::IInspectable const &) {
      if (_shutting_down.load(std::memory_order_acquire)) {
        return;
      }

      struct outstanding_guard_t {
        std::atomic<int> &counter;
        const int value;

        explicit outstanding_guard_t(std::atomic<int> &c):
            counter(c),
            value(c.fetch_add(1, std::memory_order_acq_rel) + 1) {}

        ~outstanding_guard_t() {
          counter.fetch_sub(1, std::memory_order_acq_rel);
        }
      } guard {_outstanding_frames};

      int prev_peak = _peak_outstanding.load(std::memory_order_relaxed);
      while (guard.value > prev_peak &&
             !_peak_outstanding.compare_exchange_weak(prev_peak, guard.value, std::memory_order_release, std::memory_order_relaxed)) {
      }

      process_frame(sender);
    });

    try {
      _capture_session = _frame_pool.CreateCaptureSession(_deps->graphics_item);
    } catch (const winrt::hresult_error &ex) {
      BOOST_LOG(error) << "CreateCaptureSession threw: " << ex.code() << " - " << winrt::to_string(ex.message());
      return false;
    } catch (...) {
      BOOST_LOG(error) << "CreateCaptureSession threw an unknown exception";
      return false;
    }

    if (!_capture_session) {
      BOOST_LOG(error) << "Failed to create GraphicsCaptureSession (returned null)";
      return false;
    }

    auto session3 = _capture_session.try_as<winrt::Windows::Graphics::Capture::IGraphicsCaptureSession3>();
    if (!session3) {
      BOOST_LOG(warning) << "IGraphicsCaptureSession3 not available; skipping IsBorderRequired(false)";
    } else {
      try {
        session3.IsBorderRequired(false);
      } catch (const winrt::hresult_error &ex) {
        BOOST_LOG(warning) << "IsBorderRequired(false) failed (continuing without it): " << ex.code() << " - " << winrt::to_string(ex.message());
      } catch (...) {
        BOOST_LOG(warning) << "IsBorderRequired(false) threw an unknown exception (continuing without it)";
      }
    }

    if (winrt::Windows::Foundation::Metadata::ApiInformation::IsPropertyPresent(L"Windows.Graphics.Capture.GraphicsCaptureSession", L"MinUpdateInterval")) {
      if (g_config.min_update_interval_100ns > 0) {
        _capture_session.MinUpdateInterval(winrt::Windows::Foundation::TimeSpan {g_config.min_update_interval_100ns});
        BOOST_LOG(info) << "WGC MinUpdateInterval set to " << g_config.min_update_interval_100ns << " ticks";
      } else {
        BOOST_LOG(info) << "WGC MinUpdateInterval left at system default";
      }
    }

    return true;
  }

  /**
   * @brief Starts the capture session if available.
   */
  void start_capture() const {
    if (_capture_session) {
      _capture_session.StartCapture();
      BOOST_LOG(info) << "Helper process started. Capturing frames using WGC...";
    }
  }

private:
  void check_and_adjust_frame_buffer() {
    auto now = std::chrono::steady_clock::now();

    // Check every 1 second for buffer adjustments
    if (auto time_since_last_check = std::chrono::duration_cast<std::chrono::milliseconds>(now - _last_buffer_check);
        time_since_last_check.count() < 1000) {
      return;
    }

    _last_buffer_check = now;

    // 1) Prune old drop timestamps (older than 5 seconds)
    prune_old_drop_timestamps(now);

    // 2) Try to increase buffer count if we have recent drops
    if (try_increase_buffer_size(now)) {
      maybe_log_capture_diagnostics(now);
      return;
    }

    // 3) Try to decrease buffer count if we've been quiet
    try_decrease_buffer_size(now);
    maybe_log_capture_diagnostics(now);
  }
};

/**
 * @brief Callback procedure for desktop switch events.
 *
 * This function handles EVENT_SYSTEM_DESKTOPSWITCH events to detect when the system
 * transitions to or from secure desktop mode (such as UAC prompts or lock screens).
 * If secure desktop is not active yet, it starts a short confirmation window so we can
 * still catch the secure-desktop transition after the event settles.
 *
 * @param h_win_event_hook Handle to the event hook (unused).
 * @param event The event type that occurred.
 * @param hwnd Handle to the window (unused).
 * @param id_object Object identifier (unused).
 * @param id_child Child object identifier (unused).
 * @param dw_event_thread Thread that generated the event (unused).
 * @param dwms_event_time Time the event occurred (unused).
 */
void CALLBACK desktop_switch_hook_proc(HWINEVENTHOOK /*h_win_event_hook*/, DWORD event, HWND /*hwnd*/, LONG /*id_object*/, LONG /*id_child*/, DWORD /*dw_event_thread*/, DWORD /*dwms_event_time*/) {
  if (event == EVENT_SYSTEM_DESKTOPSWITCH) {
    BOOST_LOG(info) << "Desktop switch detected!";

    const bool secure_desktop_active = platf::dxgi::is_secure_desktop_active();
    BOOST_LOG(info) << "Desktop switch - Secure desktop: " << (secure_desktop_active ? "YES" : "NO");

    if (secure_desktop_active) {
      notify_main_process_about_secure_desktop();
    } else if (!secure_desktop_active && g_secure_desktop_detected) {
      BOOST_LOG(info) << "Returned to normal desktop";
      g_secure_desktop_detected = false;
      g_pending_secure_desktop_check_deadline.reset();
    } else {
      g_pending_secure_desktop_check_deadline = std::chrono::steady_clock::now() + SECURE_DESKTOP_CONFIRMATION_WINDOW;
      BOOST_LOG(debug) << "Desktop switch was not immediately secure; waiting briefly for confirmation";
    }
  }
}

std::filesystem::path get_roaming_log_directory() {
  PWSTR roaming_path = nullptr;
  HRESULT hr = SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_CREATE, nullptr, &roaming_path);
  if (FAILED(hr) || roaming_path == nullptr) {
    if (roaming_path) {
      CoTaskMemFree(roaming_path);
    }
    return {};
  }

  std::filesystem::path result(roaming_path);
  CoTaskMemFree(roaming_path);
  result /= L"Sunshine";

  std::error_code ec;
  std::filesystem::create_directories(result, ec);
  if (ec) {
    return {};
  }

  return result;
}

/**
 * @brief Helper function to get the WGC helper log path.
 *
 * Logs live under Roaming/Sunshine so they sit with the other Sunshine logs.
 * When session-mode logging is enabled, the returned file path is used to derive
 * the base name and output directory (typically Roaming/Sunshine/logs).
 * Falls back to the system temporary directory (or current directory) if the roaming
 * folder cannot be resolved.
 *
 * @return Path to the log file as a UTF-8 string.
 */
std::string get_temp_log_path() {
  if (auto roaming_dir = get_roaming_log_directory(); !roaming_dir.empty()) {
    auto log_file = roaming_dir / L"sunshine_wgc_helper.log";
    return wide_to_utf8(log_file.wstring());
  }

  std::wstring temp_path(MAX_PATH, L'\0');
  if (auto len = GetTempPathW(MAX_PATH, temp_path.data()); len == 0 || len > MAX_PATH) {
    return "sunshine_wgc_helper.log";
  }
  temp_path.resize(wcslen(temp_path.data()));
  std::wstring wlog = temp_path + L"sunshine_wgc_helper.log";
  return wide_to_utf8(wlog);
}

/**
 * @brief Helper function to handle IPC messages from the main process.
 *
 * Processes incoming messages from the main Sunshine process via named pipe:
 *
 * - Configuration messages: Receives and stores config_data_t structure with display settings
 *
 * @param message The received message bytes from the named pipe.
 *
 */
void handle_ipc_message(std::span<const uint8_t> message) {
  if (message.size() == sizeof(platf::dxgi::activity_admission_data_t)) {
    platf::dxgi::activity_admission_data_t update {};
    memcpy(&update, message.data(), sizeof(update));
    if (update.magic != platf::dxgi::WGC_ACTIVITY_ADMISSION_MESSAGE_MAGIC || update.admission_fps <= 0) {
      BOOST_LOG(warning) << "Ignoring invalid WGC activity admission update";
      return;
    }

    g_activity_admission_fps.store(update.admission_fps, std::memory_order_release);
    g_activity_admission_generation.fetch_add(1, std::memory_order_acq_rel);
    BOOST_LOG(info) << "WGC activity admission updated to " << update.admission_fps << "fps";
    return;
  }

  // Handle config data message
  if (message.size() == sizeof(platf::dxgi::config_data_t)) {
    std::lock_guard lock(g_config_mutex);
    if (g_config_received) {
      return;
    }

    memcpy(&g_config, message.data(), sizeof(platf::dxgi::config_data_t));
    g_config_received = true;
    g_activity_admission_fps.store(g_config.activity_admission_fps, std::memory_order_release);
    g_activity_admission_generation.fetch_add(1, std::memory_order_acq_rel);
    // If log_level in config differs from current, update log filter
    if (INITIAL_LOG_LEVEL != g_config.log_level) {
      // Update log filter to new log level
      boost::log::core::get()->set_filter(
        severity >= g_config.log_level
      );
      BOOST_LOG(info) << "Log level updated from config: " << g_config.log_level;
    }
    BOOST_LOG(info) << "Received config data: hdr: " << g_config.dynamic_range
                    << ", display: '" << winrt::to_string(g_config.display_name) << "'"
                    << ", adapter LUID: " << std::hex << g_config.adapter_luid.HighPart
                    << ":" << g_config.adapter_luid.LowPart << std::dec
                    << ", target_fps: " << g_config.target_fps
                    << ", activity_admission_fps: " << g_config.activity_admission_fps
                    << ", min_update_interval_100ns: " << g_config.min_update_interval_100ns
                    << ", initial_buffers: " << g_config.initial_frame_buffer_size
                    << ", max_buffers: " << g_config.max_frame_buffer_size
                    << ", force_sdr_capture: " << ((g_config.flags & platf::dxgi::WGC_IPC_FLAG_FORCE_SDR_CAPTURE_FORMAT) ? "yes" : "no")
                    << ", drain_to_latest: " << ((g_config.flags & platf::dxgi::WGC_IPC_FLAG_DRAIN_TO_LATEST) ? "yes" : "no")
                    << ", allow_buffer_decrease: " << ((g_config.flags & platf::dxgi::WGC_IPC_FLAG_ALLOW_BUFFER_DECREASE) ? "yes" : "no");
    g_config_cv.notify_all();
  }
}

/**
 * @brief Helper function to setup the communication pipe with the main process.
 *
 * Configures the AsyncNamedPipe with callback functions for message handling:
 * - on_message: Delegates to handle_ipc_message() for processing received data
 * - on_error: Handles pipe communication errors (currently empty handler)
 *
 * @param pipe Reference to the AsyncNamedPipe to configure.
 *
 * @return true if the pipe was successfully configured and started, false otherwise.
 */
bool setup_pipe_callbacks(AsyncNamedPipe &pipe) {
  auto on_message = [](std::span<const uint8_t> message) {
    handle_ipc_message(message);
  };

  auto on_error = [](std::string_view /*err*/) {
    // Error handler, intentionally left empty or log as needed
  };

  return pipe.start(on_message, on_error);
}

/**
 * @brief Helper function to process window messages for desktop hooks.
 *
 * @param shutdown_requested Reference to shutdown flag that may be set if WM_QUIT is received.
 * @return true if messages were processed, false if shutdown was requested.
 */
bool process_window_messages(bool &shutdown_requested) {
  MSG msg;
  while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) {
    TranslateMessage(&msg);
    DispatchMessageW(&msg);
    if (msg.message == WM_QUIT) {
      shutdown_requested = true;
      return false;
    }
  }
  return true;
}

/**
 * @brief Helper function to setup desktop switch hook for secure desktop detection.
 *
 * @return true if the hook was successfully installed, false otherwise.
 */
bool setup_desktop_switch_hook() {
  BOOST_LOG(info) << "Setting up desktop switch hook...";

  HWINEVENTHOOK raw_hook = SetWinEventHook(
    EVENT_SYSTEM_DESKTOPSWITCH,
    EVENT_SYSTEM_DESKTOPSWITCH,
    nullptr,
    desktop_switch_hook_proc,
    0,
    0,
    WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS
  );

  if (!raw_hook) {
    BOOST_LOG(error) << "Failed to set up desktop switch hook: " << GetLastError();
    return false;
  }

  g_desktop_switch_hook.reset(raw_hook);
  BOOST_LOG(info) << "Desktop switch hook installed successfully";
  return true;
}

/**
 * @brief Main application entry point for the Windows Graphics Capture helper process.
 *
 * This standalone executable serves as a helper process for Sunshine's Windows Graphics
 * Capture functionality. The main function performs these key operations:
 *
 * 1. **System Initialization**: Sets up logging, DPI awareness, thread priority, and MMCSS
 * 2. **IPC Setup**: Establishes named pipe communication with the main Sunshine process
 * 3. **D3D11 Device Creation**: Creates hardware-accelerated D3D11 device and WinRT interop
 * 4. **Monitor Selection**: Identifies and configures the target monitor for capture
 * 5. **Shared Resource Creation**: Sets up shared D3D11 texture for inter-process frame sharing
 * 6. **WGC Setup**: Initializes Windows Graphics Capture frame pool and capture session
 * 7. **Desktop Monitoring**: Sets up hooks to detect secure desktop transitions
 * 8. **Main Loop**: Processes window messages and handles capture events until shutdown
 *
 * @param argc Number of command line arguments. Expects at least 2 arguments.
 * @param argv Array of command line argument strings. argv[1] should contain the pipe name GUID.
 * @return 0 on successful completion, 1 on initialization failure.
 */
int main(int argc, char *argv[]) {
  // Set up default config and log level
  // Use session-mode logs so rare startup deadlocks don't get overwritten by the next helper run.
  auto log_deinit = logging::init(2, get_temp_log_path());

  // Check command line arguments for pipe names
  if (argc < 2) {
    BOOST_LOG(error) << "Usage: " << argv[0] << " <pipe_name_guid>";
    return 1;
  }

  std::string pipe_name = argv[1];
  BOOST_LOG(info) << "Using pipe name: " << pipe_name;

  // Initialize system settings (DPI awareness, thread priority, MMCSS)
  SystemInitializer system_initializer;
  if (!system_initializer.initialize_all()) {
    BOOST_LOG(error) << "System initialization failed, exiting...";
    return 1;
  }

  // Debug: Verify system settings
  BOOST_LOG(info) << "DPI awareness set: " << (system_initializer.is_dpi_awareness_set() ? "YES" : "NO");
  BOOST_LOG(info) << "Thread priority set: " << (system_initializer.is_thread_priority_set() ? "YES" : "NO");
  BOOST_LOG(info) << "GPU scheduling priority set: " << (system_initializer.is_gpu_priority_set() ? "YES" : "NO");
  BOOST_LOG(info) << "MMCSS characteristics set: " << (system_initializer.is_mmcss_characteristics_set() ? "YES" : "NO");

  BOOST_LOG(info) << "Starting Windows Graphics Capture helper process...";

  // Create named pipe for communication with main process using provided pipe name
  AnonymousPipeFactory pipe_factory;

  auto comm_pipe = pipe_factory.create_client(pipe_name);
  auto pipe_shared = std::make_shared<AsyncNamedPipe>(std::move(comm_pipe));
  g_communication_pipe_weak = pipe_shared;  // Store weak reference for desktop hook callback

  if (!setup_pipe_callbacks(*pipe_shared)) {
    BOOST_LOG(error) << "Failed to start communication pipe";
    return 1;
  }

  constexpr auto max_wait = std::chrono::milliseconds(5000);
  {
    std::unique_lock lock(g_config_mutex);
    if (!g_config_cv.wait_for(lock, max_wait, []() {
          return g_config_received;
        })) {
      BOOST_LOG(error) << "Timed out waiting for config data from main process (" << max_wait.count() << "ms)";
      return 1;
    }
  }

  // Create D3D11 device and context using the same adapter as the main process
  D3D11DeviceManager d3d11_manager;
  if (!d3d11_manager.initialize_all(g_config.adapter_luid)) {
    BOOST_LOG(error) << "D3D11 device initialization failed, exiting...";
    return 1;
  }

  // Monitor management
  DisplayManager display_manager;
  if (!display_manager.select_monitor(g_config)) {
    BOOST_LOG(error) << "Monitor selection failed, exiting...";
    return 1;
  }

  if (!display_manager.get_monitor_info()) {
    BOOST_LOG(error) << "Failed to get monitor info, exiting...";
    return 1;
  }

  // Create GraphicsCaptureItem for monitor using interop.
  // Virtual display topology can churn briefly while Sunshine is applying display settings,
  // so retry monitor selection/item creation before treating startup as fatal.
  GraphicsCaptureItem item = nullptr;
  if (!display_manager.create_graphics_capture_item(item)) {
    constexpr int kMaxCreateItemAttempts = 8;
    bool created = false;
    for (int attempt = 1; attempt <= kMaxCreateItemAttempts && !created; ++attempt) {
      std::this_thread::sleep_for(std::chrono::milliseconds(250));
      if (!display_manager.select_monitor(g_config)) {
        BOOST_LOG(warning) << "GraphicsCaptureItem retry " << attempt
                           << "/" << kMaxCreateItemAttempts
                           << ": monitor selection failed";
        continue;
      }
      if (!display_manager.get_monitor_info()) {
        BOOST_LOG(warning) << "GraphicsCaptureItem retry " << attempt
                           << "/" << kMaxCreateItemAttempts
                           << ": failed to query monitor info";
        continue;
      }
      if (display_manager.create_graphics_capture_item(item)) {
        BOOST_LOG(info) << "GraphicsCaptureItem created after retry " << attempt
                        << "/" << kMaxCreateItemAttempts;
        created = true;
        break;
      }
    }
    if (!created) {
      BOOST_LOG(error) << "Failed to create GraphicsCaptureItem after retries";
      return 1;
    }
  }

  // Calculate final resolution based on config and monitor info
  display_manager.configure_capture_resolution(item);

  // WGC silently stops delivering frames once the capture item closes; display mode
  // changes, DWM restarts and monitor removals all do this (especially on Windows 10).
  // Exit so the main process notices the broken pipe and reinitializes capture instead
  // of freezing on the last delivered frame.
  item.Closed([](GraphicsCaptureItem const &, winrt::Windows::Foundation::IInspectable const &) {
    BOOST_LOG(warning) << "GraphicsCaptureItem closed; shutting down so capture can be reinitialized";
    g_capture_item_closed.store(true, std::memory_order_release);
  });

  // Use FP16 whenever the stream is HDR or the target output is already in
  // Advanced Color, except when the main process asks for SDR-compatible
  // capture so RTX HDR/TrueHDR can synthesize the HDR frame itself.
  const bool force_sdr_capture =
    g_config_received &&
    ((g_config.flags & platf::dxgi::WGC_IPC_FLAG_FORCE_SDR_CAPTURE_FORMAT) != 0);
  const auto capture_surface_format = platf::dxgi::wgc_policy::select_capture_surface_format(
    g_config_received,
    force_sdr_capture,
    g_config.dynamic_range,
    g_config.advanced_color_capture
  );
  const DXGI_FORMAT capture_format =
    capture_surface_format == platf::dxgi::wgc_policy::capture_surface_format::rgba16_float ?
      DXGI_FORMAT_R16G16B16A16_FLOAT :
      DXGI_FORMAT_B8G8R8A8_UNORM;

  // Create shared resource manager for texture, keyed mutex, and metadata
  SharedResourceManager shared_resource_manager;
  if (!shared_resource_manager.initialize_all(d3d11_manager.get_device(), display_manager.get_width(), display_manager.get_height(), capture_format)) {
    return 1;
  }

  // Send shared handle data via named pipe to main process
  platf::dxgi::shared_handle_data_t handle_data = shared_resource_manager.get_shared_handle_data();
  BOOST_LOG(info) << "Prepared shared handle message - Size: " << sizeof(handle_data) << " bytes, Handle: 0x" << std::hex << reinterpret_cast<uintptr_t>(handle_data.texture_handle) << std::dec;
  std::span<const uint8_t> handle_message(reinterpret_cast<const uint8_t *>(&handle_data), sizeof(handle_data));

  // Wait for connection and send the handle data
  BOOST_LOG(info) << "Waiting for main process to connect...";
  {
    constexpr int connect_timeout_ms = 5000;
    int connect_waited_ms = 0;
    while (!pipe_shared->is_connected() && connect_waited_ms < connect_timeout_ms) {
      std::this_thread::sleep_for(std::chrono::milliseconds(50));
      connect_waited_ms += 50;
    }

    if (!pipe_shared->is_connected()) {
      BOOST_LOG(error) << "Timed out waiting for main process to connect (" << connect_timeout_ms << "ms)";
      return 1;
    }
  }
  BOOST_LOG(info) << "Connected! Sending duplicated handle data...";
  pipe_shared->send(handle_message);
  BOOST_LOG(info) << "Duplicated handle data sent successfully to main process";

  // Create dependencies for capture manager
  WgcCaptureDependencies deps {
    d3d11_manager.get_winrt_device(),
    item,
    shared_resource_manager,
    d3d11_manager.get_context()
  };

  // Create WGC capture manager
  WgcCaptureManager wgc_capture_manager {capture_format, display_manager.get_width(), display_manager.get_height(), std::move(deps)};
  const auto initial_frame_buffer_size = std::clamp<uint32_t>(
    g_config.initial_frame_buffer_size ? g_config.initial_frame_buffer_size : 1,
    1,
    std::max<uint32_t>(1, g_config.max_frame_buffer_size ? g_config.max_frame_buffer_size : 1)
  );
  if (!wgc_capture_manager.create_or_adjust_frame_pool(initial_frame_buffer_size)) {
    BOOST_LOG(error) << "Failed to create frame pool";
    return 1;
  }

  if (!wgc_capture_manager.create_capture_session()) {
    BOOST_LOG(error) << "Failed to create capture session";
    return 1;
  }

  // Set up desktop switch hook for secure desktop detection
  setup_desktop_switch_hook();

  wgc_capture_manager.start_capture();

  // Main message loop
  bool shutdown_requested = false;
  while (pipe_shared->is_connected() && !shutdown_requested && !g_capture_item_closed.load(std::memory_order_acquire)) {
    // Process window messages and check for shutdown
    if (!process_window_messages(shutdown_requested)) {
      break;
    }

    poll_pending_secure_desktop_transition();

    std::this_thread::sleep_for(std::chrono::milliseconds(1));  // Reduced from 5ms for lower IPC jitter
  }

  if (g_capture_item_closed.load(std::memory_order_acquire)) {
    BOOST_LOG(info) << "Capture item closed, shutting down...";
  } else {
    BOOST_LOG(info) << "Main process disconnected, shutting down...";
  }

  pipe_shared->stop();

  // Flush logs before exit
  boost::log::core::get()->flush();

  BOOST_LOG(info) << "WGC Helper process terminated";

  return 0;
}