Skip to content

Commit

Permalink
fix(video): allow encoder probing when there are no devices at all (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
FrogTheFrog authored Jan 27, 2025
1 parent 24cce3a commit 23e1314
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
12 changes: 4 additions & 8 deletions src/display_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,19 +810,15 @@ namespace display_device {
});
}

bool is_any_device_active() {
EnumeratedDeviceList enumerate_devices() {
std::lock_guard lock {DD_DATA.mutex};
if (!DD_DATA.sm_instance) {
// Platform is not supported, assume success.
return true;
// Platform is not supported.
return {};
}

return DD_DATA.sm_instance->execute([](auto &settings_iface) {
const auto devices {settings_iface.enumAvailableDevices()};
// If at least one device has additional info, it is active.
return std::any_of(std::begin(devices), std::end(devices), [](const auto &device) {
return static_cast<bool>(device.m_info);
});
return settings_iface.enumAvailableDevices();
});
}

Expand Down
8 changes: 4 additions & 4 deletions src/display_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,14 @@ 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.
* @brief Enumerate the available devices.
* @return A list of devices.
*
* @examples
* const auto result = is_any_device_active();
* const auto devices = enumerate_devices();
* @examples_end
*/
[[nodiscard]] bool is_any_device_active();
[[nodiscard]] EnumeratedDeviceList enumerate_devices();

/**
* @brief A tag structure indicating that configuration parsing has failed.
Expand Down
35 changes: 33 additions & 2 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,37 @@ using namespace std::literals;

namespace video {

namespace {
/**
* @brief Check if we can allow probing for the encoders.
* @return True if there should be no issues with the probing, false if we should prevent it.
*/
bool allow_encoder_probing() {
const auto devices {display_device::enumerate_devices()};

// If there are no devices, then either the API is not working correctly or OS does not support the lib.
// Either way we should not block the probing in this case as we can't tell what's wrong.
if (devices.empty()) {
return true;
}

// Since Windows 11 24H2, it is possible that there will be no active devices present
// for some reason (probably a bug). Trying to probe encoders in such a state locks/breaks the DXGI
// and also the display device for Windows. So we must have at least 1 active device.
const bool at_least_one_device_is_active = std::any_of(std::begin(devices), std::end(devices), [](const auto &device) {
// If device has additional info, it is active.
return static_cast<bool>(device.m_info);
});

if (at_least_one_device_is_active) {
return true;
}

BOOST_LOG(error) << "No display devices are active at the moment! Cannot probe the encoders.";
return false;
}
} // namespace

void free_ctx(AVCodecContext *ctx) {
avcodec_free_context(&ctx);
}
Expand Down Expand Up @@ -2550,8 +2581,8 @@ namespace video {
}

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.";
if (!allow_encoder_probing()) {
// Error already logged
return -1;
}

Expand Down

0 comments on commit 23e1314

Please sign in to comment.