File indexing completed on 2024-04-21 16:13:07

0001 /*
0002     Render a PipeWire stream into a QtQuick scene as a standard Item
0003     SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #pragma once
0009 
0010 #include <QImage>
0011 #include <QQuickItem>
0012 #include <functional>
0013 #include <optional>
0014 
0015 #include <pipewire/pipewire.h>
0016 #include <spa/param/format-utils.h>
0017 #include <spa/param/props.h>
0018 #include <spa/param/video/format-utils.h>
0019 
0020 #include <kpipewire_export.h>
0021 
0022 struct DmaBufAttributes;
0023 class PipeWireSourceStream;
0024 struct PipeWireFrame;
0025 class QSGTexture;
0026 class QOpenGLTexture;
0027 typedef void *EGLImage;
0028 
0029 class PipeWireSourceItemPrivate;
0030 
0031 class KPIPEWIRE_EXPORT PipeWireSourceItem : public QQuickItem
0032 {
0033     Q_OBJECT
0034 
0035     /// Returns where the streams current state
0036     Q_PROPERTY(StreamState state READ state NOTIFY stateChanged)
0037 
0038     /// Specify the pipewire node id that we want to play
0039     Q_PROPERTY(uint nodeId READ nodeId WRITE setNodeId NOTIFY nodeIdChanged)
0040 
0041     /**
0042      * Specifies the file descriptor we are connected to, if none 0 will be returned
0043      *
0044      * Transfers the ownership of the fd, will close it when it's done with it.
0045      */
0046     Q_PROPERTY(uint fd READ fd WRITE setFd NOTIFY fdChanged RESET resetFd)
0047 
0048     /**
0049      * Returns the size of the source being rendered
0050      * @note: This won't be updated until the first frame is recieved
0051      */
0052     Q_PROPERTY(QSize streamSize READ streamSize NOTIFY streamSizeChanged)
0053 public:
0054     enum class StreamState { Error, Unconnected, Connecting, Paused, Streaming };
0055     Q_ENUM(StreamState);
0056 
0057     PipeWireSourceItem(QQuickItem *parent = nullptr);
0058     ~PipeWireSourceItem() override;
0059 
0060     QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) override;
0061     Q_SCRIPTABLE QString error() const;
0062 
0063     void setNodeId(uint nodeId);
0064     uint nodeId() const;
0065 
0066     void setFd(uint fd);
0067     void resetFd();
0068     uint fd() const;
0069 
0070     QSize streamSize() const;
0071 
0072     void componentComplete() override;
0073     void releaseResources() override;
0074 
0075     StreamState state() const;
0076 
0077 Q_SIGNALS:
0078     void nodeIdChanged(uint nodeId);
0079     void fdChanged(uint fd);
0080     void stateChanged();
0081     void streamSizeChanged();
0082 
0083 private:
0084     void itemChange(ItemChange change, const ItemChangeData &data) override;
0085     void processFrame(const PipeWireFrame &frame);
0086     void updateTextureDmaBuf(const DmaBufAttributes &attribs, spa_video_format format);
0087     void updateTextureImage(const QImage &image);
0088     void refresh();
0089 
0090     QScopedPointer<PipeWireSourceItemPrivate> d;
0091 };