// SPDX-FileCopyrightText: Nheko Contributors // // SPDX-License-Identifier: GPL-3.0-or-later #pragma once #include #include #include #include #include "mtx/events/voip.hpp" typedef struct _GstElement GstElement; class CallDevices; class QQuickItem; namespace webrtc { Q_NAMESPACE QML_NAMED_ELEMENT(Voip) enum class CallType { VOICE, VIDEO, SCREEN // localUser is sharing screen }; Q_ENUM_NS(CallType) enum class ScreenShareType { X11, XDP, D3D11 }; Q_ENUM_NS(ScreenShareType) enum class State { DISCONNECTED, ICEFAILED, INITIATING, INITIATED, OFFERSENT, ANSWERSENT, CONNECTING, CONNECTED }; Q_ENUM_NS(State) } class WebRTCSession final : public QObject { Q_OBJECT public: static WebRTCSession &instance() { static WebRTCSession instance; return instance; } bool havePlugins(bool isVideo, bool isScreenshare, webrtc::ScreenShareType screenShareType, std::string *errorMessage = nullptr); webrtc::CallType callType() const { return callType_; } webrtc::State state() const { return state_; } bool haveLocalPiP() const; bool isOffering() const { return isOffering_; } bool isRemoteVideoRecvOnly() const { return isRemoteVideoRecvOnly_; } bool isRemoteVideoSendOnly() const { return isRemoteVideoSendOnly_; } bool createOffer(webrtc::CallType, webrtc::ScreenShareType, uint32_t shareWindowId); bool acceptOffer(const std::string &sdp); bool acceptAnswer(const std::string &sdp); bool acceptNegotiation(const std::string &sdp); void acceptICECandidates(const std::vector &); bool isMicMuted() const; bool toggleMicMute(); void toggleLocalPiP(); void end(); void setTurnServers(const std::vector &uris) { turnServers_ = uris; } void setVideoItem(QQuickItem *item) { videoItem_ = item; } QQuickItem *getVideoItem() const { return videoItem_; } signals: void offerCreated(const std::string &sdp, const std::vector &); void answerCreated(const std::string &sdp, const std::vector &); void newICECandidate(const mtx::events::voip::CallCandidates::Candidate &); void stateChanged(webrtc::State); private slots: void setState(webrtc::State state) { state_ = state; } private: WebRTCSession(); CallDevices &devices_; bool initialised_ = false; bool haveVoicePlugins_ = false; bool haveVideoPlugins_ = false; webrtc::CallType callType_ = webrtc::CallType::VOICE; webrtc::ScreenShareType screenShareType_ = webrtc::ScreenShareType::X11; webrtc::State state_ = webrtc::State::DISCONNECTED; bool isOffering_ = false; bool isRemoteVideoRecvOnly_ = false; bool isRemoteVideoSendOnly_ = false; QQuickItem *videoItem_ = nullptr; GstElement *pipe_ = nullptr; GstElement *webrtc_ = nullptr; unsigned int busWatchId_ = 0; std::vector turnServers_; uint32_t shareWindowId_ = 0; bool init(std::string *errorMessage = nullptr); bool startPipeline(int opusPayloadType, int vp8PayloadType); bool createPipeline(int opusPayloadType, int vp8PayloadType); bool addVideoPipeline(int vp8PayloadType); void clear(); public: WebRTCSession(WebRTCSession const &) = delete; void operator=(WebRTCSession const &) = delete; };