summaryrefslogtreecommitdiffstats
path: root/src/voip/WebRTCSession.h
blob: 20c32110cdf58fc43b0461f29053b420bce8b8a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-FileCopyrightText: Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once

#include <string>
#include <vector>

#include <QObject>
#include <QQmlEngine>

#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<mtx::events::voip::CallCandidates::Candidate> &);

    bool isMicMuted() const;
    bool toggleMicMute();
    void toggleLocalPiP();
    void end();

    void setTurnServers(const std::vector<std::string> &uris) { turnServers_ = uris; }

    void setVideoItem(QQuickItem *item) { videoItem_ = item; }
    QQuickItem *getVideoItem() const { return videoItem_; }

signals:
    void offerCreated(const std::string &sdp,
                      const std::vector<mtx::events::voip::CallCandidates::Candidate> &);
    void answerCreated(const std::string &sdp,
                       const std::vector<mtx::events::voip::CallCandidates::Candidate> &);
    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<std::string> 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;
};