File indexing completed on 2024-04-21 16:13:07
0001 /* 0002 SPDX-FileCopyrightText: 2018-2020 Red Hat Inc 0003 SPDX-FileCopyrightText: 2020-2021 Aleix Pol Gonzalez <aleixpol@kde.org> 0004 SPDX-FileContributor: Jan Grulich <jgrulich@redhat.com> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #pragma once 0010 0011 #include <QHash> 0012 #include <QImage> 0013 #include <QObject> 0014 #include <QPoint> 0015 #include <QSharedPointer> 0016 #include <QSize> 0017 #include <optional> 0018 0019 #include <pipewire/pipewire.h> 0020 #include <spa/param/format-utils.h> 0021 #include <spa/param/props.h> 0022 #include <spa/param/video/format-utils.h> 0023 0024 #include <kpipewire_export.h> 0025 0026 #undef Status 0027 0028 class PipeWireCore; 0029 struct gbm_device; 0030 0031 typedef void *EGLDisplay; 0032 0033 struct DmaBufPlane { 0034 int fd; ///< The dmabuf file descriptor 0035 uint32_t offset; ///< The offset from the start of buffer 0036 uint32_t stride; ///< The distance from the start of a row to the next row in bytes 0037 }; 0038 0039 struct DmaBufAttributes { 0040 int width = 0; 0041 int height = 0; 0042 uint32_t format = 0; 0043 uint64_t modifier = 0; ///< The layout modifier 0044 0045 QVector<DmaBufPlane> planes; 0046 }; 0047 0048 struct PipeWireCursor { 0049 QPoint position; 0050 QPoint hotspot; 0051 QImage texture; 0052 }; 0053 0054 struct KPIPEWIRE_EXPORT PipeWireFrame { 0055 spa_video_format format; 0056 std::optional<int> sequential; 0057 std::optional<std::chrono::nanoseconds> presentationTimestamp; 0058 std::optional<DmaBufAttributes> dmabuf; 0059 std::optional<QImage> image; 0060 std::optional<QRegion> damage; 0061 std::optional<PipeWireCursor> cursor; 0062 }; 0063 0064 struct Fraction { 0065 const quint32 numerator; 0066 const quint32 denominator; 0067 }; 0068 0069 KPIPEWIRE_EXPORT QImage::Format SpaToQImageFormat(quint32 /*spa_video_format*/ format); 0070 0071 struct PipeWireSourceStreamPrivate; 0072 0073 class KPIPEWIRE_EXPORT PipeWireSourceStream : public QObject 0074 { 0075 Q_OBJECT 0076 public: 0077 explicit PipeWireSourceStream(QObject *parent = nullptr); 0078 ~PipeWireSourceStream(); 0079 0080 Fraction framerate() const; 0081 uint nodeId(); 0082 QString error() const; 0083 0084 QSize size() const; 0085 pw_stream_state state() const; 0086 bool createStream(uint nodeid, int fd); 0087 void setActive(bool active); 0088 void setDamageEnabled(bool withDamage); 0089 0090 void handleFrame(struct pw_buffer *buffer); 0091 void process(); 0092 void renegotiateModifierFailed(spa_video_format format, quint64 modifier); 0093 0094 std::optional<std::chrono::nanoseconds> currentPresentationTimestamp() const; 0095 0096 static uint32_t spaVideoFormatToDrmFormat(spa_video_format spa_format); 0097 0098 Q_SIGNALS: 0099 void streamReady(); 0100 void startStreaming(); 0101 void stopStreaming(); 0102 void streamParametersChanged(); 0103 void frameReceived(const PipeWireFrame &frame); 0104 void stateChanged(pw_stream_state state, pw_stream_state oldState); 0105 0106 private: 0107 static void onStreamParamChanged(void *data, uint32_t id, const struct spa_pod *format); 0108 static void onStreamStateChanged(void *data, pw_stream_state old, pw_stream_state state, const char *error_message); 0109 static void onRenegotiate(void *data, uint64_t); 0110 QVector<const spa_pod *> createFormatsParams(spa_pod_builder podBuilder); 0111 0112 void coreFailed(const QString &errorMessage); 0113 QScopedPointer<PipeWireSourceStreamPrivate> d; 0114 }; 0115 0116 Q_DECLARE_METATYPE(QVector<DmaBufPlane>);