WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-167289-20170126175652.patch (text/plain), 50.98 KB, created by
youenn fablet
on 2017-01-26 17:58:55 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2017-01-26 17:58:55 PST
Size:
50.98 KB
patch
obsolete
>Subversion Revision: 211224 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 5a48a45dc1449017a32e618f58c2864cd316c8f4..2d6389049ebadc036dc71bdf0587ac09cc312adf 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,71 @@ >+2017-01-26 Youenn Fablet <youennf@gmail.com> >+ >+ [WebRTC] Implement WebRTC PeerConnection backend based on libwebrtc >+ https://bugs.webkit.org/show_bug.cgi?id=167289 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Introducing an initial implementation of WebRTC peer connection backend based on LibWebRTC. >+ This is done behind a compilation flag which is off by default, until the implementation is ready. >+ >+ The backend implements the PeerConnectionBackend API. >+ The implementation is split into LibWebRTCPeerConnectionBackend which contains mostly generic code and >+ passes the real work to LibWebRTCMediaEndpoint. >+ The latter class is implementing the API using LibWebRTC. >+ >+ * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp: Added. >+ (WebCore::LibWebRTCMediaEndpoint::LibWebRTCMediaEndpoint): >+ (WebCore::sessionDescriptionType): >+ (WebCore::LibWebRTCMediaEndpoint::doSetLocalDescription): >+ (WebCore::LibWebRTCMediaEndpoint::doSetRemoteDescription): >+ (WebCore::LibWebRTCMediaEndpoint::addPendingIceCandidates): >+ (WebCore::streamId): >+ (WebCore::LibWebRTCMediaEndpoint::doCreateOffer): >+ (WebCore::LibWebRTCMediaEndpoint::doCreateAnswer): >+ (WebCore::LibWebRTCMediaEndpoint::getStats): >+ (WebCore::LibWebRTCMediaEndpoint::StatsCollector::StatsCollector): >+ (WebCore::LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered): >+ (WebCore::signalingState): >+ (WebCore::LibWebRTCMediaEndpoint::OnSignalingChange): >+ (WebCore::trackId): >+ (WebCore::createMediaStreamTrack): >+ (WebCore::LibWebRTCMediaEndpoint::addStream): >+ (WebCore::LibWebRTCMediaEndpoint::OnAddStream): >+ (WebCore::LibWebRTCMediaEndpoint::OnRemoveStream): >+ (WebCore::LibWebRTCMediaEndpoint::OnDataChannel): >+ (WebCore::LibWebRTCMediaEndpoint::stop): >+ (WebCore::LibWebRTCMediaEndpoint::OnRenegotiationNeeded): >+ (WebCore::iceConnectionState): >+ (WebCore::LibWebRTCMediaEndpoint::OnIceConnectionChange): >+ (WebCore::LibWebRTCMediaEndpoint::OnIceGatheringChange): >+ (WebCore::LibWebRTCMediaEndpoint::OnIceCandidate): >+ (WebCore::LibWebRTCMediaEndpoint::OnIceCandidatesRemoved): >+ (WebCore::LibWebRTCMediaEndpoint::createSessionDescriptionSucceeded): >+ (WebCore::LibWebRTCMediaEndpoint::createSessionDescriptionFailed): >+ (WebCore::LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded): >+ (WebCore::LibWebRTCMediaEndpoint::setLocalSessionDescriptionFailed): >+ (WebCore::LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded): >+ (WebCore::LibWebRTCMediaEndpoint::setRemoteSessionDescriptionFailed): >+ * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h: Added. >+ * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp: Added. >+ (WebCore::createLibWebRTCPeerConnectionBackend): >+ (WebCore::libWebRTCProvider): >+ (WebCore::LibWebRTCPeerConnectionBackend::LibWebRTCPeerConnectionBackend): >+ (WebCore::configurationFromMediaEndpointConfiguration): >+ (WebCore::LibWebRTCPeerConnectionBackend::setConfiguration): >+ (WebCore::LibWebRTCPeerConnectionBackend::getStats): >+ (WebCore::LibWebRTCPeerConnectionBackend::doSetLocalDescription): >+ (WebCore::LibWebRTCPeerConnectionBackend::doSetRemoteDescription): >+ (WebCore::LibWebRTCPeerConnectionBackend::doCreateOffer): >+ (WebCore::LibWebRTCPeerConnectionBackend::doCreateAnswer): >+ (WebCore::LibWebRTCPeerConnectionBackend::doStop): >+ (WebCore::LibWebRTCPeerConnectionBackend::doAddIceCandidate): >+ (WebCore::LibWebRTCPeerConnectionBackend::markAsNeedingNegotiation): >+ (WebCore::LibWebRTCPeerConnectionBackend::createReceiver): >+ (WebCore::LibWebRTCPeerConnectionBackend::createDataChannelHandler): >+ * Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h: Added. >+ * WebCore.xcodeproj/project.pbxproj: >+ > 2017-01-26 Zalan Bujtas <zalan@apple.com> > > Simple line layout: Add support for -webkit-hyphenate-limit-after and -webkit-hyphenate-limit-before >diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..c4f40631d6349dff04bb4378d3d178bc8d4d5956 >--- /dev/null >+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp >@@ -0,0 +1,449 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON >+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "LibWebRTCMediaEndpoint.h" >+ >+#if USE(LIBWEBRTC) >+ >+#include "EventNames.h" >+#include "LibWebRTCPeerConnectionBackend.h" >+#include "LibWebRTCProvider.h" >+#include "LibWebRTCUtils.h" >+#include "MediaStreamEvent.h" >+#include "NotImplemented.h" >+#include "PlatformStrategies.h" >+#include "RTCDataChannel.h" >+#include "RTCDataChannelEvent.h" >+#include "RTCIceCandidate.h" >+#include "RTCPeerConnection.h" >+#include "RTCSessionDescription.h" >+#include "RTCTrackEvent.h" >+#include "RealtimeIncomingAudioSource.h" >+#include "RealtimeIncomingVideoSource.h" >+#include <webrtc/api/peerconnectionfactory.h> >+#include <webrtc/base/physicalsocketserver.h> >+#include <webrtc/p2p/base/basicpacketsocketfactory.h> >+#include <webrtc/p2p/client/basicportallocator.h> >+#include <wtf/MainThread.h> >+ >+#include "CoreMediaSoftLink.h" >+ >+namespace WebCore { >+ >+LibWebRTCMediaEndpoint::LibWebRTCMediaEndpoint(LibWebRTCPeerConnectionBackend& peerConnection, LibWebRTCProvider& client) >+ : m_peerConnectionBackend(peerConnection) >+ , m_backend(client.createPeerConnection(*this)) >+ , m_createSessionDescriptionObserver(*this) >+ , m_setLocalSessionDescriptionObserver(*this) >+ , m_setRemoteSessionDescriptionObserver(*this) >+{ >+ ASSERT(m_backend); >+} >+ >+static inline const char* sessionDescriptionType(RTCSessionDescription::SdpType sdpType) >+{ >+ switch (sdpType) { >+ case RTCSessionDescription::SdpType::Offer: >+ return "offer"; >+ case RTCSessionDescription::SdpType::Pranswer: >+ return "pranswer"; >+ case RTCSessionDescription::SdpType::Answer: >+ return "answer"; >+ case RTCSessionDescription::SdpType::Rollback: >+ return "rollback"; >+ } >+} >+ >+void LibWebRTCMediaEndpoint::doSetLocalDescription(RTCSessionDescription& description) >+{ >+ webrtc::SdpParseError error; >+ std::unique_ptr<webrtc::SessionDescriptionInterface> sessionDescription(webrtc::CreateSessionDescription(sessionDescriptionType(description.type()), description.sdp().utf8().data(), &error)); >+ >+ if (!sessionDescription) { >+ String errorMessage(error.description.data(), error.description.size()); >+ m_peerConnectionBackend.setLocalDescriptionFailed(Exception { OperationError, WTFMove(errorMessage) }); >+ return; >+ } >+ m_backend->SetLocalDescription(&m_setLocalSessionDescriptionObserver, sessionDescription.release()); >+} >+ >+void LibWebRTCMediaEndpoint::doSetRemoteDescription(RTCSessionDescription& description) >+{ >+ webrtc::SdpParseError error; >+ std::unique_ptr<webrtc::SessionDescriptionInterface> sessionDescription(webrtc::CreateSessionDescription(sessionDescriptionType(description.type()), description.sdp().utf8().data(), &error)); >+ if (!sessionDescription) { >+ String errorMessage(error.description.data(), error.description.size()); >+ m_peerConnectionBackend.setRemoteDescriptionFailed(Exception { OperationError, WTFMove(errorMessage) }); >+ return; >+ } >+ m_backend->SetRemoteDescription(&m_setRemoteSessionDescriptionObserver, sessionDescription.release()); >+} >+ >+void LibWebRTCMediaEndpoint::addPendingIceCandidates() >+{ >+ while (m_pendingCandidates.size()) >+ m_backend->AddIceCandidate(m_pendingCandidates.takeLast().release()); >+} >+ >+static inline std::string streamId(RTCPeerConnection& connection) >+{ >+ auto& senders = connection.getSenders(); >+ if (senders.size()) { >+ for (RTCRtpSender& sender : senders) { >+ auto* track = sender.track(); >+ if (track) { >+ ASSERT(sender.mediaStreamIds().size() == 1); >+ return std::string(sender.mediaStreamIds().first().utf8().data()); >+ } >+ } >+ } >+ return "av_label"; >+} >+ >+void LibWebRTCMediaEndpoint::doCreateOffer() >+{ >+ m_isInitiator = true; >+ auto& senders = m_peerConnectionBackend.connection().getSenders(); >+ if (senders.size()) { >+ // FIXME: We only support one stream for the moment. >+ auto stream = peerConnectionFactory().CreateLocalMediaStream(streamId(m_peerConnectionBackend.connection())); >+ for (RTCRtpSender& sender : senders) { >+ auto* track = sender.track(); >+ if (track) { >+ ASSERT(sender.mediaStreamIds().size() == 1); >+ auto& source = track->source(); >+ if (source.type() == RealtimeMediaSource::Audio) { >+ auto trackSource = RealtimeOutgoingAudioSource::create(source); >+ auto rtcTrack = peerConnectionFactory().CreateAudioTrack(track->id().utf8().data(), trackSource.ptr()); >+ trackSource->setTrack(rtc::scoped_refptr<webrtc::AudioTrackInterface>(rtcTrack)); >+ m_audioSources.append(WTFMove(trackSource)); >+ stream->AddTrack(WTFMove(rtcTrack)); >+ } else { >+ m_videoSources.append(RealtimeOutgoingVideoSource::create(source)); >+ stream->AddTrack(peerConnectionFactory().CreateVideoTrack(track->id().utf8().data(), m_videoSources.last().ptr())); >+ } >+ } >+ } >+ m_backend->AddStream(stream); >+ } >+ m_backend->CreateOffer(&m_createSessionDescriptionObserver, nullptr); >+} >+ >+void LibWebRTCMediaEndpoint::doCreateAnswer() >+{ >+ m_isInitiator = false; >+ >+ auto& senders = m_peerConnectionBackend.connection().getSenders(); >+ if (senders.size()) { >+ // FIXME: We only support one stream for the moment. >+ auto stream = peerConnectionFactory().CreateLocalMediaStream(streamId(m_peerConnectionBackend.connection())); >+ for (RTCRtpSender& sender : senders) { >+ auto* track = sender.track(); >+ if (track) { >+ ASSERT(sender.mediaStreamIds().size() == 1); >+ auto& source = track->source(); >+ if (source.type() == RealtimeMediaSource::Audio) { >+ auto trackSource = RealtimeOutgoingAudioSource::create(source); >+ auto rtcTrack = peerConnectionFactory().CreateAudioTrack(track->id().utf8().data(), trackSource.ptr()); >+ trackSource->setTrack(rtc::scoped_refptr<webrtc::AudioTrackInterface>(rtcTrack)); >+ m_audioSources.append(WTFMove(trackSource)); >+ stream->AddTrack(WTFMove(rtcTrack)); >+ } else { >+ m_videoSources.append(RealtimeOutgoingVideoSource::create(source)); >+ stream->AddTrack(peerConnectionFactory().CreateVideoTrack(track->id().utf8().data(), m_videoSources.last().ptr())); >+ } >+ } >+ } >+ m_backend->AddStream(stream); >+ } >+ m_backend->CreateAnswer(&m_createSessionDescriptionObserver, nullptr); >+} >+ >+void LibWebRTCMediaEndpoint::getStats(MediaStreamTrack* track, PeerConnection::StatsPromise&& promise) >+{ >+ auto collector = StatsCollector::create(*this, WTFMove(promise), track); >+ m_backend->GetStats(collector.ptr()); >+ m_statsCollectors.append(WTFMove(collector)); >+} >+ >+LibWebRTCMediaEndpoint::StatsCollector::StatsCollector(LibWebRTCMediaEndpoint& endpoint, PeerConnection::StatsPromise&& promise, MediaStreamTrack* track) >+ : m_endpoint(endpoint) >+ , m_promise(WTFMove(promise)) >+{ >+ if (track) >+ m_id = track->id(); >+} >+ >+void LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>& report) >+{ >+ callOnMainThread([this, report, protector = makeRef(m_endpoint)] { >+ // FIXME: Fulfill promise with the report >+ UNUSED_PARAM(report); >+ m_promise.reject(TypeError, ASCIILiteral("Stats API is not yet implemented")); >+ >+ m_endpoint.m_statsCollectors.removeFirstMatching([this](const Ref<StatsCollector>& collector) { >+ return this == collector.ptr(); >+ }); >+ }); >+} >+ >+static PeerConnectionStates::SignalingState signalingState(webrtc::PeerConnectionInterface::SignalingState state) >+{ >+ switch (state) { >+ case webrtc::PeerConnectionInterface::kStable: >+ return PeerConnectionStates::SignalingState::Stable; >+ case webrtc::PeerConnectionInterface::kHaveLocalOffer: >+ return PeerConnectionStates::SignalingState::HaveLocalOffer; >+ case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer: >+ return PeerConnectionStates::SignalingState::HaveLocalPrAnswer; >+ case webrtc::PeerConnectionInterface::kHaveRemoteOffer: >+ return PeerConnectionStates::SignalingState::HaveRemoteOffer; >+ case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer: >+ return PeerConnectionStates::SignalingState::HaveRemotePrAnswer; >+ case webrtc::PeerConnectionInterface::kClosed: >+ return PeerConnectionStates::SignalingState::Closed; >+ } >+} >+ >+void LibWebRTCMediaEndpoint::OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState rtcState) >+{ >+ auto state = signalingState(rtcState); >+ callOnMainThread([protectedThis = makeRef(*this), state] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->m_peerConnectionBackend.updateSignalingState(state); >+ }); >+} >+ >+static inline String trackId(webrtc::MediaStreamTrackInterface& videoTrack) >+{ >+ return String(videoTrack.id().data(), videoTrack.id().size()); >+} >+ >+static inline Ref<MediaStreamTrack> createMediaStreamTrack(ScriptExecutionContext& context, Ref<RealtimeMediaSource>&& remoteSource) >+{ >+ String trackId = remoteSource->id(); >+ return MediaStreamTrack::create(context, MediaStreamTrackPrivate::create(WTFMove(remoteSource), WTFMove(trackId))); >+} >+ >+void LibWebRTCMediaEndpoint::addStream(webrtc::MediaStreamInterface& stream) >+{ >+ MediaStreamTrackVector tracks; >+ for (auto& videoTrack : stream.GetVideoTracks()) { >+ ASSERT(videoTrack); >+ String id = trackId(*videoTrack); >+ auto remoteSource = RealtimeIncomingVideoSource::create(WTFMove(videoTrack), WTFMove(id)); >+ tracks.append(createMediaStreamTrack(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(remoteSource))); >+ } >+ for (auto& audioTrack : stream.GetAudioTracks()) { >+ ASSERT(audioTrack); >+ String id = trackId(*audioTrack); >+ auto remoteSource = RealtimeIncomingAudioSource::create(WTFMove(audioTrack), WTFMove(id)); >+ tracks.append(createMediaStreamTrack(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(remoteSource))); >+ } >+ >+ auto newStream = MediaStream::create(*m_peerConnectionBackend.connection().scriptExecutionContext(), WTFMove(tracks)); >+ m_peerConnectionBackend.connection().fireEvent(MediaStreamEvent::create(eventNames().addstreamEvent, false, false, newStream.copyRef())); >+ >+ Vector<RefPtr<MediaStream>> streams; >+ streams.append(newStream.copyRef()); >+ for (auto& track : newStream->getTracks()) >+ m_peerConnectionBackend.connection().fireEvent(RTCTrackEvent::create(eventNames().trackEvent, false, false, nullptr, track.get(), Vector<RefPtr<MediaStream>>(streams), nullptr)); >+} >+ >+void LibWebRTCMediaEndpoint::OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream) >+{ >+ callOnMainThread([protectedThis = makeRef(*this), stream = WTFMove(stream)] { >+ if (protectedThis->isStopped()) >+ return; >+ ASSERT(stream); >+ protectedThis->addStream(*stream.get()); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) >+{ >+ ASSERT_NOT_REACHED(); >+} >+ >+void LibWebRTCMediaEndpoint::OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel) >+{ >+ callOnMainThread([protectedThis = makeRef(*this), dataChannel = WTFMove(dataChannel)] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->addDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>(dataChannel)); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::stop() >+{ >+ ASSERT(m_backend); >+ m_backend->Close(); >+ m_backend = nullptr; >+} >+ >+void LibWebRTCMediaEndpoint::OnRenegotiationNeeded() >+{ >+ notImplemented(); >+} >+ >+static inline PeerConnectionStates::IceConnectionState iceConnectionState(webrtc::PeerConnectionInterface::IceConnectionState state) >+{ >+ switch (state) { >+ case webrtc::PeerConnectionInterface::kIceConnectionNew: >+ return PeerConnectionStates::IceConnectionState::New; >+ case webrtc::PeerConnectionInterface::kIceConnectionChecking: >+ return PeerConnectionStates::IceConnectionState::Checking; >+ case webrtc::PeerConnectionInterface::kIceConnectionConnected: >+ return PeerConnectionStates::IceConnectionState::Connected; >+ case webrtc::PeerConnectionInterface::kIceConnectionCompleted: >+ return PeerConnectionStates::IceConnectionState::Completed; >+ case webrtc::PeerConnectionInterface::kIceConnectionFailed: >+ return PeerConnectionStates::IceConnectionState::Failed; >+ case webrtc::PeerConnectionInterface::kIceConnectionDisconnected: >+ return PeerConnectionStates::IceConnectionState::Disconnected; >+ case webrtc::PeerConnectionInterface::kIceConnectionClosed: >+ return PeerConnectionStates::IceConnectionState::Closed; >+ case webrtc::PeerConnectionInterface::kIceConnectionMax: >+ ASSERT_NOT_REACHED(); >+ return PeerConnectionStates::IceConnectionState::New; >+ } >+} >+ >+void LibWebRTCMediaEndpoint::OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState state) >+{ >+ auto connectionState = iceConnectionState(state); >+ callOnMainThread([protectedThis = makeRef(*this), connectionState] { >+ if (protectedThis->isStopped()) >+ return; >+ if (protectedThis->m_peerConnectionBackend.connection().internalIceConnectionState() != connectionState) >+ protectedThis->m_peerConnectionBackend.connection().updateIceConnectionState(connectionState); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState state) >+{ >+ if (state == webrtc::PeerConnectionInterface::kIceGatheringComplete) { >+ callOnMainThread([protectedThis = makeRef(*this)] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->m_peerConnectionBackend.doneGatheringCandidates(); >+ }); >+ } >+} >+ >+void LibWebRTCMediaEndpoint::OnIceCandidate(const webrtc::IceCandidateInterface *rtcCandidate) >+{ >+ ASSERT(rtcCandidate); >+ >+ std::string sdp; >+ rtcCandidate->ToString(&sdp); >+ String candidateSDP(sdp.data(), sdp.size()); >+ >+ auto mid = rtcCandidate->sdp_mid(); >+ String candidateMid(mid.data(), mid.size()); >+ >+ callOnMainThread([protectedThis = makeRef(*this), mid = WTFMove(candidateMid), sdp = WTFMove(candidateSDP)] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->m_peerConnectionBackend.fireICECandidateEvent(RTCIceCandidate::create(String(sdp), String(mid), 0)); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::OnIceCandidatesRemoved(const std::vector<cricket::Candidate>&) >+{ >+ ASSERT_NOT_REACHED(); >+} >+ >+void LibWebRTCMediaEndpoint::createSessionDescriptionSucceeded(webrtc::SessionDescriptionInterface* description) >+{ >+ std::string sdp; >+ description->ToString(&sdp); >+ String sdpString(sdp.data(), sdp.size()); >+ >+ callOnMainThread([protectedThis = makeRef(*this), sdp = WTFMove(sdpString)] { >+ if (protectedThis->isStopped()) >+ return; >+ if (protectedThis->m_isInitiator) >+ protectedThis->m_peerConnectionBackend.createOfferSucceeded(String(sdp)); >+ else >+ protectedThis->m_peerConnectionBackend.createAnswerSucceeded(String(sdp)); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::createSessionDescriptionFailed(const std::string& errorMessage) >+{ >+ String error(errorMessage.data(), errorMessage.size()); >+ callOnMainThread([protectedThis = makeRef(*this), error = WTFMove(error)] { >+ if (protectedThis->isStopped()) >+ return; >+ if (protectedThis->m_isInitiator) >+ protectedThis->m_peerConnectionBackend.createOfferFailed(Exception { OperationError, String(error) }); >+ else >+ protectedThis->m_peerConnectionBackend.createAnswerFailed(Exception { OperationError, String(error) }); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded() >+{ >+ callOnMainThread([protectedThis = makeRef(*this)] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->m_peerConnectionBackend.setLocalDescriptionSucceeded(); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::setLocalSessionDescriptionFailed(const std::string& errorMessage) >+{ >+ String error(errorMessage.data(), errorMessage.size()); >+ callOnMainThread([protectedThis = makeRef(*this), error = WTFMove(error)] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->m_peerConnectionBackend.setLocalDescriptionFailed(Exception { OperationError, String(error) }); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded() >+{ >+ callOnMainThread([protectedThis = makeRef(*this)] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->m_peerConnectionBackend.setRemoteDescriptionSucceeded(); >+ }); >+} >+ >+void LibWebRTCMediaEndpoint::setRemoteSessionDescriptionFailed(const std::string& errorMessage) >+{ >+ String error(errorMessage.data(), errorMessage.size()); >+ callOnMainThread([protectedThis = makeRef(*this), error = WTFMove(error)] { >+ if (protectedThis->isStopped()) >+ return; >+ protectedThis->m_peerConnectionBackend.setRemoteDescriptionFailed(Exception { OperationError, String(error) }); >+ }); >+} >+ >+} // namespace WebCore >+ >+#endif // USE(LIBWEBRTC) >diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h >new file mode 100644 >index 0000000000000000000000000000000000000000..74a50cf0bc57c0da106b2baa52fe6fc241ae4f83 >--- /dev/null >+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h >@@ -0,0 +1,176 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON >+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(LIBWEBRTC) >+ >+#include "LibWebRTCUtils.h" >+#include "PeerConnectionBackend.h" >+#include "RealtimeOutgoingAudioSource.h" >+#include "RealtimeOutgoingVideoSource.h" >+ >+#include <webrtc/api/jsep.h> >+#include <webrtc/api/peerconnectionfactory.h> >+#include <webrtc/api/peerconnectioninterface.h> >+#include <webrtc/api/rtcstatscollector.h> >+ >+namespace webrtc { >+class CreateSessionDescriptionObserver; >+class DataChannelInterface; >+class IceCandidateInterface; >+class MediaStreamInterface; >+class PeerConnectionObserver; >+class SessionDescriptionInterface; >+class SetSessionDescriptionObserver; >+} >+ >+namespace WebCore { >+ >+class LibWebRTCProvider; >+class LibWebRTCPeerConnectionBackend; >+class MediaStreamTrack; >+class RTCSessionDescription; >+ >+class LibWebRTCMediaEndpoint final : public RefCounted<LibWebRTCMediaEndpoint>, private webrtc::PeerConnectionObserver { >+public: >+ static Ref<LibWebRTCMediaEndpoint> create(LibWebRTCPeerConnectionBackend& peerConnection, LibWebRTCProvider& client) { return adoptRef(*new LibWebRTCMediaEndpoint(peerConnection, client)); } >+ virtual ~LibWebRTCMediaEndpoint() { } >+ >+ webrtc::PeerConnectionInterface& backend() const { ASSERT(m_backend); return *m_backend.get(); } >+ void doSetLocalDescription(RTCSessionDescription&); >+ void doSetRemoteDescription(RTCSessionDescription&); >+ void doCreateOffer(); >+ void doCreateAnswer(); >+ void getStats(MediaStreamTrack*, PeerConnection::StatsPromise&&); >+ >+ void storeIceCandidate(std::unique_ptr<webrtc::IceCandidateInterface>&& candidate) { m_pendingCandidates.append(WTFMove(candidate)); } >+ void addPendingIceCandidates(); >+ >+ void stop(); >+ >+private: >+ LibWebRTCMediaEndpoint(LibWebRTCPeerConnectionBackend&, LibWebRTCProvider&); >+ >+ // webrtc::PeerConnectionObserver API >+ void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState) final; >+ void OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) final; >+ void OnRemoveStream(rtc::scoped_refptr<webrtc::MediaStreamInterface>) final; >+ void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>) final; >+ void OnRenegotiationNeeded() final; >+ void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState) final; >+ void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState) final; >+ void OnIceCandidate(const webrtc::IceCandidateInterface*) final; >+ void OnIceCandidatesRemoved(const std::vector<cricket::Candidate>&) final; >+ >+ void createSessionDescriptionSucceeded(webrtc::SessionDescriptionInterface*); >+ void createSessionDescriptionFailed(const std::string&); >+ void setLocalSessionDescriptionSucceeded(); >+ void setLocalSessionDescriptionFailed(const std::string&); >+ void setRemoteSessionDescriptionSucceeded(); >+ void setRemoteSessionDescriptionFailed(const std::string&); >+ void addStream(webrtc::MediaStreamInterface&); >+ void addDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface>&&); >+ >+ bool isStopped() const { return !m_backend; } >+ >+ int AddRef() const { ref(); return static_cast<int>(refCount()); } >+ int Release() const { deref(); return static_cast<int>(refCount()); } >+ >+ class CreateSessionDescriptionObserver final : public webrtc::CreateSessionDescriptionObserver { >+ public: >+ explicit CreateSessionDescriptionObserver(LibWebRTCMediaEndpoint &endpoint) : m_endpoint(endpoint) { } >+ >+ void OnSuccess(webrtc::SessionDescriptionInterface* sessionDescription) final { m_endpoint.createSessionDescriptionSucceeded(sessionDescription); } >+ void OnFailure(const std::string& error) final { m_endpoint.createSessionDescriptionFailed(error); } >+ >+ int AddRef() const { return m_endpoint.AddRef(); } >+ int Release() const { return m_endpoint.Release(); } >+ >+ private: >+ LibWebRTCMediaEndpoint& m_endpoint; >+ }; >+ >+ class SetLocalSessionDescriptionObserver final : public webrtc::SetSessionDescriptionObserver { >+ public: >+ explicit SetLocalSessionDescriptionObserver(LibWebRTCMediaEndpoint &endpoint) : m_endpoint(endpoint) { } >+ >+ void OnSuccess() final { m_endpoint.setLocalSessionDescriptionSucceeded(); } >+ void OnFailure(const std::string& error) final { m_endpoint.setLocalSessionDescriptionFailed(error); } >+ >+ int AddRef() const { return m_endpoint.AddRef(); } >+ int Release() const { return m_endpoint.Release(); } >+ >+ private: >+ LibWebRTCMediaEndpoint& m_endpoint; >+ }; >+ >+ class SetRemoteSessionDescriptionObserver final : public webrtc::SetSessionDescriptionObserver { >+ public: >+ explicit SetRemoteSessionDescriptionObserver(LibWebRTCMediaEndpoint &endpoint) : m_endpoint(endpoint) { } >+ >+ void OnSuccess() final { m_endpoint.setRemoteSessionDescriptionSucceeded(); } >+ void OnFailure(const std::string& error) final { m_endpoint.setRemoteSessionDescriptionFailed(error); } >+ >+ int AddRef() const { return m_endpoint.AddRef(); } >+ int Release() const { return m_endpoint.Release(); } >+ >+ private: >+ LibWebRTCMediaEndpoint& m_endpoint; >+ }; >+ >+ class StatsCollector final : public RefCounted<StatsCollector>, public webrtc::RTCStatsCollectorCallback { >+ public: >+ static Ref<StatsCollector> create(LibWebRTCMediaEndpoint& endpoint, PeerConnection::StatsPromise&& promise, MediaStreamTrack* track) { return adoptRef(* new StatsCollector(endpoint, WTFMove(promise), track)); } >+ private: >+ StatsCollector(LibWebRTCMediaEndpoint&, PeerConnection::StatsPromise&&, MediaStreamTrack*); >+ >+ void OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>&) final; >+ >+ int AddRef() const final { ref(); return static_cast<int>(refCount()); } >+ int Release() const final { deref(); return static_cast<int>(refCount()); } >+ >+ LibWebRTCMediaEndpoint& m_endpoint; >+ PeerConnection::StatsPromise m_promise; >+ String m_id; >+ }; >+ >+ LibWebRTCPeerConnectionBackend& m_peerConnectionBackend; >+ rtc::scoped_refptr<webrtc::PeerConnectionInterface> m_backend; >+ >+ CreateSessionDescriptionObserver m_createSessionDescriptionObserver; >+ SetLocalSessionDescriptionObserver m_setLocalSessionDescriptionObserver; >+ SetRemoteSessionDescriptionObserver m_setRemoteSessionDescriptionObserver; >+ >+ bool m_isInitiator { false }; >+ >+ Vector<std::unique_ptr<webrtc::IceCandidateInterface>> m_pendingCandidates; >+ Vector<Ref<RealtimeOutgoingAudioSource>> m_audioSources; >+ Vector<Ref<RealtimeOutgoingVideoSource>> m_videoSources; >+ Vector<Ref<StatsCollector>> m_statsCollectors; >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(LIBWEBRTC) >diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..3fd02183d8981dd066a0d307f536e4cfc6b4ee5c >--- /dev/null >+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.cpp >@@ -0,0 +1,190 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON >+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "LibWebRTCPeerConnectionBackend.h" >+ >+#if USE(LIBWEBRTC) >+ >+#include "Document.h" >+#include "IceCandidate.h" >+#include "LibWebRTCMediaEndpoint.h" >+#include "MediaEndpointConfiguration.h" >+#include "Page.h" >+#include "RTCIceCandidate.h" >+#include "RTCPeerConnection.h" >+#include "RTCRtpReceiver.h" >+#include "RTCSessionDescription.h" >+#include "RealtimeIncomingAudioSource.h" >+#include "RealtimeIncomingVideoSource.h" >+ >+namespace WebCore { >+ >+static std::unique_ptr<PeerConnectionBackend> createLibWebRTCPeerConnectionBackend(RTCPeerConnection& peerConnection) >+{ >+ return std::unique_ptr<PeerConnectionBackend>(new LibWebRTCPeerConnectionBackend(peerConnection)); >+} >+ >+CreatePeerConnectionBackend PeerConnectionBackend::create = createLibWebRTCPeerConnectionBackend; >+ >+static inline LibWebRTCProvider& libWebRTCProvider(RTCPeerConnection& peerConnection) >+{ >+ ASSERT(peerConnection.scriptExecutionContext()->isDocument()); >+ auto* page = static_cast<Document*>(peerConnection.scriptExecutionContext())->page(); >+ return page->libWebRTCProvider(); >+} >+ >+LibWebRTCPeerConnectionBackend::LibWebRTCPeerConnectionBackend(RTCPeerConnection& peerConnection) >+ : PeerConnectionBackend(peerConnection) >+ , m_endpoint(LibWebRTCMediaEndpoint::create(*this, libWebRTCProvider(peerConnection))) >+{ >+} >+ >+static webrtc::PeerConnectionInterface::RTCConfiguration configurationFromMediaEndpointConfiguration(MediaEndpointConfiguration&& configuration) >+{ >+ webrtc::PeerConnectionInterface::RTCConfiguration rtcConfiguration(webrtc::PeerConnectionInterface::RTCConfigurationType::kAggressive); >+ >+ if (configuration.iceTransportPolicy == PeerConnectionStates::IceTransportPolicy::Relay) >+ rtcConfiguration.type = webrtc::PeerConnectionInterface::kRelay; >+ >+ if (configuration.bundlePolicy == PeerConnectionStates::BundlePolicy::MaxBundle) >+ rtcConfiguration.bundle_policy = webrtc::PeerConnectionInterface::kBundlePolicyMaxBundle; >+ else if (configuration.bundlePolicy == PeerConnectionStates::BundlePolicy::MaxCompat) >+ rtcConfiguration.bundle_policy = webrtc::PeerConnectionInterface::kBundlePolicyMaxCompat; >+ >+ for (auto& server : configuration.iceServers) { >+ webrtc::PeerConnectionInterface::IceServer iceServer; >+ iceServer.username = server.username.utf8().data(); >+ iceServer.password = server.credential.utf8().data(); >+ for (auto& url : server.urls) >+ iceServer.urls.push_back({ url.string().utf8().data() }); >+ rtcConfiguration.servers.push_back(WTFMove(iceServer)); >+ } >+ >+ return rtcConfiguration; >+} >+ >+void LibWebRTCPeerConnectionBackend::setConfiguration(MediaEndpointConfiguration&& configuration) >+{ >+ m_endpoint->backend().SetConfiguration(configurationFromMediaEndpointConfiguration(WTFMove(configuration))); >+} >+ >+void LibWebRTCPeerConnectionBackend::getStats(MediaStreamTrack* track, PeerConnection::StatsPromise&& promise) >+{ >+ m_endpoint->getStats(track, WTFMove(promise)); >+} >+ >+void LibWebRTCPeerConnectionBackend::doSetLocalDescription(RTCSessionDescription& description) >+{ >+ m_endpoint->doSetLocalDescription(description); >+ if (!m_isLocalDescriptionSet) { >+ if (m_isRemoteDescriptionSet) >+ m_endpoint->addPendingIceCandidates(); >+ m_isLocalDescriptionSet = true; >+ } >+} >+ >+void LibWebRTCPeerConnectionBackend::doSetRemoteDescription(RTCSessionDescription& description) >+{ >+ m_endpoint->doSetRemoteDescription(description); >+ if (!m_isRemoteDescriptionSet) { >+ if (m_isLocalDescriptionSet) >+ m_endpoint->addPendingIceCandidates(); >+ m_isRemoteDescriptionSet = true; >+ } >+} >+ >+void LibWebRTCPeerConnectionBackend::doCreateOffer(RTCOfferOptions&&) >+{ >+ m_endpoint->doCreateOffer(); >+} >+ >+void LibWebRTCPeerConnectionBackend::doCreateAnswer(RTCAnswerOptions&&) >+{ >+ if (!m_isRemoteDescriptionSet) { >+ createAnswerFailed(Exception { INVALID_STATE_ERR, "No remote description set" }); >+ return; >+ } >+ m_endpoint->doCreateAnswer(); >+} >+ >+void LibWebRTCPeerConnectionBackend::doStop() >+{ >+ m_endpoint->stop(); >+} >+ >+void LibWebRTCPeerConnectionBackend::doAddIceCandidate(RTCIceCandidate& candidate) >+{ >+ if (!m_isRemoteDescriptionSet) { >+ addIceCandidateFailed(Exception { INVALID_STATE_ERR, "No remote description set" }); >+ return; >+ } >+ >+ webrtc::SdpParseError error; >+ int sdpMLineIndex = candidate.sdpMLineIndex() ? candidate.sdpMLineIndex().value() : 0; >+ std::unique_ptr<webrtc::IceCandidateInterface> rtcCandidate(webrtc::CreateIceCandidate(candidate.sdpMid().utf8().data(), sdpMLineIndex, candidate.candidate().utf8().data(), &error)); >+ >+ if (!rtcCandidate) { >+ String message(error.description.data(), error.description.size()); >+ addIceCandidateFailed(Exception { OperationError, WTFMove(message) }); >+ return; >+ } >+ >+ // libwebrtc does not like that ice candidates are set before the description. >+ if (!m_isLocalDescriptionSet || !m_isRemoteDescriptionSet) >+ m_endpoint->storeIceCandidate(WTFMove(rtcCandidate)); >+ else if (!m_endpoint->backend().AddIceCandidate(rtcCandidate.get())) { >+ ASSERT_NOT_REACHED(); >+ addIceCandidateFailed(Exception { OperationError, ASCIILiteral("Failed to apply the received candidate") }); >+ return; >+ } >+ addIceCandidateSucceeded(); >+} >+ >+void LibWebRTCPeerConnectionBackend::markAsNeedingNegotiation() >+{ >+ // FIXME: Implement this >+} >+ >+Ref<RTCRtpReceiver> LibWebRTCPeerConnectionBackend::createReceiver(const String&, const String& trackKind, const String& trackId) >+{ >+ // FIXME: We need to create a source that will get fueled once we will receive OnAddStream. >+ // For the moment, we create an empty one. >+ auto remoteTrackPrivate = (trackKind == "audio") ? MediaStreamTrackPrivate::create(RealtimeIncomingAudioSource::create(nullptr, String(trackId))) : MediaStreamTrackPrivate::create(RealtimeIncomingVideoSource::create(nullptr, String(trackId))); >+ auto remoteTrack = MediaStreamTrack::create(*m_peerConnection.scriptExecutionContext(), WTFMove(remoteTrackPrivate)); >+ >+ return RTCRtpReceiver::create(WTFMove(remoteTrack)); >+} >+ >+std::unique_ptr<RTCDataChannelHandler> LibWebRTCPeerConnectionBackend::createDataChannelHandler(const String& label, const RTCDataChannelInit& options) >+{ >+ UNUSED_PARAM(label); >+ UNUSED_PARAM(options); >+ ASSERT_NOT_REACHED(); >+ return nullptr; >+} >+ >+} // namespace WebCore >+ >+#endif // USE(LIBWEBRTC) >diff --git a/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h >new file mode 100644 >index 0000000000000000000000000000000000000000..06778ab6a3181e51823ecb9cd0919d9c7f26dc05 >--- /dev/null >+++ b/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCPeerConnectionBackend.h >@@ -0,0 +1,84 @@ >+/* >+ * Copyright (C) 2017 Apple Inc. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON >+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS >+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if USE(LIBWEBRTC) >+ >+#include "PeerConnectionBackend.h" >+ >+namespace WebCore { >+ >+class LibWebRTCMediaEndpoint; >+class RTCRtpReceiver; >+class RTCSessionDescription; >+ >+class LibWebRTCPeerConnectionBackend final : public PeerConnectionBackend { >+public: >+ explicit LibWebRTCPeerConnectionBackend(RTCPeerConnection&); >+ >+private: >+ void doCreateOffer(RTCOfferOptions&&) final; >+ void doCreateAnswer(RTCAnswerOptions&&) final; >+ void doSetLocalDescription(RTCSessionDescription&) final; >+ void doSetRemoteDescription(RTCSessionDescription&) final; >+ void doAddIceCandidate(RTCIceCandidate&) final; >+ void doStop() final; >+ std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) final; >+ void setConfiguration(MediaEndpointConfiguration&&) final; >+ void getStats(MediaStreamTrack*, PeerConnection::StatsPromise&&) final; >+ Ref<RTCRtpReceiver> createReceiver(const String& transceiverMid, const String& trackKind, const String& trackId) final; >+ >+ // FIXME: API to implement for real >+ RefPtr<RTCSessionDescription> localDescription() const final { return nullptr; } >+ RefPtr<RTCSessionDescription> currentLocalDescription() const final { return nullptr; } >+ RefPtr<RTCSessionDescription> pendingLocalDescription() const final { return nullptr; } >+ >+ RefPtr<RTCSessionDescription> remoteDescription() const final { return nullptr; } >+ RefPtr<RTCSessionDescription> currentRemoteDescription() const final { return nullptr; } >+ RefPtr<RTCSessionDescription> pendingRemoteDescription() const final { return nullptr; } >+ >+ >+ Vector<RefPtr<MediaStream>> getRemoteStreams() const final { return { }; } >+ >+ void replaceTrack(RTCRtpSender&, RefPtr<MediaStreamTrack>&&, DOMPromise<void>&&) final { } >+ >+ bool isNegotiationNeeded() const final { return false; } >+ void markAsNeedingNegotiation() final; >+ void clearNegotiationNeededState() final { } >+ >+ void emulatePlatformEvent(const String&) final { } >+ >+ friend LibWebRTCMediaEndpoint; >+ RTCPeerConnection& connection() { return m_peerConnection; } >+ >+private: >+ Ref<LibWebRTCMediaEndpoint> m_endpoint; >+ bool m_isLocalDescriptionSet { false }; >+ bool m_isRemoteDescriptionSet { false }; >+}; >+ >+} // namespace WebCore >+ >+#endif // USE(LIBWEBRTC) >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index cc2779ee00c483abd3d6fe72b76e0244e05a5a52..c4a1cea2242f0779bcddb41b395cba16f856a3bc 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -1561,6 +1561,10 @@ > 4170A2EA1D8C0CCA00318452 /* JSDOMWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4170A2E91D8C0CC000318452 /* JSDOMWrapper.cpp */; }; > 417253AA1354BBBC00360F2A /* MediaControlElements.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417253A81354BBBC00360F2A /* MediaControlElements.cpp */; }; > 417253AB1354BBBC00360F2A /* MediaControlElements.h in Headers */ = {isa = PBXBuildFile; fileRef = 417253A91354BBBC00360F2A /* MediaControlElements.h */; }; >+ 417612AF1E3A994000C3D81D /* LibWebRTCMediaEndpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417612AB1E3A993B00C3D81D /* LibWebRTCMediaEndpoint.cpp */; }; >+ 417612B01E3A994000C3D81D /* LibWebRTCMediaEndpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 417612AC1E3A993B00C3D81D /* LibWebRTCMediaEndpoint.h */; }; >+ 417612B11E3A994000C3D81D /* LibWebRTCPeerConnectionBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417612AD1E3A993B00C3D81D /* LibWebRTCPeerConnectionBackend.cpp */; }; >+ 417612B21E3A994000C3D81D /* LibWebRTCPeerConnectionBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 417612AE1E3A993B00C3D81D /* LibWebRTCPeerConnectionBackend.h */; }; > 417DA6D913734E6E007C57FB /* Internals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417DA4CF13734326007C57FB /* Internals.cpp */; }; > 417DA6DA13734E6E007C57FB /* Internals.h in Headers */ = {isa = PBXBuildFile; fileRef = 417DA4CE13734326007C57FB /* Internals.h */; }; > 417DA71D13735DFA007C57FB /* JSInternals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 417DA71B13735DFA007C57FB /* JSInternals.cpp */; }; >@@ -8736,6 +8740,10 @@ > 4170A2E91D8C0CC000318452 /* JSDOMWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDOMWrapper.cpp; sourceTree = "<group>"; }; > 417253A81354BBBC00360F2A /* MediaControlElements.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaControlElements.cpp; sourceTree = "<group>"; }; > 417253A91354BBBC00360F2A /* MediaControlElements.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaControlElements.h; sourceTree = "<group>"; }; >+ 417612AB1E3A993B00C3D81D /* LibWebRTCMediaEndpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCMediaEndpoint.cpp; path = libwebrtc/LibWebRTCMediaEndpoint.cpp; sourceTree = "<group>"; }; >+ 417612AC1E3A993B00C3D81D /* LibWebRTCMediaEndpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCMediaEndpoint.h; path = libwebrtc/LibWebRTCMediaEndpoint.h; sourceTree = "<group>"; }; >+ 417612AD1E3A993B00C3D81D /* LibWebRTCPeerConnectionBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibWebRTCPeerConnectionBackend.cpp; path = libwebrtc/LibWebRTCPeerConnectionBackend.cpp; sourceTree = "<group>"; }; >+ 417612AE1E3A993B00C3D81D /* LibWebRTCPeerConnectionBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCPeerConnectionBackend.h; path = libwebrtc/LibWebRTCPeerConnectionBackend.h; sourceTree = "<group>"; }; > 417DA4CE13734326007C57FB /* Internals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Internals.h; sourceTree = "<group>"; }; > 417DA4CF13734326007C57FB /* Internals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Internals.cpp; sourceTree = "<group>"; }; > 417DA6D013734E02007C57FB /* libWebCoreTestSupport.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libWebCoreTestSupport.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; >@@ -15111,6 +15119,7 @@ > 07221B4617CEC32700848E51 /* mediastream */ = { > isa = PBXGroup; > children = ( >+ 417612AA1E3A992300C3D81D /* libwebrtc */, > 073794ED19EE364200E5A045 /* DOMURLMediaStream.cpp */, > 15FCC9FD1B4DF85600E72326 /* DOMURLMediaStream.h */, > 073794EE19EE364200E5A045 /* DOMURLMediaStream.idl */, >@@ -16660,6 +16669,17 @@ > name = libwebrtc; > sourceTree = "<group>"; > }; >+ 417612AA1E3A992300C3D81D /* libwebrtc */ = { >+ isa = PBXGroup; >+ children = ( >+ 417612AB1E3A993B00C3D81D /* LibWebRTCMediaEndpoint.cpp */, >+ 417612AC1E3A993B00C3D81D /* LibWebRTCMediaEndpoint.h */, >+ 417612AD1E3A993B00C3D81D /* LibWebRTCPeerConnectionBackend.cpp */, >+ 417612AE1E3A993B00C3D81D /* LibWebRTCPeerConnectionBackend.h */, >+ ); >+ name = libwebrtc; >+ sourceTree = "<group>"; >+ }; > 417DA4CD13734204007C57FB /* testing */ = { > isa = PBXGroup; > children = ( >@@ -24970,6 +24990,7 @@ > 319848011A1D817B00A13318 /* AnimationEvent.h in Headers */, > 49E912AD0EFAC906009D0CAF /* AnimationList.h in Headers */, > 31DCD29D1AB4FBDE0072E817 /* AnimationTrigger.h in Headers */, >+ 417612B01E3A994000C3D81D /* LibWebRTCMediaEndpoint.h in Headers */, > 0F580FAF149800D400FB5BD8 /* AnimationUtilities.h in Headers */, > 93309DD7099E64920056E581 /* AppendNodeCommand.h in Headers */, > 7C6579E31E00827000E3A27A /* ApplePayLineItem.h in Headers */, >@@ -27833,6 +27854,7 @@ > A8EA800C0A19516E00A8EF5F /* StyleSheet.h in Headers */, > E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */, > A8EA800A0A19516E00A8EF5F /* StyleSheetList.h in Headers */, >+ 417612B21E3A994000C3D81D /* LibWebRTCPeerConnectionBackend.h in Headers */, > BC5EB5E50E81BF6D00B25965 /* StyleSurroundData.h in Headers */, > BC5EB8100E81F2CE00B25965 /* StyleTransformData.h in Headers */, > E4DEAA1817A93DC3000E0430 /* StyleTreeResolver.h in Headers */, >@@ -29161,6 +29183,7 @@ > E1B4CD2510B322E200BFFD7E /* CredentialStorageMac.mm in Sources */, > 2D481F00146B5C4C00AA7834 /* CrossfadeGeneratedImage.cpp in Sources */, > E1C416170F6563180092D2FB /* CrossOriginAccessControl.cpp in Sources */, >+ 417612B11E3A994000C3D81D /* LibWebRTCPeerConnectionBackend.cpp in Sources */, > 41ABE67C1D0580E0006D862D /* CrossOriginPreflightChecker.cpp in Sources */, > E1C415DE0F655D7C0092D2FB /* CrossOriginPreflightResultCache.cpp in Sources */, > E16980491133644700894115 /* CRuntimeObject.cpp in Sources */, >@@ -30475,6 +30498,7 @@ > B2FA3DBA0AB75A6F000E5AC4 /* JSSVGPathSegArcRel.cpp in Sources */, > B2FA3DBC0AB75A6F000E5AC4 /* JSSVGPathSegClosePath.cpp in Sources */, > B2FA3DBE0AB75A6F000E5AC4 /* JSSVGPathSegCurvetoCubicAbs.cpp in Sources */, >+ 417612AF1E3A994000C3D81D /* LibWebRTCMediaEndpoint.cpp in Sources */, > B2FA3DC00AB75A6F000E5AC4 /* JSSVGPathSegCurvetoCubicRel.cpp in Sources */, > B2FA3DC20AB75A6F000E5AC4 /* JSSVGPathSegCurvetoCubicSmoothAbs.cpp in Sources */, > B2FA3DC40AB75A6F000E5AC4 /* JSSVGPathSegCurvetoCubicSmoothRel.cpp in Sources */,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 167289
:
299459
|
299464
|
299469
|
299859
|
299890
|
299910