File indexing completed on 2024-05-05 09:46:37

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 
0054     /**
0055      * Allows disabling the dmabuf streams
0056      */
0057     Q_PROPERTY(bool allowDmaBuf READ allowDmaBuf WRITE setAllowDmaBuf)
0058 
0059     Q_PROPERTY(bool usingDmaBuf READ usingDmaBuf NOTIFY usingDmaBufChanged)
0060 
0061 public:
0062     enum class StreamState { Error, Unconnected, Connecting, Paused, Streaming };
0063     Q_ENUM(StreamState);
0064 
0065     PipeWireSourceItem(QQuickItem *parent = nullptr);
0066     ~PipeWireSourceItem() override;
0067 
0068     QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) override;
0069     Q_SCRIPTABLE QString error() const;
0070 
0071     void setNodeId(uint nodeId);
0072     uint nodeId() const;
0073 
0074     void setFd(uint fd);
0075     void resetFd();
0076     uint fd() const;
0077 
0078     QSize streamSize() const;
0079 
0080     bool usingDmaBuf() const;
0081     bool allowDmaBuf() const;
0082     void setAllowDmaBuf(bool allowed);
0083 
0084     void componentComplete() override;
0085     void releaseResources() override;
0086 
0087     StreamState state() const;
0088 
0089 Q_SIGNALS:
0090     void nodeIdChanged(uint nodeId);
0091     void fdChanged(uint fd);
0092     void streamSizeChanged();
0093     void stateChanged();
0094     void usingDmaBufChanged();
0095 
0096 private:
0097     void itemChange(ItemChange change, const ItemChangeData &data) override;
0098     void processFrame(const PipeWireFrame &frame);
0099     void updateTextureDmaBuf(const DmaBufAttributes &attribs, spa_video_format format);
0100     void updateTextureImage(const QImage &image);
0101     void refresh();
0102 
0103     QScopedPointer<PipeWireSourceItemPrivate> d;
0104 };