1 // SPDX-FileCopyrightText: 2021 Nheko Contributors
2 //
3 // SPDX-License-Identifier: GPL-3.0-or-later
4 
5 #pragma once
6 
7 #include <string>
8 #include <vector>
9 
10 #include <QObject>
11 
12 #include "mtx/events/voip.hpp"
13 
14 typedef struct _GstElement GstElement;
15 class CallDevices;
16 class QQuickItem;
17 
18 namespace webrtc {
19 Q_NAMESPACE
20 
21 enum class CallType
22 {
23     VOICE,
24     VIDEO,
25     SCREEN // localUser is sharing screen
26 };
27 Q_ENUM_NS(CallType)
28 
29 enum class State
30 {
31     DISCONNECTED,
32     ICEFAILED,
33     INITIATING,
34     INITIATED,
35     OFFERSENT,
36     ANSWERSENT,
37     CONNECTING,
38     CONNECTED
39 
40 };
41 Q_ENUM_NS(State)
42 }
43 
44 class WebRTCSession : public QObject
45 {
46     Q_OBJECT
47 
48 public:
instance()49     static WebRTCSession &instance()
50     {
51         static WebRTCSession instance;
52         return instance;
53     }
54 
55     bool havePlugins(bool isVideo, std::string *errorMessage = nullptr);
callType()56     webrtc::CallType callType() const { return callType_; }
state()57     webrtc::State state() const { return state_; }
58     bool haveLocalPiP() const;
isOffering()59     bool isOffering() const { return isOffering_; }
isRemoteVideoRecvOnly()60     bool isRemoteVideoRecvOnly() const { return isRemoteVideoRecvOnly_; }
isRemoteVideoSendOnly()61     bool isRemoteVideoSendOnly() const { return isRemoteVideoSendOnly_; }
62 
63     bool createOffer(webrtc::CallType, uint32_t shareWindowId);
64     bool acceptOffer(const std::string &sdp);
65     bool acceptAnswer(const std::string &sdp);
66     void acceptICECandidates(const std::vector<mtx::events::msg::CallCandidates::Candidate> &);
67 
68     bool isMicMuted() const;
69     bool toggleMicMute();
70     void toggleLocalPiP();
71     void end();
72 
setTurnServers(const std::vector<std::string> & uris)73     void setTurnServers(const std::vector<std::string> &uris) { turnServers_ = uris; }
74 
setVideoItem(QQuickItem * item)75     void setVideoItem(QQuickItem *item) { videoItem_ = item; }
getVideoItem()76     QQuickItem *getVideoItem() const { return videoItem_; }
77 
78 signals:
79     void offerCreated(const std::string &sdp,
80                       const std::vector<mtx::events::msg::CallCandidates::Candidate> &);
81     void answerCreated(const std::string &sdp,
82                        const std::vector<mtx::events::msg::CallCandidates::Candidate> &);
83     void newICECandidate(const mtx::events::msg::CallCandidates::Candidate &);
84     void stateChanged(webrtc::State);
85 
86 private slots:
setState(webrtc::State state)87     void setState(webrtc::State state) { state_ = state; }
88 
89 private:
90     WebRTCSession();
91 
92     CallDevices &devices_;
93     bool initialised_           = false;
94     bool haveVoicePlugins_      = false;
95     bool haveVideoPlugins_      = false;
96     webrtc::CallType callType_  = webrtc::CallType::VOICE;
97     webrtc::State state_        = webrtc::State::DISCONNECTED;
98     bool isOffering_            = false;
99     bool isRemoteVideoRecvOnly_ = false;
100     bool isRemoteVideoSendOnly_ = false;
101     QQuickItem *videoItem_      = nullptr;
102     GstElement *pipe_           = nullptr;
103     GstElement *webrtc_         = nullptr;
104     unsigned int busWatchId_    = 0;
105     std::vector<std::string> turnServers_;
106     uint32_t shareWindowId_ = 0;
107 
108     bool init(std::string *errorMessage = nullptr);
109     bool startPipeline(int opusPayloadType, int vp8PayloadType);
110     bool createPipeline(int opusPayloadType, int vp8PayloadType);
111     bool addVideoPipeline(int vp8PayloadType);
112     void clear();
113 
114 public:
115     WebRTCSession(WebRTCSession const &) = delete;
116     void operator=(WebRTCSession const &) = delete;
117 };
118