Add native Windows cursor overlay to screen broadcasts
This commit is contained in:
1 parent
49d55a25a1
commit
4a6f95cebd
6 files changed
+202
-17
No files matched your search
@@ -34,7 +34,7 @@ extern "C" {
|
||||
#include <QWindowCapture>
|
||||
#include <QVideoFrame>
|
||||
#endif
|
||||
#ifdef UTUN_STREAM_X11_CURSOR
|
||||
#if defined(UTUN_STREAM_X11_CURSOR) || defined(UTUN_STREAM_WIN_CURSOR)
|
||||
#include "stream_screen_cursor.h"
|
||||
#endif
|
||||
#ifdef UTUN_STREAM_PORTAL
|
||||
@@ -113,7 +113,7 @@ struct StreamPublishEngine::Impl {
|
||||
std::unique_ptr<StreamPortalCapture> portal;
|
||||
#endif
|
||||
std::unique_ptr<QTimer> screenGrabTimer;
|
||||
#ifdef UTUN_STREAM_X11_CURSOR
|
||||
#if defined(UTUN_STREAM_X11_CURSOR) || defined(UTUN_STREAM_WIN_CURSOR)
|
||||
std::unique_ptr<StreamScreenCursor> cursor;
|
||||
#endif
|
||||
std::unique_ptr<QWindowCapture> window;
|
||||
@@ -235,6 +235,8 @@ bool StreamPublishEngine::cursorSupported(const StreamVideoSource& source) {
|
||||
#endif
|
||||
#ifdef UTUN_STREAM_X11_CURSOR
|
||||
return source.kind == StreamVideoSource::Screen && source.screen && source.id != "portal" && QGuiApplication::platformName() == "xcb";
|
||||
#elif defined(UTUN_STREAM_WIN_CURSOR)
|
||||
return source.kind == StreamVideoSource::Screen && source.screen && QGuiApplication::platformName() == "windows";
|
||||
#else
|
||||
Q_UNUSED(source); return false;
|
||||
#endif
|
||||
@@ -373,9 +375,10 @@ bool StreamPublishEngine::openSource(const StreamPublishConfig& config) {
|
||||
m->portal->start(config.showCursor);
|
||||
} else
|
||||
#endif
|
||||
// Qt X11 screen capture ищет root по имени и путает мониторы; QScreen захватывает именно выбранный экран.
|
||||
if (selected && QGuiApplication::platformName() == "xcb") {
|
||||
#ifdef UTUN_STREAM_X11_CURSOR
|
||||
// QScreen даёт выбранный монитор без курсора; накладываем его один раз до preview и кодирования.
|
||||
// Для X11 это также исключает путаницу Qt Multimedia с одноимёнными root.
|
||||
if (selected && (QGuiApplication::platformName() == "xcb" || cursorSupported(config.source))) {
|
||||
#if defined(UTUN_STREAM_X11_CURSOR) || defined(UTUN_STREAM_WIN_CURSOR)
|
||||
m->cursor = std::make_unique<StreamScreenCursor>(selected);
|
||||
#endif
|
||||
m->screenGrabTimer = std::make_unique<QTimer>(); m->screenGrabTimer->setTimerType(Qt::PreciseTimer);
|
||||
@@ -384,11 +387,11 @@ bool StreamPublishEngine::openSource(const StreamPublishConfig& config) {
|
||||
int64_t captured = monotonicUs();
|
||||
QImage image = screen ? screen->grabWindow(0).toImage() : QImage();
|
||||
if (image.isNull()) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop X11 screen grab failed present=%d", !screen.isNull());
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop native screen grab failed present=%d", !screen.isNull());
|
||||
m->screenGrabTimer->stop();
|
||||
QMetaObject::invokeMethod(this, [failed] { failed(text("Video capture stopped")); }); return;
|
||||
}
|
||||
#ifdef UTUN_STREAM_X11_CURSOR
|
||||
#if defined(UTUN_STREAM_X11_CURSOR) || defined(UTUN_STREAM_WIN_CURSOR)
|
||||
if (this->config().showCursor && !m->cursor->draw(image)) {
|
||||
m->screenGrabTimer->stop();
|
||||
QMetaObject::invokeMethod(this, [failed] { failed(text("Could not capture the mouse cursor")); }); return;
|
||||
@@ -405,15 +408,16 @@ bool StreamPublishEngine::openSource(const StreamPublishConfig& config) {
|
||||
} else frame = {};
|
||||
#endif
|
||||
if (!frame.isValid()) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop X11 video frame allocation failed size=%dx%d", image.width(), image.height());
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_VIDEO, "desktop native video frame allocation failed size=%dx%d", image.width(), image.height());
|
||||
m->screenGrabTimer->stop();
|
||||
QMetaObject::invokeMethod(this, [failed] { failed(text("Video frame conversion failed")); }); return;
|
||||
}
|
||||
frame.setStartTime(captured); m->sink->setVideoFrame(frame);
|
||||
});
|
||||
m->screenGrabTimer->start(std::max(1, 1000 / std::clamp(config.video.fps, 1, 60)));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_VIDEO, "desktop X11 screen grab started source=%s interval_ms=%d cursor=%d supported=%d",
|
||||
qPrintable(config.source.name), m->screenGrabTimer->interval(), config.showCursor, cursorSupported(config.source));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_VIDEO, "desktop native screen grab started platform=%s source=%s interval_ms=%d cursor=%d supported=%d",
|
||||
qPrintable(QGuiApplication::platformName()), qPrintable(config.source.name), m->screenGrabTimer->interval(),
|
||||
config.showCursor, cursorSupported(config.source));
|
||||
} else {
|
||||
m->screen = std::make_unique<QScreenCapture>();
|
||||
m->screen->setScreen(selected);
|
||||
@@ -454,7 +458,7 @@ void StreamPublishEngine::closeSource() {
|
||||
#ifdef UTUN_STREAM_PORTAL
|
||||
m->portal.reset();
|
||||
#endif
|
||||
#ifdef UTUN_STREAM_X11_CURSOR
|
||||
#if defined(UTUN_STREAM_X11_CURSOR) || defined(UTUN_STREAM_WIN_CURSOR)
|
||||
m->cursor.reset();
|
||||
#endif
|
||||
emit previewVideoChanged(QVariant());
|
||||
|
||||
Reference in new issue
Block a user