From 725d61877c662e3267d25b52f1c725138c15e6ca Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Mon, 17 Jan 2022 13:31:48 +0100 Subject: [PATCH] screencast: have our streams provide SPA_META_Header It can be useful for clients to know what's going on in a specific stream. --- .../screencast/outputscreencastsource.cpp | 6 ++++++ .../screencast/outputscreencastsource.h | 1 + src/plugins/screencast/screencastsource.h | 1 + src/plugins/screencast/screencaststream.cpp | 19 ++++++++++++++++++- src/plugins/screencast/screencaststream.h | 9 ++++++++- .../screencast/windowscreencastsource.cpp | 7 +++++++ .../screencast/windowscreencastsource.h | 1 + 7 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/plugins/screencast/outputscreencastsource.cpp b/src/plugins/screencast/outputscreencastsource.cpp index d7c2151537..cefb728836 100644 --- a/src/plugins/screencast/outputscreencastsource.cpp +++ b/src/plugins/screencast/outputscreencastsource.cpp @@ -11,6 +11,7 @@ #include "composite.h" #include "kwingltexture.h" #include "kwinglutils.h" +#include "renderloop.h" #include "scene.h" namespace KWin @@ -62,4 +63,9 @@ void OutputScreenCastSource::render(GLRenderTarget *target) GLRenderTarget::popRenderTarget(); } +std::chrono::nanoseconds OutputScreenCastSource::clock() const +{ + return m_output->renderLoop()->lastPresentationTimestamp(); +} + } // namespace KWin diff --git a/src/plugins/screencast/outputscreencastsource.h b/src/plugins/screencast/outputscreencastsource.h index 64c8d51525..e8bf6911ed 100644 --- a/src/plugins/screencast/outputscreencastsource.h +++ b/src/plugins/screencast/outputscreencastsource.h @@ -27,6 +27,7 @@ public: void render(GLRenderTarget *target) override; void render(QImage *image) override; + std::chrono::nanoseconds clock() const override; private: QPointer m_output; diff --git a/src/plugins/screencast/screencastsource.h b/src/plugins/screencast/screencastsource.h index 7d8090b98f..1b19bc7f20 100644 --- a/src/plugins/screencast/screencastsource.h +++ b/src/plugins/screencast/screencastsource.h @@ -25,6 +25,7 @@ public: virtual void render(GLRenderTarget *target) = 0; virtual void render(QImage *image) = 0; + virtual std::chrono::nanoseconds clock() const = 0; Q_SIGNALS: void closed(); diff --git a/src/plugins/screencast/screencaststream.cpp b/src/plugins/screencast/screencaststream.cpp index cb3531f0dc..5d5dec7d09 100644 --- a/src/plugins/screencast/screencaststream.cpp +++ b/src/plugins/screencast/screencaststream.cpp @@ -108,9 +108,13 @@ void ScreenCastStream::newStreamParams() sizeof(struct spa_meta_region) * videoDamageRegionCount, sizeof(struct spa_meta_region) * 1, sizeof(struct spa_meta_region) * videoDamageRegionCount)), + (spa_pod*) spa_pod_builder_add_object(&pod_builder, + SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, + SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), + SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header))), }; - pw_stream_update_params(pwStream, params, 3); + pw_stream_update_params(pwStream, params, 4); } void ScreenCastStream::onStreamParamChanged(void *data, uint32_t id, const struct spa_pod *format) @@ -456,6 +460,19 @@ void ScreenCastStream::recordFrame(const QRegion &damagedRegion) } } + spa_meta_header *spaHeader = (spa_meta_header *) spa_buffer_find_meta_data(spa_buffer, SPA_META_Header, sizeof(spaHeader)); + if (spaHeader) { + spaHeader->flags = 0; + spaHeader->dts_offset = 0; + spaHeader->seq = m_sequential++; + + const auto timestamp = m_source->clock(); + if (!m_start) { + m_start = timestamp; + } + spaHeader->pts = (timestamp - m_start.value()).count(); + } + tryEnqueue(buffer); } diff --git a/src/plugins/screencast/screencaststream.h b/src/plugins/screencast/screencaststream.h index 63a343756b..19dc747890 100644 --- a/src/plugins/screencast/screencaststream.h +++ b/src/plugins/screencast/screencaststream.h @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -50,7 +52,10 @@ public: void stop(); - /** Renders @p frame into the current framebuffer into the stream */ + /** + * Renders @p frame into the current framebuffer into the stream + * @p timestamp + */ void recordFrame(const QRegion &damagedRegion); void setCursorMode(KWaylandServer::ScreencastV1Interface::CursorMode mode, qreal scale, const QRect &viewport); @@ -111,6 +116,8 @@ private: pw_buffer *m_pendingBuffer = nullptr; QSocketNotifier *m_pendingNotifier = nullptr; EGLNativeFence *m_pendingFence = nullptr; + std::optional m_start; + quint64 m_sequential = 0; }; } // namespace KWin diff --git a/src/plugins/screencast/windowscreencastsource.cpp b/src/plugins/screencast/windowscreencastsource.cpp index 2ac14ac836..40e4fab81e 100644 --- a/src/plugins/screencast/windowscreencastsource.cpp +++ b/src/plugins/screencast/windowscreencastsource.cpp @@ -7,11 +7,13 @@ #include "windowscreencastsource.h" #include "screencastutils.h" +#include "abstract_output.h" #include "deleted.h" #include "effects.h" #include "kwineffects.h" #include "kwingltexture.h" #include "kwinglutils.h" +#include "renderloop.h" #include "scene.h" #include "toplevel.h" @@ -62,4 +64,9 @@ void WindowScreenCastSource::render(GLRenderTarget *target) GLRenderTarget::popRenderTarget(); } +std::chrono::nanoseconds WindowScreenCastSource::clock() const +{ + return m_window->output()->renderLoop()->lastPresentationTimestamp(); +} + } // namespace KWin diff --git a/src/plugins/screencast/windowscreencastsource.h b/src/plugins/screencast/windowscreencastsource.h index 5b07068c90..2a928f22d4 100644 --- a/src/plugins/screencast/windowscreencastsource.h +++ b/src/plugins/screencast/windowscreencastsource.h @@ -27,6 +27,7 @@ public: void render(GLRenderTarget *target) override; void render(QImage *image) override; + std::chrono::nanoseconds clock() const override; private: QPointer m_window;