Skip to content

Commit

Permalink
Add new API to modify display devices for Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
FrogTheFrog committed Jun 2, 2024
1 parent 9afb1ae commit 2a0aa07
Show file tree
Hide file tree
Showing 57 changed files with 6,171 additions and 88 deletions.
1 change: 0 additions & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,6 @@ jobs:
mingw-w64-ucrt-x86_64-cppwinrt \
mingw-w64-ucrt-x86_64-graphviz \
mingw-w64-ucrt-x86_64-miniupnpc \
mingw-w64-ucrt-x86_64-nlohmann-json \
mingw-w64-ucrt-x86_64-nodejs \
mingw-w64-ucrt-x86_64-nsis \
mingw-w64-ucrt-x86_64-onevpl \
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
path = third-party/nanors
url = https://github.com/sleepybishop/nanors.git
branch = master
[submodule "third-party/nlohmann_json"]
path = third-party/nlohmann_json
url = https://github.com/nlohmann/json
branch = master
[submodule "third-party/nv-codec-headers"]
path = third-party/nv-codec-headers
url = https://github.com/FFmpeg/nv-codec-headers
Expand Down
10 changes: 10 additions & 0 deletions cmake/compile_definitions/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ set(SUNSHINE_TARGET_FILES
"${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/src/RtspParser.c"
"${CMAKE_SOURCE_DIR}/third-party/moonlight-common-c/src/Video.h"
"${CMAKE_SOURCE_DIR}/third-party/tray/src/tray.h"
"${CMAKE_SOURCE_DIR}/src/display_device/display_device.h"
"${CMAKE_SOURCE_DIR}/src/display_device/parsed_config.cpp"
"${CMAKE_SOURCE_DIR}/src/display_device/parsed_config.h"
"${CMAKE_SOURCE_DIR}/src/display_device/session.cpp"
"${CMAKE_SOURCE_DIR}/src/display_device/session.h"
"${CMAKE_SOURCE_DIR}/src/display_device/settings.cpp"
"${CMAKE_SOURCE_DIR}/src/display_device/settings.h"
"${CMAKE_SOURCE_DIR}/src/display_device/to_string.cpp"
"${CMAKE_SOURCE_DIR}/src/display_device/to_string.h"
"${CMAKE_SOURCE_DIR}/src/upnp.cpp"
"${CMAKE_SOURCE_DIR}/src/upnp.h"
"${CMAKE_SOURCE_DIR}/src/cbs.cpp"
Expand Down Expand Up @@ -137,4 +146,5 @@ list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
${FFMPEG_LIBRARIES}
${Boost_LIBRARIES}
${OPENSSL_LIBRARIES}
${JSON_LIBRARIES}
${PLATFORM_LIBRARIES})
1 change: 1 addition & 0 deletions cmake/compile_definitions/linux.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ list(APPEND PLATFORM_TARGET_FILES
"${CMAKE_SOURCE_DIR}/src/platform/linux/misc.h"
"${CMAKE_SOURCE_DIR}/src/platform/linux/misc.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/linux/audio.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/linux/display_device.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/linux/input.cpp"
"${CMAKE_SOURCE_DIR}/third-party/glad/src/egl.c"
"${CMAKE_SOURCE_DIR}/third-party/glad/src/gl.c"
Expand Down
1 change: 1 addition & 0 deletions cmake/compile_definitions/macos.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ set(PLATFORM_TARGET_FILES
"${CMAKE_SOURCE_DIR}/src/platform/macos/av_video.h"
"${CMAKE_SOURCE_DIR}/src/platform/macos/av_video.m"
"${CMAKE_SOURCE_DIR}/src/platform/macos/display.mm"
"${CMAKE_SOURCE_DIR}/src/platform/macos/display_device.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/macos/input.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/macos/microphone.mm"
"${CMAKE_SOURCE_DIR}/src/platform/macos/misc.mm"
Expand Down
10 changes: 9 additions & 1 deletion cmake/compile_definitions/windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ set(PLATFORM_TARGET_FILES
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_ram.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_wgc.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/audio.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/device_hdr_states.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/device_modes.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/device_topology.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/general_functions.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/settings_topology.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/settings_topology.h"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/settings.cpp"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/windows_utils.h"
"${CMAKE_SOURCE_DIR}/src/platform/windows/display_device/windows_utils.cpp"
"${CMAKE_SOURCE_DIR}/third-party/ViGEmClient/src/ViGEmClient.cpp"
"${CMAKE_SOURCE_DIR}/third-party/ViGEmClient/include/ViGEm/Client.h"
"${CMAKE_SOURCE_DIR}/third-party/ViGEmClient/include/ViGEm/Common.h"
Expand All @@ -78,7 +87,6 @@ list(PREPEND PLATFORM_LIBRARIES
avrt
iphlpapi
shlwapi
PkgConfig::NLOHMANN_JSON
${CURL_STATIC_LIBRARIES})

if(SUNSHINE_ENABLE_TRAY)
Expand Down
9 changes: 9 additions & 0 deletions cmake/dependencies/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ pkg_check_modules(CURL REQUIRED libcurl)
pkg_check_modules(MINIUPNP miniupnpc REQUIRED)
include_directories(SYSTEM ${MINIUPNP_INCLUDE_DIRS})

# nlohmann_json
if(SUNSHINE_SYSTEM_NLOHMANN_JSON)
pkg_check_modules(NLOHMANN_JSON nlohmann_json>=3.9.0 REQUIRED IMPORTED_TARGET)
set(JSON_LIBRARIES PkgConfig::NLOHMANN_JSON)
else()
add_subdirectory("${CMAKE_SOURCE_DIR}/third-party/nlohmann_json")
set(JSON_LIBRARIES nlohmann_json::nlohmann_json)
endif()

# ffmpeg pre-compiled binaries
if(NOT DEFINED FFMPEG_PREPARED_BINARIES)
if(WIN32)
Expand Down
3 changes: 0 additions & 3 deletions cmake/dependencies/windows.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@

set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103
find_package(Boost 1.71.0 COMPONENTS locale log filesystem program_options REQUIRED)

# nlohmann_json
pkg_check_modules(NLOHMANN_JSON nlohmann_json REQUIRED IMPORTED_TARGET)
1 change: 1 addition & 0 deletions cmake/prep/options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ option(SUNSHINE_CONFIGURE_ONLY "Configure special files only, then exit." OFF)
option(SUNSHINE_ENABLE_TRAY "Enable system tray icon. This option will be ignored on macOS." ON)
option(SUNSHINE_REQUIRE_TRAY "Require system tray icon. Fail the build if tray requirements are not met." ON)

option(SUNSHINE_SYSTEM_NLOHMANN_JSON "Use system installation of nlohmann_json rather than the submodule." OFF)
option(SUNSHINE_SYSTEM_WAYLAND_PROTOCOLS "Use system installation of wayland-protocols rather than the submodule." OFF)

option(CUDA_INHERIT_COMPILE_OPTIONS
Expand Down
34 changes: 30 additions & 4 deletions docs/source/about/advanced_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ keybindings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

**Description**
Select the display number you want to stream.
Select the display you want to stream.

.. tip:: To find the name of the appropriate values follow these instructions.

Expand Down Expand Up @@ -615,9 +615,35 @@ keybindings
You need to use the id value inside the parenthesis, e.g. ``3``.

**Windows**
.. code-block:: batch
During Sunshine startup, you should see the list of detected display devices:

tools\dxgi-info.exe
.. code-block:: text
DEVICE ID: {de9bb7e2-186e-505b-9e93-f48793333810}
DISPLAY NAME: \\.\DISPLAY1
FRIENDLY NAME: ROG PG279Q
DEVICE STATE: PRIMARY
HDR STATE: UNKNOWN
-----------------------
DEVICE ID: {3bd008cd-0465-547c-8da5-c28749c041e6}
DISPLAY NAME: NOT AVAILABLE
FRIENDLY NAME: IDD HDR
DEVICE STATE: INACTIVE
HDR STATE: UNKNOWN
-----------------------
DEVICE ID: {77f67f3e-754f-5d31-af64-ee037e18100a}
DISPLAY NAME: NOT AVAILABLE
FRIENDLY NAME: SunshineHDR
DEVICE STATE: INACTIVE
HDR STATE: UNKNOWN
-----------------------
DEVICE ID: {bc172e6d-86eb-5851-aeca-56525ed716e9}
DISPLAY NAME: NOT AVAILABLE
FRIENDLY NAME: ROG PG279Q
DEVICE STATE: INACTIVE
HDR STATE: UNKNOWN
You need to use the ``DEVICE ID`` value.

**Default**
Sunshine will select the default display.
Expand All @@ -636,7 +662,7 @@ keybindings
**Windows**
.. code-block:: text
output_name = \\.\DISPLAY1
output_name = {de9bb7e2-186e-505b-9e93-f48793333810}
`resolutions <https://localhost:47990/config/#resolutions>`__
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
1 change: 0 additions & 1 deletion docs/source/building/windows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Install dependencies:
mingw-w64-ucrt-x86_64-curl \
mingw-w64-ucrt-x86_64-graphviz \
mingw-w64-ucrt-x86_64-miniupnpc \
mingw-w64-ucrt-x86_64-nlohmann-json \
mingw-w64-ucrt-x86_64-nodejs \
mingw-w64-ucrt-x86_64-nsis \
mingw-w64-ucrt-x86_64-onevpl \
Expand Down
14 changes: 14 additions & 0 deletions docs/source/source_code/source_code.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ Source

src/*

.. toctree::
:caption: src/display_device
:maxdepth: 1
:glob:

src/display_device/*

.. toctree::
:caption: src/platform
:maxdepth: 1
Expand Down Expand Up @@ -89,3 +96,10 @@ Source
:glob:

src/platform/windows/*

.. toctree::
:caption: src/platform/windows/display_device
:maxdepth: 1
:glob:

src/platform/windows/display_device/*
4 changes: 4 additions & 0 deletions docs/source/source_code/src/display_device/display_device.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
display_device
==============

.. todo:: Add display_device.h
4 changes: 4 additions & 0 deletions docs/source/source_code/src/display_device/parsed_config.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
parsed_config
=============

.. todo:: Add parsed_config.h
4 changes: 4 additions & 0 deletions docs/source/source_code/src/display_device/session.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
session
=======

.. todo:: Add session.h
4 changes: 4 additions & 0 deletions docs/source/source_code/src/display_device/settings.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
settings
========

.. todo:: Add settings.h
4 changes: 4 additions & 0 deletions docs/source/source_code/src/display_device/to_string.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
to_string
=========

.. todo:: Add to_string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
settings_data
=============

.. todo:: Add settings_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
settings_topology
=================

.. todo:: Add settings_topology.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
windows_utils
=============

.. todo:: Add windows_utils.h
20 changes: 7 additions & 13 deletions src/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,6 @@ namespace audio {
using opus_t = util::safe_ptr<OpusMSEncoder, opus_multistream_encoder_destroy>;
using sample_queue_t = std::shared_ptr<safe::queue_t<std::vector<std::int16_t>>>;

struct audio_ctx_t {
// We want to change the sink for the first stream only
std::unique_ptr<std::atomic_bool> sink_flag;

std::unique_ptr<platf::audio_control_t> control;

bool restore_sink;
platf::sink_t sink;
};

static int
start_audio_control(audio_ctx_t &ctx);
static void
Expand Down Expand Up @@ -95,8 +85,6 @@ namespace audio {
},
};

auto control_shared = safe::make_shared<audio_ctx_t>(start_audio_control, stop_audio_control);

void
encodeThread(sample_queue_t samples, config_t config, void *channel_data) {
auto packets = mail::man->queue<packet_t>(mail::audio_packets);
Expand Down Expand Up @@ -149,7 +137,7 @@ namespace audio {
apply_surround_params(stream, config.customStreamParams);
}

auto ref = control_shared.ref();
auto ref = get_audio_ctx_ref();
if (!ref) {
return;
}
Expand Down Expand Up @@ -255,6 +243,12 @@ namespace audio {
}
}

audio_ctx_ref_t
get_audio_ctx_ref() {
static auto control_shared { safe::make_shared<audio_ctx_t>(start_audio_control, stop_audio_control) };
return control_shared.ref();
}

int
map_stream(int channels, bool quality) {
int shift = quality ? 1 : 0;
Expand Down
29 changes: 29 additions & 0 deletions src/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
*/
#pragma once

// local includes
#include "platform/common.h"
#include "thread_safe.h"
#include "utility.h"

namespace audio {
enum stream_config_e : int {
STEREO,
Expand Down Expand Up @@ -52,8 +55,34 @@ namespace audio {
std::bitset<MAX_FLAGS> flags;
};

struct audio_ctx_t {
// We want to change the sink for the first stream only
std::unique_ptr<std::atomic_bool> sink_flag;

std::unique_ptr<platf::audio_control_t> control;

bool restore_sink;
platf::sink_t sink;
};

using buffer_t = util::buffer_t<std::uint8_t>;
using packet_t = std::pair<void *, buffer_t>;
using audio_ctx_ref_t = safe::shared_t<audio::audio_ctx_t>::ptr_t;

void
capture(safe::mail_t mail, config_t config, void *channel_data);

/**
* @brief Get the reference to the audio context.
* @returns A shared pointer reference to audio context.
* @note Aside from the configuration purposes, it can be used to extend the
* audio sink lifetime to capture sink earlier and restore it later.
*
* EXAMPLES:
* ```cpp
* audio_ctx_ref_t audio = get_audio_ctx_ref()
* ```
*/
audio_ctx_ref_t
get_audio_ctx_ref();
} // namespace audio
Loading

0 comments on commit 2a0aa07

Please sign in to comment.