screencast: have our streams provide SPA_META_Header

It can be useful for clients to know what's going on in a specific
stream.
This commit is contained in:
Aleix Pol 2022-01-17 13:31:48 +01:00 committed by Aleix Pol Gonzalez
parent 0574a7534a
commit 725d61877c
7 changed files with 42 additions and 2 deletions

View file

@ -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

View file

@ -27,6 +27,7 @@ public:
void render(GLRenderTarget *target) override;
void render(QImage *image) override;
std::chrono::nanoseconds clock() const override;
private:
QPointer<AbstractOutput> m_output;

View file

@ -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();

View file

@ -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);
}

View file

@ -18,6 +18,8 @@
#include <QSharedPointer>
#include <QSize>
#include <QSocketNotifier>
#include <chrono>
#include <optional>
#include <pipewire/pipewire.h>
#include <spa/param/format-utils.h>
@ -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<std::chrono::nanoseconds> m_start;
quint64 m_sequential = 0;
};
} // namespace KWin

View file

@ -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

View file

@ -27,6 +27,7 @@ public:
void render(GLRenderTarget *target) override;
void render(QImage *image) override;
std::chrono::nanoseconds clock() const override;
private:
QPointer<Toplevel> m_window;