File indexing completed on 2024-05-05 05:30:18

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 PipeWireFrameData;
0026 class QSGTexture;
0027 class QOpenGLTexture;
0028 typedef void *EGLImage;
0029 
0030 class PipeWireSourceItemPrivate;
0031 
0032 class KPIPEWIRE_EXPORT PipeWireSourceItem : public QQuickItem
0033 {
0034     Q_OBJECT
0035 
0036     /// Returns where the streams current state
0037     Q_PROPERTY(StreamState state READ state NOTIFY stateChanged)
0038 
0039     /// Specify the pipewire node id that we want to play
0040     Q_PROPERTY(uint nodeId READ nodeId WRITE setNodeId NOTIFY nodeIdChanged)
0041 
0042     /**
0043      * Specifies the file descriptor we are connected to, if none 0 will be returned
0044      *
0045      * Transfers the ownership of the fd, will close it when it's done with it.
0046      */
0047     Q_PROPERTY(uint fd READ fd WRITE setFd NOTIFY fdChanged RESET resetFd)
0048 
0049     /**
0050      * Returns the size of the source being rendered
0051      * @note: This won't be updated until the first frame is recieved
0052      */
0053     Q_PROPERTY(QSize streamSize READ streamSize NOTIFY streamSizeChanged)
0054 
0055     /**
0056      * Allows disabling the dmabuf streams
0057      */
0058     Q_PROPERTY(bool allowDmaBuf READ allowDmaBuf WRITE setAllowDmaBuf)
0059 
0060     Q_PROPERTY(bool usingDmaBuf READ usingDmaBuf NOTIFY usingDmaBufChanged)
0061 
0062 public:
0063     enum class StreamState { Error, Unconnected, Connecting, Paused, Streaming };
0064     Q_ENUM(StreamState);
0065 
0066     PipeWireSourceItem(QQuickItem *parent = nullptr);
0067     ~PipeWireSourceItem() override;
0068 
0069     QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) override;
0070     Q_SCRIPTABLE QString error() const;
0071 
0072     void setNodeId(uint nodeId);
0073     uint nodeId() const;
0074 
0075     void setFd(uint fd);
0076     void resetFd();
0077     uint fd() const;
0078 
0079     QSize streamSize() const;
0080 
0081     bool usingDmaBuf() const;
0082     bool allowDmaBuf() const;
0083     void setAllowDmaBuf(bool allowed);
0084 
0085     void componentComplete() override;
0086     void releaseResources() override;
0087 
0088     StreamState state() const;
0089 
0090 Q_SIGNALS:
0091     void nodeIdChanged(uint nodeId);
0092     void fdChanged(uint fd);
0093     void streamSizeChanged();
0094     void stateChanged();
0095     void usingDmaBufChanged();
0096 
0097 private:
0098     void itemChange(ItemChange change, const ItemChangeData &data) override;
0099     void processFrame(const PipeWireFrame &frame);
0100     void updateTextureDmaBuf(const DmaBufAttributes &attribs, spa_video_format format);
0101     void updateTextureImage(const std::shared_ptr<PipeWireFrameData> &data);
0102     void refresh();
0103 
0104     QScopedPointer<PipeWireSourceItemPrivate> d;
0105 };