Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(video): prevent encoder probing with no active displays #3592

Merged
merged 1 commit into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/display_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,22 @@
});
}

bool is_any_device_active() {
std::lock_guard lock {DD_DATA.mutex};

Check warning on line 814 in src/display_device.cpp

View check run for this annotation

Codecov / codecov/patch

src/display_device.cpp#L813-L814

Added lines #L813 - L814 were not covered by tests
if (!DD_DATA.sm_instance) {
// Platform is not supported, assume success.
return true;
}

return DD_DATA.sm_instance->execute([](auto &settings_iface) {
const auto devices {settings_iface.enumAvailableDevices()};

Check warning on line 821 in src/display_device.cpp

View check run for this annotation

Codecov / codecov/patch

src/display_device.cpp#L821

Added line #L821 was not covered by tests
// If at least one device has additional info, it is active.
return std::any_of(std::begin(devices), std::end(devices), [](const auto &device) {

Check warning on line 823 in src/display_device.cpp

View check run for this annotation

Codecov / codecov/patch

src/display_device.cpp#L823

Added line #L823 was not covered by tests
return static_cast<bool>(device.m_info);
});
});

Check warning on line 826 in src/display_device.cpp

View check run for this annotation

Codecov / codecov/patch

src/display_device.cpp#L825-L826

Added lines #L825 - L826 were not covered by tests
}

std::variant<failed_to_parse_tag_t, configuration_disabled_tag_t, SingleDisplayConfiguration> parse_configuration(const config::video_t &video_config, const rtsp_stream::launch_session_t &session) {
const auto device_prep {parse_device_prep_option(video_config)};
if (!device_prep) {
Expand Down
14 changes: 12 additions & 2 deletions src/display_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ namespace display_device {
* The user then accepts that Sunshine is not able to restore the state and "agrees" to
* do it manually.
*
* @return
* @note Whether the function succeeds or fails, the any of the scheduled "retries" from
* @return True if persistence was reset, false otherwise.
* @note Whether the function succeeds or fails, any of the scheduled "retries" from
* other methods will be stopped to not interfere with the user actions.
*
* @examples
Expand All @@ -120,6 +120,16 @@ namespace display_device {
*/
[[nodiscard]] bool reset_persistence();

/**
* @brief Check if any of the display devices is currently active.
* @return True if at least one device is active.
*
* @examples
* const auto result = is_any_device_active();
* @examples_end
*/
[[nodiscard]] bool is_any_device_active();

/**
* @brief A tag structure indicating that configuration parsing has failed.
*/
Expand Down
6 changes: 3 additions & 3 deletions src/nvhttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,14 +852,14 @@
auto launch_session = make_launch_session(host_audio, args);

if (rtsp_stream::session_count() == 0) {
// The display should be restored in case something fails as there are no other sessions.
revert_display_configuration = true;

Check warning on line 856 in src/nvhttp.cpp

View check run for this annotation

Codecov / codecov/patch

src/nvhttp.cpp#L856

Added line #L856 was not covered by tests

// We want to prepare display only if there are no active sessions at
// the moment. This should be done before probing encoders as it could
// change the active displays.
display_device::configure_display(config::video, *launch_session);

// The display should be restored in case something fails as there are no other sessions.
revert_display_configuration = true;

// Probe encoders again before streaming to ensure our chosen
// encoder matches the active GPU (which could have changed
// due to hotplugging, driver crash, primary monitor change,
Expand Down
5 changes: 5 additions & 0 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2550,6 +2550,11 @@
}

int probe_encoders() {
if (!display_device::is_any_device_active()) {
BOOST_LOG(error) << "No display devices are active at the moment! Cannot probe encoders as this could break Sunshine.";
return -1;

Check warning on line 2555 in src/video.cpp

View check run for this annotation

Codecov / codecov/patch

src/video.cpp#L2555

Added line #L2555 was not covered by tests
}

auto encoder_list = encoders;

// If we already have a good encoder, check to see if another probe is required
Expand Down
Loading