diff --git a/src/display_device/display_device.h b/src/display_device/display_device.h index 17ef25f2d22..b3ba4ed8bd5 100644 --- a/src/display_device/display_device.h +++ b/src/display_device/display_device.h @@ -128,6 +128,9 @@ namespace display_device { device_info_map_t enum_available_devices(); + std::string + find_device_by_friendlyname(const std::string &friendly_name); + /** * @brief Get display name associated with the device. * @param device_id A device to get display name for. diff --git a/src/display_device/parsed_config.cpp b/src/display_device/parsed_config.cpp index 22fae80ffc9..6dc7d45d644 100644 --- a/src/display_device/parsed_config.cpp +++ b/src/display_device/parsed_config.cpp @@ -4,7 +4,9 @@ #include // local includes +#include "display_device.h" #include "parsed_config.h" +#include "session.h" #include "src/config.h" #include "src/logging.h" #include "src/rtsp.h" @@ -527,23 +529,12 @@ namespace display_device { } boost::optional - make_parsed_config(const config::video_t &config, const rtsp_stream::launch_session_t &session) { + make_parsed_config(const config::video_t &config, const rtsp_stream::launch_session_t &session, bool is_reconfigure) { parsed_config_t parsed_config; parsed_config.device_id = config.output_name; parsed_config.device_prep = static_cast(config.display_device_prep); parsed_config.change_hdr_state = parse_hdr_option(config, session); - // Just wanna use virtual display device - if (config.preferUseVdd) { - auto devices { display_device::enum_available_devices() }; - const auto device_zako { std::find_if(std::begin(devices), std::end(devices), [&](const auto &entry) { - return entry.second.friendly_name == "VDD by MTT"; - }) }; - BOOST_LOG(info) << "Found display devices: " << device_zako->first; - parsed_config.device_id = device_zako->first; - config::video.output_name = device_zako->first; - } - if (!parse_resolution_option(config, session, parsed_config)) { // Error already logged return boost::none; @@ -559,6 +550,10 @@ namespace display_device { return boost::none; } + if (config.preferUseVdd || session.use_vdd || display_device::get_display_friendly_name(config.output_name) == "VDD by MTT") { + display_device::session_t::get().prepare_vdd(parsed_config, session); + } + BOOST_LOG(debug) << "Parsed display device config:\n" << "device_id: " << parsed_config.device_id << "\n" << "device_prep: " << static_cast(parsed_config.device_prep) << "\n" diff --git a/src/display_device/parsed_config.h b/src/display_device/parsed_config.h index b7b840c369d..d22e5b93170 100644 --- a/src/display_device/parsed_config.h +++ b/src/display_device/parsed_config.h @@ -119,6 +119,7 @@ namespace display_device { boost::optional resolution; /**< Parsed resolution value we need to switch to. Empty optional if no action is required. */ boost::optional refresh_rate; /**< Parsed refresh rate value we need to switch to. Empty optional if no action is required. */ boost::optional change_hdr_state; /**< Parsed HDR state value we need to switch to (true == ON, false == OFF). Empty optional if no action is required. */ + boost::optional use_vdd; /**< Parsed VDD state value we need to switch to (true == ON, false == OFF). */ }; /** @@ -135,6 +136,6 @@ namespace display_device { * ``` */ boost::optional - make_parsed_config(const config::video_t &config, const rtsp_stream::launch_session_t &session); + make_parsed_config(const config::video_t &config, const rtsp_stream::launch_session_t &session, bool is_reconfigure); } // namespace display_device diff --git a/src/display_device/session.cpp b/src/display_device/session.cpp index 3b5ad22370b..5814263dfe5 100644 --- a/src/display_device/session.cpp +++ b/src/display_device/session.cpp @@ -7,6 +7,7 @@ #include "session.h" #include "src/confighttp.h" #include "src/platform/common.h" +#include "src/rtsp.h" #include "to_string.h" namespace display_device { @@ -141,29 +142,20 @@ namespace display_device { session_t::get().settings.set_filepath(platf::appdata() / "original_display_settings.json"); - // Disable the display device manually if it has more than one device - if (config::video.preferUseVdd && devices.size() > 1) { - session_t::get().disable_vdd(); - } - session_t::get().restore_state(); return std::make_unique(); } void - session_t::configure_display(const config::video_t &config, const rtsp_stream::launch_session_t &session) { + session_t::configure_display(const config::video_t &config, const rtsp_stream::launch_session_t &session, bool is_reconfigure) { std::lock_guard lock { mutex }; - const auto parsed_config { make_parsed_config(config, session) }; + const auto parsed_config { make_parsed_config(config, session, is_reconfigure) }; if (!parsed_config) { BOOST_LOG(error) << "Failed to parse configuration for the the display device settings!"; return; } - if (config.preferUseVdd || display_device::get_display_friendly_name(config::video.output_name) == "VDD by MTT") { - session_t::get().prepare_vdd(*parsed_config); - } - if (settings.is_changing_settings_going_to_fail()) { timer->setup_timer([this, config_copy = *parsed_config]() { if (settings.is_changing_settings_going_to_fail()) { @@ -195,20 +187,6 @@ namespace display_device { } } - void - session_t::restore_state() { - std::lock_guard lock { mutex }; - restore_state_impl(); - } - - void - session_t::reset_persistence() { - std::lock_guard lock { mutex }; - - settings.reset_persistence(); - timer->setup_timer(nullptr); - } - void session_t::enable_vdd() { boost::process::environment _env = boost::this_process::environment(); @@ -245,68 +223,62 @@ namespace display_device { } } - // void - // session_t::prepare_vdd(const config::video_t &config, int width, int height, int refresh_rate) { - // std::stringstream new_setting; - // new_setting << width << "x" << height << "x" << refresh_rate; - // if (display_device::session_t::get().last_vdd_setting != new_setting.str()) { - // std::stringstream resolutions; - // std::stringstream fps; - // resolutions << "[1920x1080," << width << "x" << height << "]"; - // fps << "[60," << refresh_rate << "]"; - - // if (display_device::is_primary_device(config.output_name)) { - // display_device::session_t::get().disable_vdd(); - // Sleep(1500); - // } - - // confighttp::saveVddSettings(resolutions.str(), fps.str(), config.adapter_name); - // BOOST_LOG(info) << "Set Client request res to VDD: "sv << new_setting.str() << " ."sv; - // display_device::session_t::get().last_vdd_setting = new_setting.str(); - // display_device::session_t::get().enable_vdd(); - // Sleep(4567); - // } - // } - void - session_t::prepare_vdd(const parsed_config_t &config) { - auto devices { display_device::enum_available_devices() }; - bool isVddAvailable { false }; - if (!devices.empty()) { - const auto device_it { std::find_if(std::begin(devices), std::end(devices), [&](const auto &entry) { - return entry.first == config.device_id; - }) }; - if (device_it != std::end(devices)) { - isVddAvailable = true; - } - } - + session_t::prepare_vdd(parsed_config_t &config, const rtsp_stream::launch_session_t &session) { + // resolutions and fps from parsed std::stringstream new_setting; - new_setting << to_string(*config.resolution) << "x" << to_string(*config.refresh_rate); - BOOST_LOG(info) << "last_vdd_setting/new_setting: "sv << display_device::session_t::get().last_vdd_setting << "/" << new_setting.str(); - if (display_device::session_t::get().last_vdd_setting != new_setting.str()) { + new_setting << to_string(*config.resolution) << "@" << to_string(*config.refresh_rate); + bool need_reset_vdd = display_device::session_t::get().last_vdd_setting != new_setting.str(); + BOOST_LOG(info) << "last_vdd_setting/new_setting from parsed: "sv << display_device::session_t::get().last_vdd_setting << "/" << new_setting.str(); + + if (need_reset_vdd) { std::stringstream resolutions; std::stringstream fps; resolutions << "[1920x1080," << to_string(*config.resolution) << "]"; fps << "[60," << to_string(*config.refresh_rate) << "]"; confighttp::saveVddSettings(resolutions.str(), fps.str(), config::video.adapter_name); - BOOST_LOG(info) << "Set Client request res to VDD: "sv << new_setting.str() << " ."sv; + BOOST_LOG(info) << "Set Client request res to VDD: "sv << new_setting.str(); display_device::session_t::get().last_vdd_setting = new_setting.str(); + } - if (isVddAvailable) { - display_device::session_t::get().disable_vdd(); - Sleep(3000); - } - display_device::session_t::get().enable_vdd(); - Sleep(3000); + const std::string zako_name = "VDD by MTT"; + auto device_zako = display_device::find_device_by_friendlyname(zako_name); + if (device_zako.empty()) { + session_t::get().enable_vdd(); } - else if (!isVddAvailable) { - display_device::session_t::get().enable_vdd(); + else if (need_reset_vdd) { + session_t::get().disable_vdd(); Sleep(3000); + session_t::get().enable_vdd(); + } + + device_zako = display_device::find_device_by_friendlyname(zako_name); + while (device_zako.empty()) { + device_zako = display_device::find_device_by_friendlyname(zako_name); + Sleep(233); + } + + if (!device_zako.empty()) { + config.device_id = device_zako; + config::video.output_name = device_zako; } } + void + session_t::restore_state() { + std::lock_guard lock { mutex }; + restore_state_impl(); + } + + void + session_t::reset_persistence() { + std::lock_guard lock { mutex }; + + settings.reset_persistence(); + timer->setup_timer(nullptr); + } + void session_t::restore_state_impl() { if (!settings.is_changing_settings_going_to_fail() && settings.revert_settings()) { diff --git a/src/display_device/session.h b/src/display_device/session.h index 26b8976e66f..07e51d23e74 100644 --- a/src/display_device/session.h +++ b/src/display_device/session.h @@ -83,7 +83,7 @@ namespace display_device { * ``` */ void - configure_display(const config::video_t &config, const rtsp_stream::launch_session_t &session); + configure_display(const config::video_t &config, const rtsp_stream::launch_session_t &session, bool is_reconfigure); /** * @brief Revert the display configuration and restore the previous state. @@ -145,7 +145,7 @@ namespace display_device { disable_vdd(); void - prepare_vdd(const parsed_config_t &config); + prepare_vdd(parsed_config_t &config, const rtsp_stream::launch_session_t &session); /** * @brief A deleted copy constructor for singleton pattern. diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index c4fc7b4caf9..3de32f63ecd 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -356,6 +356,7 @@ namespace nvhttp { launch_session->surround_params = (get_arg(args, "surroundParams", "")); launch_session->gcmap = util::from_view(get_arg(args, "gcmap", "0")); launch_session->enable_hdr = util::from_view(get_arg(args, "hdrMode", "0")); + launch_session->use_vdd = util::from_view(get_arg(args, "useVdd", "0")); // Encrypted RTSP is enabled with client reported corever >= 1 auto corever = util::from_view(get_arg(args, "corever", "0")); @@ -387,6 +388,7 @@ namespace nvhttp { launch_session->env["SUNSHINE_CLIENT_GCMAP"] = std::to_string(launch_session->gcmap); launch_session->env["SUNSHINE_CLIENT_HOST_AUDIO"] = launch_session->host_audio ? "true" : "false"; launch_session->env["SUNSHINE_CLIENT_ENABLE_SOPS"] = launch_session->enable_sops ? "true" : "false"; + launch_session->env["SUNSHINE_CLIENT_USE_VDD"] = launch_session->use_vdd ? "true" : "false"; int channelCount = launch_session->surround_info & (65535); switch (channelCount) { case 2: @@ -947,7 +949,7 @@ namespace nvhttp { // We want to prepare display only if there are no active sessions at // the moment. This should to be done before probing encoders as it could // change display device's state. - display_device::session_t::get().configure_display(config::video, *launch_session); + display_device::session_t::get().configure_display(config::video, *launch_session, true); // The display should be restored by the fail guard in case something happens. need_to_restore_display_state = true; @@ -1054,7 +1056,7 @@ namespace nvhttp { // We want to prepare display only if there are no active sessions at // the moment. This should to be done before probing encoders as it could // change display device's state. - display_device::session_t::get().configure_display(config::video, *launch_session); + display_device::session_t::get().configure_display(config::video, *launch_session, false); // Probe encoders again before streaming to ensure our chosen // encoder matches the active GPU (which could have changed @@ -1120,15 +1122,6 @@ namespace nvhttp { // The state needs to be restored regardless of whether "proc::proc.terminate()" was called or not. display_device::session_t::get().restore_state(); - - // disbale Vistual Displays on Windows -#ifdef _WIN32 - auto devices { display_device::enum_available_devices() }; - if (config::video.preferUseVdd && devices.size() > 1) { - Sleep(2500); - display_device::session_t::get().disable_vdd(); - } -#endif } void diff --git a/src/platform/windows/display_device/device_topology.cpp b/src/platform/windows/display_device/device_topology.cpp index e01e311537f..4298a42fed7 100644 --- a/src/platform/windows/display_device/device_topology.cpp +++ b/src/platform/windows/display_device/device_topology.cpp @@ -326,6 +326,24 @@ namespace display_device { return available_devices; } + std::string + find_device_by_friendlyname(const std::string &friendly_name) { + const auto devices { enum_available_devices() }; + if (devices.empty()) { + BOOST_LOG(error) << "Display device list is empty!"; + return {}; + } + + const auto device_it { std::find_if(std::begin(devices), std::end(devices), [&friendly_name](const auto &entry) { + return entry.second.friendly_name == friendly_name; + }) }; + if (device_it == std::end(devices)) { + return {}; + } + + return device_it->first; + } + active_topology_t get_current_topology() { const auto display_data { w_utils::query_display_config(w_utils::ACTIVE_ONLY_DEVICES) }; diff --git a/src/platform/windows/display_device/settings.cpp b/src/platform/windows/display_device/settings.cpp index bd42e0914f3..3860960437a 100644 --- a/src/platform/windows/display_device/settings.cpp +++ b/src/platform/windows/display_device/settings.cpp @@ -5,6 +5,7 @@ // local includes #include "settings_topology.h" #include "src/audio.h" +#include "src/display_device/session.h" #include "src/display_device/to_string.h" #include "src/logging.h" #include "windows_utils.h" @@ -734,6 +735,16 @@ namespace display_device { BOOST_LOG(info) << "Display device configuration reverted."; } + auto devices { display_device::enum_available_devices() }; + if (config::video.preferUseVdd && devices.size() > 1) { + Sleep(2500); + display_device::session_t::get().disable_vdd(); + BOOST_LOG(info) << "VDD stat revert to disable."; + } + else if (display_device::find_device_by_friendlyname("VDD by MTT").empty()) { + display_device::session_t::get().enable_vdd(); + } + return true; } diff --git a/src/rtsp.h b/src/rtsp.h index d98bccf5a64..41c31c208f7 100644 --- a/src/rtsp.h +++ b/src/rtsp.h @@ -36,6 +36,7 @@ namespace rtsp_stream { std::string surround_params; bool enable_hdr; bool enable_sops; + bool use_vdd; std::optional rtsp_cipher; std::string rtsp_url_scheme;