@@ -1181,6 +1181,8 @@ namespace video {
11811181 int active_av1_mode;
11821182 bool last_encoder_probe_supported_ref_frames_invalidation = false ;
11831183 std::array<bool , 3 > last_encoder_probe_supported_yuv444_for_codec = {};
1184+ constexpr auto no_display_available_msg = " Unable to start capture because no display is available" sv;
1185+ constexpr auto no_encoder_selected_msg = " No encoder selected; aborting capture instead of using invalid encoder state" sv;
11841186
11851187 void reset_display (std::shared_ptr<platf::display_t > &disp, const platf::mem_type_e &type, const std::string &display_name, const config_t &config) {
11861188 // We try this twice, in case we still get an error on reinitialization
@@ -1214,16 +1216,20 @@ namespace video {
12141216 }
12151217
12161218 // Refresh the display names
1217- auto old_display_names = std::move ( display_names);
1219+ auto had_display_names = ! display_names. empty ( );
12181220 display_names = platf::display_names (dev_type);
12191221
1220- // If we now have no displays, let's put the old display array back and fail
1221- if (display_names.empty () && !old_display_names. empty () ) {
1222+ // If we now have no displays, fail instead of reusing stale display names.
1223+ if (display_names.empty () && had_display_names ) {
12221224 BOOST_LOG (error) << " No displays were found after reenumeration!" sv;
1223- display_names = std::move (old_display_names) ;
1225+ current_display_index = - 1 ;
12241226 return ;
1225- } else if (display_names.empty ()) {
1227+ } else if (display_names.empty () && !output_name. empty () ) {
12261228 display_names.emplace_back (output_name);
1229+ } else if (display_names.empty ()) {
1230+ BOOST_LOG (error) << " No displays were found during enumeration!" sv;
1231+ current_display_index = -1 ;
1232+ return ;
12271233 }
12281234
12291235 // We now have a new display name list, so reset the index back to 0
@@ -1284,6 +1290,10 @@ namespace video {
12841290 std::vector<std::string> display_names;
12851291 int display_p = -1 ;
12861292 refresh_displays (encoder.platform_formats ->dev_type , display_names, display_p);
1293+ if (display_p < 0 || display_names.empty ()) {
1294+ BOOST_LOG (error) << no_display_available_msg;
1295+ return ;
1296+ }
12871297 auto disp = platf::display (encoder.platform_formats ->dev_type , display_names[display_p], capture_ctxs.front ().config );
12881298 if (!disp) {
12891299 return ;
@@ -1912,6 +1922,13 @@ namespace video {
19121922 << video_format.name << " ]: " sv
19131923 << av_make_error_string (err_str, AV_ERROR_MAX_STRING_SIZE , status);
19141924
1925+ if (encoder.name == " vulkan" sv) {
1926+ BOOST_LOG (error)
1927+ << " Vulkan encoder setup failed for [" sv << video_format.name
1928+ << " ]; this GPU or driver does not expose the required Vulkan video encode capability. "
1929+ << " Sunshine will discard this encoder and continue probing fallback encoders." sv;
1930+ }
1931+
19151932 return nullptr ;
19161933 }
19171934 }
@@ -2286,6 +2303,10 @@ namespace video {
22862303 while (encode_session_ctx_queue.running ()) {
22872304 // Refresh display names since a display removal might have caused the reinitialization
22882305 refresh_displays (encoder.platform_formats ->dev_type , display_names, display_p);
2306+ if (display_p < 0 || display_names.empty ()) {
2307+ BOOST_LOG (error) << no_display_available_msg;
2308+ return encode_e::error;
2309+ }
22892310
22902311 // Process any pending display switch with the new list of displays
22912312 if (switch_display_event->peek ()) {
@@ -2491,6 +2512,11 @@ namespace video {
24912512 display = ref->display_wp ->lock ();
24922513 }
24932514
2515+ if (!chosen_encoder) {
2516+ BOOST_LOG (error) << no_encoder_selected_msg;
2517+ return ;
2518+ }
2519+
24942520 auto &encoder = *chosen_encoder;
24952521
24962522 auto encode_device = make_encode_device (*display, encoder, config);
@@ -2533,6 +2559,11 @@ namespace video {
25332559 ) {
25342560 auto idr_events = mail->event <bool >(mail::idr);
25352561
2562+ if (!chosen_encoder) {
2563+ BOOST_LOG (error) << no_encoder_selected_msg;
2564+ return ;
2565+ }
2566+
25362567 idr_events->raise (true );
25372568 if (chosen_encoder->flags & PARALLEL_ENCODING ) {
25382569 capture_async (std::move (mail), config, channel_data);
@@ -3013,6 +3044,7 @@ namespace video {
30133044
30143045 if (encode_device && encode_device->data ) {
30153046 if (((vulkan_init_avcodec_hardware_input_buffer_fn) encode_device->data )(encode_device, &hw_device_buf)) {
3047+ BOOST_LOG (error) << " Failed to create a Vulkan device from the capture backend; aborting Vulkan encoder setup" sv;
30163048 return -1 ;
30173049 }
30183050 return hw_device_buf;
0 commit comments