KPipewire

pipewiresourcestream.h
1/*
2 SPDX-FileCopyrightText: 2018-2020 Red Hat Inc
3 SPDX-FileCopyrightText: 2020-2021 Aleix Pol Gonzalez <aleixpol@kde.org>
4 SPDX-FileContributor: Jan Grulich <jgrulich@redhat.com>
5
6 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
7*/
8
9#pragma once
10
11#include <QDebug>
12#include <QHash>
13#include <QImage>
14#include <QObject>
15#include <QPoint>
16#include <QSharedPointer>
17#include <QSize>
18#include <optional>
19
20#include <pipewire/pipewire.h>
21#include <spa/param/format-utils.h>
22#include <spa/param/props.h>
23#include <spa/param/video/format-utils.h>
24
25#include <kpipewire_export.h>
26
27#undef Status
28
30class PipeWireCore;
31struct gbm_device;
32
33typedef void *EGLDisplay;
34
35struct DmaBufPlane {
36 int fd; ///< The dmabuf file descriptor
37 uint32_t offset; ///< The offset from the start of buffer
38 uint32_t stride; ///< The distance from the start of a row to the next row in bytes
39};
40
41struct DmaBufAttributes {
42 int width = 0;
43 int height = 0;
44 uint32_t format = 0;
45 uint64_t modifier = 0; ///< The layout modifier
46
47 QList<DmaBufPlane> planes;
48};
49
50struct PipeWireCursor {
51 QPoint position;
52 QPoint hotspot;
53 QImage texture;
54 bool operator!=(const PipeWireCursor &other) const
55 {
56 return !operator==(other);
57 };
58 bool operator==(const PipeWireCursor &other) const
59 {
60 return position == other.position && hotspot == other.hotspot && texture == other.texture;
61 }
62};
63
64class KPIPEWIRE_EXPORT PipeWireFrameData
65{
66 Q_DISABLE_COPY(PipeWireFrameData)
67public:
68 PipeWireFrameData(spa_video_format format, void *data, QSize size, qint32 stride, PipeWireFrameCleanupFunction *cleanup);
69 ~PipeWireFrameData();
70
71 QImage toImage() const;
72 std::shared_ptr<PipeWireFrameData> copy() const;
73
74 const spa_video_format format;
75 void *const data = nullptr;
76 const QSize size;
77 const qint32 stride = 0;
78 PipeWireFrameCleanupFunction *const cleanup = nullptr;
79};
80
81struct KPIPEWIRE_EXPORT PipeWireFrame {
82 spa_video_format format;
83 std::optional<quint64> sequential;
84 std::optional<std::chrono::nanoseconds> presentationTimestamp;
85 std::optional<DmaBufAttributes> dmabuf;
86 std::optional<QRegion> damage;
87 std::optional<PipeWireCursor> cursor;
88 std::shared_ptr<PipeWireFrameData> dataFrame;
89};
90
91struct Fraction {
92 bool operator==(const Fraction &other) const
93 {
94 return numerator == other.numerator && denominator == other.denominator;
95 }
96 explicit operator bool() const
97 {
98 return isValid();
99 }
100 bool isValid() const
101 {
102 return denominator > 0;
103 }
104 quint32 numerator = 0;
105 quint32 denominator = 0;
106};
107
108struct PipeWireSourceStreamPrivate;
109
110class KPIPEWIRE_EXPORT PipeWireSourceStream : public QObject
111{
112 Q_OBJECT
113public:
114 /**
115 * A hint to indicate how this stream will be used.
116 *
117 * By default this will be set to Render.
118 */
119 enum class UsageHint {
120 Render, ///< Stream is intended mainly for reading pixel data and rendering directly to screen.
121 EncodeSoftware, ///< Stream is intended mainly for encoding video using software encoding.
122 EncodeHardware, ///< Stream is intended mainly for encoding video using hardware encoding.
123 };
124
125 explicit PipeWireSourceStream(QObject *parent = nullptr);
126 ~PipeWireSourceStream();
127
128 Fraction framerate() const;
129 void setMaxFramerate(const Fraction &framerate);
130 uint nodeId();
131 QString error() const;
132
133 QSize size() const;
134 pw_stream_state state() const;
135 bool createStream(uint nodeid, int fd);
136 void setActive(bool active);
137 void setDamageEnabled(bool withDamage);
138
139 UsageHint usageHint() const;
140 void setUsageHint(UsageHint hint);
141
142 void handleFrame(struct pw_buffer *buffer);
143 void process();
144 void renegotiateModifierFailed(spa_video_format format, quint64 modifier);
145
146 std::optional<std::chrono::nanoseconds> currentPresentationTimestamp() const;
147
148 static uint32_t spaVideoFormatToDrmFormat(spa_video_format spa_format);
149
150 bool usingDmaBuf() const;
151 bool allowDmaBuf() const;
152 void setAllowDmaBuf(bool allowed);
153
154Q_SIGNALS:
155 void streamReady();
156 void startStreaming();
157 void stopStreaming();
158 void streamParametersChanged();
159 void frameReceived(const PipeWireFrame &frame);
160 void stateChanged(pw_stream_state state, pw_stream_state oldState);
161
162private:
163 static void onStreamParamChanged(void *data, uint32_t id, const struct spa_pod *format);
164 static void onStreamStateChanged(void *data, pw_stream_state old, pw_stream_state state, const char *error_message);
165 static void onRenegotiate(void *data, uint64_t);
166 static void onDestroy(void *data);
167 QList<const spa_pod *> createFormatsParams(spa_pod_builder podBuilder);
168
169 void coreFailed(const QString &errorMessage);
171};
The to track the lifetime of a pipewire frame.
Definition pwhelpers.h:25
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
const QList< QKeySequence > & copy()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:15:17 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.