From cfc828f0f816d0fa8c135f2a9e679b47cf5e50d5 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Thu, 31 Jan 2019 02:57:18 +0100 Subject: [PATCH] source-mirror: Fix crash with audio sources and late video sources Source Mirror would incorrectly crash if an Audio only source was selected, as it expected a video frame to be present of any size. This fixes the problem by first testing if there is any video information to render and then just catching any exception that happens during rendering. --- source/source-mirror.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/source/source-mirror.cpp b/source/source-mirror.cpp index a5b0f3d..6871337 100644 --- a/source/source-mirror.cpp +++ b/source/source-mirror.cpp @@ -349,13 +349,13 @@ void source::mirror::mirror_instance::acquire_input(std::string source_name) // If everything worked fine, we now set everything up. this->m_source = std::move(new_source); - this->m_source->events.rename += std::bind(&source::mirror::mirror_instance::on_source_rename, this, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3); + this->m_source->events.rename += std::bind(&source::mirror::mirror_instance::on_source_rename, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); try { // Audio this->m_source_audio = std::make_shared(this->m_source); - this->m_source_audio->on.data += std::bind(&source::mirror::mirror_instance::audio_capture_cb, this, std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3); + this->m_source_audio->on.data += std::bind(&source::mirror::mirror_instance::audio_capture_cb, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); } catch (...) { P_LOG_ERROR(" Unexpected error during registering audio callback for '%s'.", source_name.c_str()); @@ -544,6 +544,11 @@ void source::mirror::mirror_instance::video_render(gs_effect_t* effect) return; } + // Don't bother rendering sources that aren't video. + if (obs_source_get_flags(this->m_source->get()) & OBS_SOURCE_VIDEO) { + return; + } + // Only re-render the scene if there was a video_tick, saves GPU cycles. if (!m_scene_rendered) { // Override render size if rescaling is enabled. @@ -554,8 +559,13 @@ void source::mirror::mirror_instance::video_render(gs_effect_t* effect) render_height = m_rescale_height; } - m_scene_texture = this->m_scene_texture_renderer->render(render_width, render_height); - m_scene_rendered = true; + try { + m_scene_texture = this->m_scene_texture_renderer->render(render_width, render_height); + m_scene_rendered = true; + } catch (...) { + // If we fail to render the source, just render nothing. + return; + } } // Use default effect unless we are provided a different effect. @@ -570,7 +580,8 @@ void source::mirror::mirror_instance::video_render(gs_effect_t* effect) } } -void source::mirror::mirror_instance::audio_capture_cb(std::shared_ptr source, audio_data const* const audio, bool) +void source::mirror::mirror_instance::audio_capture_cb(std::shared_ptr source, + audio_data const* const audio, bool) { std::unique_lock ulock(this->m_audio_lock); if (!this->m_audio_enabled) {