1/*
2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#pragma once
26
27#if USE(LIBWEBRTC)
28
29#include "LibWebRTCObservers.h"
30#include "LibWebRTCProvider.h"
31#include "LibWebRTCRtpSenderBackend.h"
32#include "RTCRtpReceiver.h"
33#include <Timer.h>
34
35ALLOW_UNUSED_PARAMETERS_BEGIN
36
37#include <webrtc/api/jsep.h>
38#include <webrtc/api/peerconnectioninterface.h>
39#include <webrtc/pc/peerconnectionfactory.h>
40#include <webrtc/pc/rtcstatscollector.h>
41
42ALLOW_UNUSED_PARAMETERS_END
43
44#include <wtf/LoggerHelper.h>
45#include <wtf/ThreadSafeRefCounted.h>
46
47namespace webrtc {
48class CreateSessionDescriptionObserver;
49class DataChannelInterface;
50class IceCandidateInterface;
51class MediaStreamInterface;
52class PeerConnectionObserver;
53class SessionDescriptionInterface;
54class SetSessionDescriptionObserver;
55}
56
57namespace WebCore {
58class LibWebRTCProvider;
59class LibWebRTCPeerConnectionBackend;
60class LibWebRTCRtpReceiverBackend;
61class LibWebRTCRtpTransceiverBackend;
62class LibWebRTCStatsCollector;
63class MediaStreamTrack;
64class RTCSessionDescription;
65
66class LibWebRTCMediaEndpoint
67 : public ThreadSafeRefCounted<LibWebRTCMediaEndpoint, WTF::DestructionThread::Main>
68 , private webrtc::PeerConnectionObserver
69 , private webrtc::RTCStatsCollectorCallback
70#if !RELEASE_LOG_DISABLED
71 , private LoggerHelper
72#endif
73{
74public:
75 static Ref<LibWebRTCMediaEndpoint> create(LibWebRTCPeerConnectionBackend& peerConnection, LibWebRTCProvider& client) { return adoptRef(*new LibWebRTCMediaEndpoint(peerConnection, client)); }
76 virtual ~LibWebRTCMediaEndpoint() = default;
77
78 bool setConfiguration(LibWebRTCProvider&, webrtc::PeerConnectionInterface::RTCConfiguration&&);
79
80 webrtc::PeerConnectionInterface& backend() const { ASSERT(m_backend); return *m_backend.get(); }
81 void doSetLocalDescription(RTCSessionDescription&);
82 void doSetRemoteDescription(RTCSessionDescription&);
83 void doCreateOffer(const RTCOfferOptions&);
84 void doCreateAnswer();
85 void getStats(Ref<DeferredPromise>&&);
86 void getStats(webrtc::RtpReceiverInterface&, Ref<DeferredPromise>&&);
87 void getStats(webrtc::RtpSenderInterface&, Ref<DeferredPromise>&&);
88 std::unique_ptr<RTCDataChannelHandler> createDataChannel(const String&, const RTCDataChannelInit&);
89 bool addIceCandidate(webrtc::IceCandidateInterface& candidate) { return m_backend->AddIceCandidate(&candidate); }
90
91 void stop();
92 bool isStopped() const { return !m_backend; }
93
94 RefPtr<RTCSessionDescription> localDescription() const;
95 RefPtr<RTCSessionDescription> remoteDescription() const;
96 RefPtr<RTCSessionDescription> currentLocalDescription() const;
97 RefPtr<RTCSessionDescription> currentRemoteDescription() const;
98 RefPtr<RTCSessionDescription> pendingLocalDescription() const;
99 RefPtr<RTCSessionDescription> pendingRemoteDescription() const;
100
101 bool addTrack(LibWebRTCRtpSenderBackend&, MediaStreamTrack&, const Vector<String>&);
102 void removeTrack(LibWebRTCRtpSenderBackend&);
103
104 struct Backends {
105 std::unique_ptr<LibWebRTCRtpSenderBackend> senderBackend;
106 std::unique_ptr<LibWebRTCRtpReceiverBackend> receiverBackend;
107 std::unique_ptr<LibWebRTCRtpTransceiverBackend> transceiverBackend;
108 };
109 Optional<Backends> addTransceiver(const String& trackKind, const RTCRtpTransceiverInit&);
110 Optional<Backends> addTransceiver(MediaStreamTrack&, const RTCRtpTransceiverInit&);
111 std::unique_ptr<LibWebRTCRtpTransceiverBackend> transceiverBackendFromSender(LibWebRTCRtpSenderBackend&);
112
113 void setSenderSourceFromTrack(LibWebRTCRtpSenderBackend&, MediaStreamTrack&);
114 void collectTransceivers();
115
116private:
117 LibWebRTCMediaEndpoint(LibWebRTCPeerConnectionBackend&, LibWebRTCProvider&);
118
119 // webrtc::PeerConnectionObserver API
120 void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState) final;
121 void OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) final;
122 void OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) final;
123 void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>) final;
124 void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&) final;
125 void OnTrack(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>) final;
126 void OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>) final;
127
128 void OnRenegotiationNeeded() final;
129 void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState) final;
130 void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState) final;
131 void OnIceCandidate(const webrtc::IceCandidateInterface*) final;
132 void OnIceCandidatesRemoved(const std::vector<cricket::Candidate>&) final;
133
134 void createSessionDescriptionSucceeded(std::unique_ptr<webrtc::SessionDescriptionInterface>&&);
135 void createSessionDescriptionFailed(ExceptionCode, const char*);
136 void setLocalSessionDescriptionSucceeded();
137 void setLocalSessionDescriptionFailed(ExceptionCode, const char*);
138 void setRemoteSessionDescriptionSucceeded();
139 void setRemoteSessionDescriptionFailed(ExceptionCode, const char*);
140 void addRemoteStream(webrtc::MediaStreamInterface&);
141 void addRemoteTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>&&, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&);
142 void removeRemoteStream(webrtc::MediaStreamInterface&);
143 void newTransceiver(rtc::scoped_refptr<webrtc::RtpTransceiverInterface>&&);
144 void removeRemoteTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface>&&);
145
146 void addPendingTrackEvent(Ref<RTCRtpReceiver>&&, MediaStreamTrack&, const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&, RefPtr<RTCRtpTransceiver>&&);
147
148 template<typename T>
149 Optional<Backends> createTransceiverBackends(T&&, const RTCRtpTransceiverInit&, LibWebRTCRtpSenderBackend::Source&&);
150
151 void OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>&) final;
152 void gatherStatsForLogging();
153 void startLoggingStats();
154 void stopLoggingStats();
155
156 rtc::scoped_refptr<LibWebRTCStatsCollector> createStatsCollector(Ref<DeferredPromise>&&);
157
158 MediaStream& mediaStreamFromRTCStream(webrtc::MediaStreamInterface&);
159
160 void AddRef() const { ref(); }
161 rtc::RefCountReleaseStatus Release() const
162 {
163 auto result = refCount() - 1;
164 deref();
165 return result ? rtc::RefCountReleaseStatus::kOtherRefsRemained
166 : rtc::RefCountReleaseStatus::kDroppedLastRef;
167 }
168
169 std::pair<LibWebRTCRtpSenderBackend::Source, rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>> createSourceAndRTCTrack(MediaStreamTrack&);
170 RefPtr<RealtimeMediaSource> sourceFromNewReceiver(webrtc::RtpReceiverInterface&);
171
172#if !RELEASE_LOG_DISABLED
173 const Logger& logger() const final { return m_logger.get(); }
174 const void* logIdentifier() const final { return m_logIdentifier; }
175 const char* logClassName() const final { return "LibWebRTCMediaEndpoint"; }
176 WTFLogChannel& logChannel() const final;
177
178 Seconds statsLogInterval(int64_t) const;
179#endif
180
181 LibWebRTCPeerConnectionBackend& m_peerConnectionBackend;
182 webrtc::PeerConnectionFactoryInterface& m_peerConnectionFactory;
183 rtc::scoped_refptr<webrtc::PeerConnectionInterface> m_backend;
184
185 friend CreateSessionDescriptionObserver<LibWebRTCMediaEndpoint>;
186 friend SetLocalSessionDescriptionObserver<LibWebRTCMediaEndpoint>;
187 friend SetRemoteSessionDescriptionObserver<LibWebRTCMediaEndpoint>;
188
189 CreateSessionDescriptionObserver<LibWebRTCMediaEndpoint> m_createSessionDescriptionObserver;
190 SetLocalSessionDescriptionObserver<LibWebRTCMediaEndpoint> m_setLocalSessionDescriptionObserver;
191 SetRemoteSessionDescriptionObserver<LibWebRTCMediaEndpoint> m_setRemoteSessionDescriptionObserver;
192
193 HashMap<String, RefPtr<MediaStream>> m_remoteStreamsById;
194 HashMap<MediaStreamTrack*, Vector<String>> m_remoteStreamsFromRemoteTrack;
195
196 bool m_isInitiator { false };
197 Timer m_statsLogTimer;
198
199 HashMap<String, rtc::scoped_refptr<webrtc::MediaStreamInterface>> m_localStreams;
200
201#if !RELEASE_LOG_DISABLED
202 int64_t m_statsFirstDeliveredTimestamp { 0 };
203 Ref<const Logger> m_logger;
204 const void* m_logIdentifier;
205#endif
206};
207
208} // namespace WebCore
209
210#endif // USE(LIBWEBRTC)
211