Skip to content

Commit

Permalink
refactor: combing display(vdd) topology
Browse files Browse the repository at this point in the history
  • Loading branch information
qiin2333 committed Sep 11, 2024
1 parent 4375d8a commit df24587
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 98 deletions.
3 changes: 3 additions & 0 deletions src/display_device/display_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
19 changes: 7 additions & 12 deletions src/display_device/parsed_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <cmath>

// 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"
Expand Down Expand Up @@ -527,23 +529,12 @@ namespace display_device {
}

boost::optional<parsed_config_t>
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<parsed_config_t::device_prep_e>(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;
Expand All @@ -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<int>(parsed_config.device_prep) << "\n"
Expand Down
3 changes: 2 additions & 1 deletion src/display_device/parsed_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ namespace display_device {
boost::optional<resolution_t> resolution; /**< Parsed resolution value we need to switch to. Empty optional if no action is required. */
boost::optional<refresh_rate_t> refresh_rate; /**< Parsed refresh rate value we need to switch to. Empty optional if no action is required. */
boost::optional<bool> 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<bool> use_vdd; /**< Parsed VDD state value we need to switch to (true == ON, false == OFF). */
};

/**
Expand All @@ -135,6 +136,6 @@ namespace display_device {
* ```
*/
boost::optional<parsed_config_t>
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
116 changes: 44 additions & 72 deletions src/display_device/session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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<deinit_t>();
}

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()) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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()) {
Expand Down
4 changes: 2 additions & 2 deletions src/display_device/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
15 changes: 4 additions & 11 deletions src/nvhttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions src/platform/windows/display_device/device_topology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) };
Expand Down
11 changes: 11 additions & 0 deletions src/platform/windows/display_device/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
}

Expand Down
1 change: 1 addition & 0 deletions src/rtsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace rtsp_stream {
std::string surround_params;
bool enable_hdr;
bool enable_sops;
bool use_vdd;

std::optional<crypto::cipher::gcm_t> rtsp_cipher;
std::string rtsp_url_scheme;
Expand Down

0 comments on commit df24587

Please sign in to comment.