Revision control

Copy as Markdown

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QPIPEWIRE_SCREENCAPTUREHELPER_P_H
#define QPIPEWIRE_SCREENCAPTUREHELPER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtMultimedia/qvideoframe.h>
#include <QtMultimedia/private/qpipewire_screencapture_p.h>
#include <QtMultimedia/private/qsurfacecapturegrabber_p.h>
#include <QtMultimedia/private/qpipewire_support_p.h>
#include <QtDBus/qdbusextratypes.h>
#include <pipewire/pipewire.h>
#include <spa/param/video/format.h>
#include <spa/utils/dict.h>
#include <memory>
QT_BEGIN_NAMESPACE
class QDBusArgument;
class QDBusInterface;
class QDBusUnixFileDescriptor;
namespace QtPipeWire {
inline constexpr qreal DefaultCaptureFrameRate = 25.f;
class QPipeWireInstance;
class QPipeWireCaptureHelper : public QSurfaceCaptureGrabber
{
Q_OBJECT
public:
explicit QPipeWireCaptureHelper(QPipeWireCapture &, std::shared_ptr<QPipeWireInstance>);
~QPipeWireCaptureHelper() override;
bool open(QDBusUnixFileDescriptor);
QVideoFrameFormat frameFormat() const;
protected:
QVideoFrame grabFrame() override;
void initializeGrabbingContext() override;
void finalizeGrabbingContext() override;
private:
void destroy();
void onStateChanged(pw_stream_state old, pw_stream_state state, const char *error);
void onProcess();
void onParamChanged(uint32_t id, const struct spa_pod *param);
void recreateStream();
void destroyStream(bool waitForStreamEnd);
void signalLoop(bool onProcessDone, bool err);
bool subscribeToRequestResponse(const QString &handleToken);
void unsubscribeFromRequestResponse();
void createInterface();
void createSession();
void selectSources(const QDBusObjectPath &sessionHandle);
void startStream();
void updateStreams(const QDBusArgument &streamsInfo);
void openPipeWireRemote();
void closeSession();
private Q_SLOTS:
void gotRequestResponse(uint result, const QVariantMap &map);
void sessionClosed();
private:
const std::shared_ptr<QPipeWireInstance> m_pwInstance;
QVideoFrame m_currentFrame;
QVideoFrameFormat m_videoFrameFormat;
QVideoFrameFormat::PixelFormat m_pixelFormat{};
QSize m_size;
PwCoreConnectionHandle m_core;
PwRegistryHandle m_registry = nullptr;
PwStreamHandle m_stream = nullptr;
spa_hook m_streamListener = {};
spa_video_info m_format{};
bool m_err = false;
bool m_ignoreStateChange = false;
pw_stream_state m_streamState{}; // guarded by pw event loop lock
bool m_processed = false;
QString m_pendingRequestPath;
QDBusObjectPath m_sessionHandle;
std::unique_ptr<QDBusInterface> m_sessionInterface;
struct StreamInfo
{
quint32 nodeId;
quint32 sourceType;
QRect rect;
};
QVector<StreamInfo> m_streams;
std::unique_ptr<QDBusInterface> m_screenCastInterface;
enum OperationState { NoOperation, CreateSession, SelectSources, StartStream, OpenPipeWireRemote };
OperationState m_operationState = NoOperation;
enum State { NoState, Starting, Streaming, Stopping };
State m_state = NoState;
};
} // namespace QtPipeWire
QT_END_NAMESPACE
#endif // QPIPEWIRE_SCREENCAPTUREHELPER_P_H