kwin/plugins/screencast/pipewirestream.h

110 lines
2.9 KiB
C
Raw Normal View History

/*
2020-08-02 22:22:19 +00:00
SPDX-FileCopyrightText: 2018-2020 Red Hat Inc
SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
SPDX-FileContributor: Jan Grulich <jgrulich@redhat.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#pragma once
2020-07-28 13:37:04 +00:00
#include "config-kwin.h"
#include "kwinglobals.h"
#include <KWaylandServer/screencast_v1_interface.h>
2020-07-28 13:37:04 +00:00
#include <QHash>
2020-07-28 13:37:04 +00:00
#include <QObject>
#include <QSharedPointer>
2020-07-28 13:37:04 +00:00
#include <QSize>
#include <QSocketNotifier>
#include <pipewire/pipewire.h>
#include <spa/param/format-utils.h>
#include <spa/param/props.h>
2020-07-28 13:37:04 +00:00
#include <spa/param/video/format-utils.h>
namespace KWin
{
2020-07-28 13:37:04 +00:00
class Cursor;
class DmaBufTexture;
class EGLNativeFence;
2020-07-28 13:37:04 +00:00
class GLTexture;
class PipeWireCore;
class KWIN_EXPORT PipeWireStream : public QObject
{
Q_OBJECT
public:
explicit PipeWireStream(bool hasAlpha, const QSize &resolution, QObject *parent);
~PipeWireStream();
bool init();
uint framerate();
uint nodeId();
QString error() const {
return m_error;
}
void stop();
/** Renders @p frame into the current framebuffer into the stream */
2020-07-28 13:37:04 +00:00
void recordFrame(GLTexture *frame, const QRegion &damagedRegion);
void setCursorMode(KWaylandServer::ScreencastV1Interface::CursorMode mode, qreal scale, const QRect &viewport);
Q_SIGNALS:
void streamReady(quint32 nodeId);
void startStreaming();
void stopStreaming();
private:
static void onStreamParamChanged(void *data, uint32_t id, const struct spa_pod *format);
static void onStreamStateChanged(void *data, pw_stream_state old, pw_stream_state state, const char *error_message);
static void onStreamAddBuffer(void *data, pw_buffer *buffer);
static void onStreamRemoveBuffer(void *data, pw_buffer *buffer);
bool createStream();
void updateParams();
void coreFailed(const QString &errorMessage);
2020-07-28 13:37:04 +00:00
void sendCursorData(Cursor *cursor, spa_meta_cursor *spa_cursor);
void newStreamParams();
void tryEnqueue(pw_buffer *buffer);
void enqueue();
QSharedPointer<PipeWireCore> pwCore;
struct pw_stream *pwStream = nullptr;
spa_hook streamListener;
pw_stream_events pwStreamEvents = {};
uint32_t pwNodeId = 0;
QSize m_resolution;
bool m_stopped = false;
spa_video_info_raw videoFormat;
QString m_error;
const bool m_hasAlpha;
struct {
KWaylandServer::ScreencastV1Interface::CursorMode mode = KWaylandServer::ScreencastV1Interface::Hidden;
qreal scale = 1;
QRect viewport;
qint64 lastKey = 0;
QRect lastRect;
2020-07-28 13:37:04 +00:00
QScopedPointer<GLTexture> texture;
QScopedPointer<GLTexture> lastFrameTexture;
} m_cursor;
bool m_repainting = false;
2020-07-28 13:37:04 +00:00
QRect cursorGeometry(Cursor *cursor) const;
2020-07-28 13:37:04 +00:00
QHash<struct pw_buffer *, QSharedPointer<DmaBufTexture>> m_dmabufDataForPwBuffer;
pw_buffer *m_pendingBuffer = nullptr;
QSocketNotifier *m_pendingNotifier = nullptr;
EGLNativeFence *m_pendingFence = nullptr;
};
2020-07-28 13:37:04 +00:00
} // namespace KWin