diff --git a/tools/chatgui/src/stream_publish_engine.cpp b/tools/chatgui/src/stream_publish_engine.cpp index f86dc29e..d517c02f 100644 --- a/tools/chatgui/src/stream_publish_engine.cpp +++ b/tools/chatgui/src/stream_publish_engine.cpp @@ -166,7 +166,8 @@ QList StreamPublishEngine::sources() { int number = 0; for (auto* screen : QGuiApplication::screens()) { QSize size = screen->size() * screen->devicePixelRatio(); - sources.push_back({StreamVideoSource::Screen, QStringLiteral("%1: %2").arg(++number).arg(screen->name()), screenId(screen), {}, size}); + sources.push_back({StreamVideoSource::Screen, QStringLiteral("%1: %2").arg(++number).arg(screen->name()), + screenId(screen), {}, size, {}, screen}); DEBUG_DEBUG(DEBUG_CATEGORY_VIDEO, "desktop screen capability source=%s logical=%dx%d scale=%.3f pixels=%dx%d", qPrintable(screen->name()), screen->size().width(), screen->size().height(), screen->devicePixelRatio(), size.width(), size.height()); } @@ -241,7 +242,8 @@ bool StreamPublishEngine::openSource(const StreamPublishConfig& config) { m->screen = std::make_unique(); if (config.source.id != "portal") { QScreen* selected = nullptr; - for (auto* screen : QGuiApplication::screens()) if (screenId(screen) == config.source.id) { selected = screen; break; } + for (auto* screen : QGuiApplication::screens()) + if (screen == config.source.screen && screenId(screen) == config.source.id) { selected = screen; break; } if (!selected) { DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop screen disappeared"); return false; } m->screen->setScreen(selected); } @@ -321,8 +323,7 @@ bool StreamPublishEngine::reconfigure(const StreamPublishConfig& config) { DEBUG_WARN(DEBUG_CATEGORY_STREAM, "desktop microphone selection changed during live publication"); emit errorOccurred(text("Change the microphone before starting the stream")); return false; } - bool sourceChange = config.source.kind != previous.source.kind || config.source.id != previous.source.id - || config.source.window != previous.source.window || (config.source.kind == StreamVideoSource::Camera + bool sourceChange = !config.source.sameSource(previous.source) || (config.source.kind == StreamVideoSource::Camera && (config.video.width != previous.video.width || config.video.height != previous.video.height || config.video.fps != previous.video.fps)); { std::lock_guard guard(m->lock); m->wanted = config; m->generation++; m->started = monotonicUs(); #ifdef HAVE_STREAM_CAPTURE @@ -494,8 +495,7 @@ void StreamPublishEngine::videoLoop(StreamPublishConfig initial) { } if (generation != current) { auto comparable = config.video; comparable.bitrate = encoding.video.bitrate; - bool onlyBitrate = encoder && comparable == encoding.video && config.source.kind == encoding.source.kind - && config.source.id == encoding.source.id && config.source.window == encoding.source.window; + bool onlyBitrate = encoder && comparable == encoding.video && config.source.sameSource(encoding.source); if (onlyBitrate && encoder->setBitrate(config.video.bitrate)) { current = generation; encoding = config; { std::lock_guard guard(m->lock); diff --git a/tools/chatgui/src/stream_publish_engine.h b/tools/chatgui/src/stream_publish_engine.h index 7dcdf30d..7257891a 100644 --- a/tools/chatgui/src/stream_publish_engine.h +++ b/tools/chatgui/src/stream_publish_engine.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include "live_video_encoder.h" #include "stream_video_modes.h" @@ -22,6 +24,10 @@ struct StreamVideoSource { QVariant window; QSize size; QList modes; + QPointer screen; // Живой монитор; удаление устройства не должно переключать захват на его одноимённого соседа. + bool sameSource(const StreamVideoSource& other) const { + return kind == other.kind && id == other.id && window == other.window && screen == other.screen; + } }; struct StreamPublishConfig { StreamVideoSource source; diff --git a/tools/chatgui/src/stream_publish_window.cpp b/tools/chatgui/src/stream_publish_window.cpp index 1d269619..29cb47b5 100644 --- a/tools/chatgui/src/stream_publish_window.cpp +++ b/tools/chatgui/src/stream_publish_window.cpp @@ -186,7 +186,7 @@ void StreamPublishWindow::refreshSources() { int selected = -1; for (int i = 0; i < m_sources.size(); i++) { auto& source = m_sources[i]; - if (source.kind == config.source.kind && source.id == config.source.id && source.window == config.source.window) { + if (source.sameSource(config.source)) { selected = i; if (m_engine->active() && !config.source.size.isEmpty()) source.size = config.source.size; } @@ -279,8 +279,7 @@ void StreamPublishWindow::synchronize() { { QSignalBlocker blocked(m_mute); m_mute->setChecked(m_engine->muted()); } if (active) { auto config = m_engine->config(); - for (int i = 0; i < m_sources.size(); i++) if (m_sources[i].kind == config.source.kind - && m_sources[i].id == config.source.id && m_sources[i].window == config.source.window) { + for (int i = 0; i < m_sources.size(); i++) if (m_sources[i].sameSource(config.source)) { m_source->setCurrentIndex(i); if (!config.source.size.isEmpty()) m_sources[i].size = config.source.size; } refreshModes(config);