Browse Source

Keep live capture bound to the selected monitor instance

master
evgeny 3 days ago
parent
commit
ac8e701406
  1. 12
      tools/chatgui/src/stream_publish_engine.cpp
  2. 6
      tools/chatgui/src/stream_publish_engine.h
  3. 5
      tools/chatgui/src/stream_publish_window.cpp

12
tools/chatgui/src/stream_publish_engine.cpp

@ -166,7 +166,8 @@ QList<StreamVideoSource> 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<QScreenCapture>();
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<std::mutex> 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<std::mutex> guard(m->lock);

6
tools/chatgui/src/stream_publish_engine.h

@ -7,6 +7,8 @@
#include <QVariant>
#include <QImage>
#include <QList>
#include <QPointer>
#include <QScreen>
#include <memory>
#include "live_video_encoder.h"
#include "stream_video_modes.h"
@ -22,6 +24,10 @@ struct StreamVideoSource {
QVariant window;
QSize size;
QList<StreamVideoMode> modes;
QPointer<QScreen> screen; // Живой монитор; удаление устройства не должно переключать захват на его одноимённого соседа.
bool sameSource(const StreamVideoSource& other) const {
return kind == other.kind && id == other.id && window == other.window && screen == other.screen;
}
};
struct StreamPublishConfig {
StreamVideoSource source;

5
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);

Loading…
Cancel
Save