2020-07-22 17:29:23 +00:00
|
|
|
/*
|
2020-08-02 22:10:35 +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>
|
2020-07-22 17:29:23 +00:00
|
|
|
*
|
2020-08-02 22:10:35 +00:00
|
|
|
* SPDX-License-Identifier: LGPL-2.0-or-later
|
2020-07-22 17:29:23 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-07-28 13:37:04 +00:00
|
|
|
#include "config-kwin.h"
|
|
|
|
#include "kwinglobals.h"
|
|
|
|
|
|
|
|
#include <KWaylandServer/screencast_interface.h>
|
|
|
|
|
2020-07-22 17:29:23 +00:00
|
|
|
#include <QHash>
|
2020-07-28 13:37:04 +00:00
|
|
|
#include <QObject>
|
2020-07-22 17:29:23 +00:00
|
|
|
#include <QSharedPointer>
|
2020-07-28 13:37:04 +00:00
|
|
|
#include <QSize>
|
2020-07-22 17:29:23 +00:00
|
|
|
|
|
|
|
#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>
|
2020-07-22 17:29:23 +00:00
|
|
|
|
|
|
|
namespace KWin
|
|
|
|
{
|
2020-07-28 13:37:04 +00:00
|
|
|
|
|
|
|
class Cursor;
|
|
|
|
class DmaBufTexture;
|
|
|
|
class GLTexture;
|
2020-07-22 17:29:23 +00:00
|
|
|
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);
|
2020-07-22 17:29:23 +00:00
|
|
|
|
|
|
|
void setCursorMode(KWaylandServer::ScreencastInterface::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);
|
2020-07-22 17:29:23 +00:00
|
|
|
void newStreamParams();
|
|
|
|
|
|
|
|
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::ScreencastInterface::CursorMode mode = KWaylandServer::ScreencastInterface::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;
|
2020-07-22 17:29:23 +00:00
|
|
|
} m_cursor;
|
|
|
|
bool m_repainting = false;
|
2020-07-28 13:37:04 +00:00
|
|
|
QRect cursorGeometry(Cursor *cursor) const;
|
2020-07-22 17:29:23 +00:00
|
|
|
|
2020-07-28 13:37:04 +00:00
|
|
|
QHash<struct pw_buffer *, QSharedPointer<DmaBufTexture>> m_dmabufDataForPwBuffer;
|
2020-07-22 17:29:23 +00:00
|
|
|
};
|
2020-07-28 13:37:04 +00:00
|
|
|
|
|
|
|
} // namespace KWin
|