From b2018973476ab9056e8f12c994693ade7a3916c9 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Thu, 26 Feb 2015 19:09:42 +0100 Subject: [PATCH 001/155] MediaElement: complete setSrcObject implementation --- Source/WebCore/html/HTMLMediaElement.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 4f5951306445c..fd03424ff56d5 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -119,6 +119,7 @@ #endif #if ENABLE(MEDIA_STREAM) +#include "DOMURL.h" #include "MediaStream.h" #include "MediaStreamRegistry.h" #endif @@ -754,6 +755,7 @@ void HTMLMediaElement::setSrcObject(MediaStream* mediaStream) // https://bugs.webkit.org/show_bug.cgi?id=124896 m_mediaStreamSrcObject = mediaStream; + setSrc(DOMURL::createPublicURL(ActiveDOMObject::scriptExecutionContext(), mediaStream)); } #endif From c8ec607c1c7f295ba0e78f2bff8d3b253e6c05f6 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Mon, 6 Apr 2015 11:22:25 +0200 Subject: [PATCH 002/155] MediaStreamPrivate: dummy tracks() method --- Source/WebCore/platform/mediastream/MediaStreamPrivate.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/WebCore/platform/mediastream/MediaStreamPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamPrivate.h index 39ec6c04293b8..de69c24b34cc9 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamPrivate.h @@ -95,6 +95,9 @@ class MediaStreamPrivate : public RefCounted { void addRemoteTrack(MediaStreamTrackPrivate*); void removeRemoteTrack(MediaStreamTrackPrivate*); + // FIXME: implement this. + Vector> tracks() const { return Vector>(); } + private: MediaStreamPrivate(const String& id, const Vector>& audioSources, const Vector>& videoSources); MediaStreamPrivate(const String& id, const Vector>& audioPrivateTracks, const Vector>& videoPrivateTracks); From 1bfa828f1033ec8a780307324a4985dab13d851a Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Mon, 6 Apr 2015 11:12:49 +0200 Subject: [PATCH 003/155] OpenWebRTC: rendering support --- Source/WebCore/PlatformGTK.cmake | 1 + .../WebCore/platform/graphics/MediaPlayer.cpp | 8 + .../MediaPlayerPrivateGStreamerOwr.cpp | 324 ++++++++++++++++++ .../MediaPlayerPrivateGStreamerOwr.h | 118 +++++++ 4 files changed, 451 insertions(+) create mode 100644 Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp create mode 100644 Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h diff --git a/Source/WebCore/PlatformGTK.cmake b/Source/WebCore/PlatformGTK.cmake index 2105728eca984..f2771425ed6cf 100644 --- a/Source/WebCore/PlatformGTK.cmake +++ b/Source/WebCore/PlatformGTK.cmake @@ -99,6 +99,7 @@ list(APPEND WebCore_SOURCES platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp + platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp platform/graphics/gstreamer/MediaSourceGStreamer.cpp platform/graphics/gstreamer/SourceBufferPrivateGStreamer.cpp platform/graphics/gstreamer/TextCombinerGStreamer.cpp diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp index 3a410fc3d53cd..a2a9fe985a5b1 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.cpp +++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp @@ -53,6 +53,9 @@ #if USE(GSTREAMER) #include "MediaPlayerPrivateGStreamer.h" +#if ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC) +#include "MediaPlayerPrivateGStreamerOwr.h" +#endif #define PlatformMediaEngineClassName MediaPlayerPrivateGStreamer #endif @@ -194,6 +197,11 @@ static void buildMediaEnginesVector() MediaPlayerPrivateQTKit::registerMediaEngine(addMediaEngine); #endif + +#if ENABLE(MEDIA_STREAM) && USE(GSTREAMER) && USE(OPENWEBRTC) + MediaPlayerPrivateGStreamerOwr::registerMediaEngine(addMediaEngine); +#endif + #if defined(PlatformMediaEngineClassName) PlatformMediaEngineClassName::registerMediaEngine(addMediaEngine); #endif diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp new file mode 100644 index 0000000000000..efd14018c38c8 --- /dev/null +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2012 Collabora Ltd. All rights reserved. + * Copyright (C) 2014, 2015 Igalia S.L. All rights reserved. + * Copyright (C) 2015 Metrological All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "config.h" + +#if ENABLE(MEDIA_STREAM) && USE(GSTREAMER) && USE(OPENWEBRTC) +#include "MediaPlayerPrivateGStreamerOwr.h" + +#include "GStreamerUtilities.h" +#include "MediaPlayer.h" +#include "MediaStreamPrivate.h" +#include "NotImplemented.h" +#include "RealtimeMediaSourceOwr.h" +#include "URL.h" +#include +#include +#include +#include +#include + +GST_DEBUG_CATEGORY(webkit_openwebrtc_debug); +#define GST_CAT_DEFAULT webkit_openwebrtc_debug + +namespace WebCore { + +MediaPlayerPrivateGStreamerOwr::MediaPlayerPrivateGStreamerOwr(MediaPlayer* player) + : MediaPlayerPrivateGStreamerBase(player) + , m_paused(true) + , m_stopped(true) +{ + if (isAvailable()) { + LOG_MEDIA_MESSAGE("Creating Stream media player"); + + createVideoSink(); + createGSTAudioSinkBin(); + } +} + +MediaPlayerPrivateGStreamerOwr::~MediaPlayerPrivateGStreamerOwr() +{ + LOG_MEDIA_MESSAGE("Destructing"); + + stop(); +} + +void MediaPlayerPrivateGStreamerOwr::play() +{ + LOG_MEDIA_MESSAGE("Play"); + + if (!m_streamPrivate || !m_streamPrivate->active()) { + m_readyState = MediaPlayer::HaveNothing; + loadingFailed(MediaPlayer::Empty); + return; + } + + m_paused = false; + internalLoad(); +} + +void MediaPlayerPrivateGStreamerOwr::pause() +{ + LOG_MEDIA_MESSAGE("Pause"); + m_paused = true; + stop(); +} + +bool MediaPlayerPrivateGStreamerOwr::hasVideo() const +{ + return m_videoSource; +} + +bool MediaPlayerPrivateGStreamerOwr::hasAudio() const +{ + return m_audioSource; +} + +float MediaPlayerPrivateGStreamerOwr::currentTime() const +{ + gint64 position = GST_CLOCK_TIME_NONE; + GstQuery* query= gst_query_new_position(GST_FORMAT_TIME); + + if (m_videoSource && gst_element_query(m_videoSink.get(), query)) + gst_query_parse_position(query, 0, &position); + else if (m_audioSource && gst_element_query(m_audioSink.get(), query)) + gst_query_parse_position(query, 0, &position); + + float result = 0.0f; + if (static_cast(position) != GST_CLOCK_TIME_NONE) + result = static_cast(position) / GST_SECOND; + + LOG_MEDIA_MESSAGE("Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position)); + gst_query_unref(query); + + return result; +} + +void MediaPlayerPrivateGStreamerOwr::load(const String &url) +{ + notImplemented(); +} + +void MediaPlayerPrivateGStreamerOwr::load(MediaStreamPrivate* streamPrivate) +{ + if (!initializeGStreamer()) + return; + + LOG_MEDIA_MESSAGE("Loading MediaStreamPrivate %p", streamPrivate); + + m_streamPrivate = streamPrivate; + if (!m_streamPrivate || !m_streamPrivate->active()) { + loadingFailed(MediaPlayer::NetworkError); + return; + } + + m_readyState = MediaPlayer::HaveNothing; + m_networkState = MediaPlayer::Loading; + m_player->networkStateChanged(); + m_player->readyStateChanged(); + + if (!internalLoad()) + return; + + // If the stream contains video, wait for first video frame before setting + // HaveEnoughData + if (!hasVideo()) + m_readyState = MediaPlayer::HaveEnoughData; + + m_player->readyStateChanged(); + +} + +void MediaPlayerPrivateGStreamerOwr::loadingFailed(MediaPlayer::NetworkState error) +{ + + if (m_networkState != error) { + m_networkState = error; + m_player->networkStateChanged(); + } + if (m_readyState != MediaPlayer::HaveNothing) { + m_readyState = MediaPlayer::HaveNothing; + m_player->readyStateChanged(); + } +} + +bool MediaPlayerPrivateGStreamerOwr::didLoadingProgress() const +{ + return true; +} + +bool MediaPlayerPrivateGStreamerOwr::internalLoad() +{ + if (!m_stopped) + return false; + + m_stopped = false; + if (!m_streamPrivate || !m_streamPrivate->active()) { + loadingFailed(MediaPlayer::NetworkError); + return false; + } + + LOG_MEDIA_MESSAGE("Connecting to live stream, descriptor: %p", m_streamPrivate.get()); + + for (auto track : m_streamPrivate->tracks()) { + if (!track->enabled()) { + LOG_MEDIA_MESSAGE("Track %s disabled", track->label().ascii().data()); + continue; + } + + RealtimeMediaSourceOwr* source = reinterpret_cast(track->source()); + OwrMediaSource* mediaSource = OWR_MEDIA_SOURCE(source->mediaSource()); + OwrSourceType sourceType; + g_object_get(mediaSource, "type", &sourceType, nullptr); + if ((sourceType & OWR_SOURCE_TYPE_CAPTURE) != OWR_SOURCE_TYPE_CAPTURE) + continue; + + if (track->type() == RealtimeMediaSource::Audio) { + if (m_audioSource && (m_audioSource.get() == source)) + g_object_set(m_audioRenderer, "disabled", FALSE, nullptr); + + owr_media_renderer_set_source(OWR_MEDIA_RENDERER(m_audioRenderer), mediaSource); + m_audioSource = source; + source->addObserver(this); + } else if (track->type() == RealtimeMediaSource::Video) { + if (m_videoSource && (m_videoSource.get() == source)) + g_object_set(m_videoRenderer, "disabled", FALSE, nullptr); + + owr_media_renderer_set_source(OWR_MEDIA_RENDERER(m_videoRenderer), mediaSource); + m_videoSource = source; + source->addObserver(this); + } else + ASSERT_NOT_REACHED(); + } + + m_readyState = MediaPlayer::HaveEnoughData; + m_player->readyStateChanged(); + return true; +} + +void MediaPlayerPrivateGStreamerOwr::stop() +{ + if (m_stopped) + return; + + m_stopped = true; + if (m_audioSource) { + LOG_MEDIA_MESSAGE("Stop: disconnecting audio"); + g_object_set(m_audioRenderer, "disabled", TRUE, nullptr); + } + if (m_videoSource) { + LOG_MEDIA_MESSAGE("Stop: disconnecting video"); + g_object_set(m_videoRenderer, "disabled", TRUE, nullptr); + } +} + +void MediaPlayerPrivateGStreamerOwr::registerMediaEngine(MediaEngineRegistrar registrar) +{ + if (isAvailable()) { + registrar([](MediaPlayer* player) { + return std::make_unique(player); + }, getSupportedTypes, supportsType, 0, 0, 0, 0); + } +} + +void MediaPlayerPrivateGStreamerOwr::getSupportedTypes(HashSet& types) +{ + // FIXME +} + +MediaPlayer::SupportsType MediaPlayerPrivateGStreamerOwr::supportsType(const MediaEngineSupportParameters& parameters) +{ + // FIXME + return MediaPlayer::IsNotSupported; +} + +bool MediaPlayerPrivateGStreamerOwr::isAvailable() +{ + if (!initializeGStreamer()) + return false; + + static bool debugRegistered = false; + if (!debugRegistered) { + GST_DEBUG_CATEGORY_INIT(webkit_openwebrtc_debug, "webkitowrplayer", 0, "WebKit OpenWebRTC player"); + debugRegistered = true; + } + + return true; +} + +void MediaPlayerPrivateGStreamerOwr::createGSTAudioSinkBin() +{ + ASSERT(!m_audioSink); + LOG_MEDIA_MESSAGE("Creating audio sink"); + // FIXME: volume/mute support + + GRefPtr sink = gst_element_factory_make("autoaudiosink", 0); + GstStateChangeReturn stateChangeResult = gst_element_set_state(sink.get(), GST_STATE_READY); + GstChildProxy* childProxy = GST_CHILD_PROXY(sink.get()); + m_audioSink = adoptGRef(GST_ELEMENT(gst_child_proxy_get_child_by_index(childProxy, 0))); + gst_element_set_state(sink.get(), GST_STATE_NULL); + + m_audioRenderer = owr_audio_renderer_new(G_OBJECT(m_audioSink.get())); +} + +void MediaPlayerPrivateGStreamerOwr::sourceReadyStateChanged() +{ + LOG_MEDIA_MESSAGE("Source state changed"); + + if (!m_streamPrivate || !m_streamPrivate->active()) + stop(); + + for (auto track : m_streamPrivate->tracks()) { + RealtimeMediaSourceOwr* source = reinterpret_cast(track->source()); + if (track->enabled()) + continue; + if (source == m_audioSource) + g_object_set(m_audioRenderer, "disabled", TRUE, nullptr); + else if (source == m_videoSource) + g_object_set(m_videoRenderer, "disabled", TRUE, nullptr); + } +} + +void MediaPlayerPrivateGStreamerOwr::sourceMutedChanged() +{ + LOG_MEDIA_MESSAGE("Source muted state changed"); +} + +void MediaPlayerPrivateGStreamerOwr::sourceEnabledChanged() +{ + LOG_MEDIA_MESSAGE("Source enabled state changed"); +} + +bool MediaPlayerPrivateGStreamerOwr::observerIsEnabled() +{ + return true; +} + +GstElement* MediaPlayerPrivateGStreamerOwr::createVideoSink() +{ + GstElement* sink = MediaPlayerPrivateGStreamerBase::createVideoSink(); + m_videoRenderer = owr_video_renderer_new(0, G_OBJECT(sink)); + return nullptr; +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) && USE(GSTREAMER) && USE(OPENWEBRTC) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h new file mode 100644 index 0000000000000..8961e2e211454 --- /dev/null +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2015 Igalia S.L. All rights reserved. + * Copyright (C) 2015 Metrological. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MediaPlayerPrivateGStreamerOwr_h +#define MediaPlayerPrivateGStreamerOwr_h + +#if ENABLE(MEDIA_STREAM) && USE(GSTREAMER) && USE(OPENWEBRTC) + +#include "MediaPlayerPrivateGStreamerBase.h" +#include "RealtimeMediaSource.h" + +typedef struct _OwrVideoRenderer OwrVideoRenderer; +typedef struct _OwrAudioRenderer OwrAudioRenderer; + +namespace WebCore { + +class MediaStreamPrivate; +class RealtimeMediaSourceOwr; +class URL; + +class MediaPlayerPrivateGStreamerOwr : public MediaPlayerPrivateGStreamerBase, private RealtimeMediaSource::Observer { +public: + explicit MediaPlayerPrivateGStreamerOwr(MediaPlayer*); + ~MediaPlayerPrivateGStreamerOwr(); + + static void registerMediaEngine(MediaEngineRegistrar); + virtual String engineDescription() const { return "OpenWebRTC"; } + + virtual void load(const String&); +#if ENABLE(MEDIA_SOURCE) + virtual void load(const String&, MediaSourcePrivateClient*) { } +#endif + virtual void load(MediaStreamPrivate*); + virtual void cancelLoad() { } + + virtual void prepareToPlay() { } + void play(); + void pause(); + + bool hasVideo() const; + bool hasAudio() const; + + virtual float duration() const { return 0; } + + virtual float currentTime() const; + virtual void seek(float) { } + virtual bool seeking() const { return false; } + + virtual void setRate(float) { } + virtual void setPreservesPitch(bool) { } + virtual bool paused() const { return m_paused; } + + virtual bool hasClosedCaptions() const { return false; } + virtual void setClosedCaptionsVisible(bool) { }; + + virtual float maxTimeSeekable() const { return 0; } + virtual std::unique_ptr buffered() const { return std::make_unique(); } + bool didLoadingProgress() const; + + virtual unsigned long long totalBytes() const { return 0; } + virtual unsigned bytesLoaded() const { return 0; } + + virtual bool canLoadPoster() const { return false; } + virtual void setPoster(const String&) { } + + virtual bool isLiveStream() const { return true; } + + // RealtimeMediaSource::Observer implementation + virtual void sourceReadyStateChanged() override final; + virtual void sourceMutedChanged() override final; + virtual void sourceEnabledChanged() override final; + virtual bool observerIsEnabled() override final; + +protected: + virtual GstElement* createVideoSink(); + +private: + static void getSupportedTypes(HashSet&); + static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&); + static bool isAvailable(); + void createGSTAudioSinkBin(); + void loadingFailed(MediaPlayer::NetworkState error); + bool internalLoad(); + void stop(); + virtual GstElement* audioSink() const { return m_audioSink.get(); } + +private: + bool m_paused; + bool m_stopped; + RefPtr m_videoSource; + RefPtr m_audioSource; + GRefPtr m_audioSink; + RefPtr m_streamPrivate; + OwrVideoRenderer* m_videoRenderer; + OwrAudioRenderer* m_audioRenderer; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) && USE(GSTREAMER) && USE(OPENWEBRTC) + +#endif // MediaPlayerPrivateGStreamerOwr_h From 3e5ae70340a28f0c8f9ab6c51d0f8ebffceada20 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 18 Mar 2015 09:58:10 +0100 Subject: [PATCH 004/155] Spec sync: removed Audio/VideoStreamTrack --- Source/WebCore/CMakeLists.txt | 4 -- .../Modules/mediastream/AudioStreamTrack.cpp | 71 ------------------- .../Modules/mediastream/AudioStreamTrack.h | 59 --------------- .../Modules/mediastream/AudioStreamTrack.idl | 31 -------- .../Modules/mediastream/MediaStream.cpp | 10 +-- .../Modules/mediastream/MediaStreamTrack.cpp | 32 ++++++--- .../Modules/mediastream/MediaStreamTrack.h | 11 +-- .../Modules/mediastream/VideoStreamTrack.cpp | 71 ------------------- .../Modules/mediastream/VideoStreamTrack.h | 59 --------------- .../Modules/mediastream/VideoStreamTrack.idl | 32 --------- 10 files changed, 31 insertions(+), 349 deletions(-) delete mode 100644 Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp delete mode 100644 Source/WebCore/Modules/mediastream/AudioStreamTrack.h delete mode 100644 Source/WebCore/Modules/mediastream/AudioStreamTrack.idl delete mode 100644 Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp delete mode 100644 Source/WebCore/Modules/mediastream/VideoStreamTrack.h delete mode 100644 Source/WebCore/Modules/mediastream/VideoStreamTrack.idl diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 98dfd89106aaa..1580931d1f9aa 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -221,7 +221,6 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/AllAudioCapabilities.idl Modules/mediastream/AllVideoCapabilities.idl - Modules/mediastream/AudioStreamTrack.idl Modules/mediastream/CapabilityRange.idl Modules/mediastream/DOMURLMediaStream.idl Modules/mediastream/HTMLMediaElementMediaStream.idl @@ -257,7 +256,6 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/RTCStatsReport.idl Modules/mediastream/RTCStatsResponse.idl Modules/mediastream/SourceInfo.idl - Modules/mediastream/VideoStreamTrack.idl Modules/navigatorcontentutils/NavigatorContentUtils.idl @@ -871,7 +869,6 @@ set(WebCore_SOURCES Modules/mediasource/SourceBufferList.cpp Modules/mediasource/VideoPlaybackQuality.cpp - Modules/mediastream/AudioStreamTrack.cpp Modules/mediastream/CapabilityRange.cpp Modules/mediastream/DOMURLMediaStream.cpp Modules/mediastream/HTMLMediaElementMediaStream.cpp @@ -908,7 +905,6 @@ set(WebCore_SOURCES Modules/mediastream/SourceInfo.cpp Modules/mediastream/UserMediaController.cpp Modules/mediastream/UserMediaRequest.cpp - Modules/mediastream/VideoStreamTrack.cpp Modules/navigatorcontentutils/NavigatorContentUtils.cpp diff --git a/Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp b/Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp deleted file mode 100644 index d8211558caa68..0000000000000 --- a/Source/WebCore/Modules/mediastream/AudioStreamTrack.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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" - -#if ENABLE(MEDIA_STREAM) - -#include "AudioStreamTrack.h" - -#include "Dictionary.h" -#include "ScriptExecutionContext.h" -#include - -namespace WebCore { - -RefPtr AudioStreamTrack::create(ScriptExecutionContext& context, const Dictionary& audioConstraints) -{ - return adoptRef(new AudioStreamTrack(context, *MediaStreamTrackPrivate::create(0), &audioConstraints)); -} - -RefPtr AudioStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) -{ - return adoptRef(new AudioStreamTrack(context, privateTrack, 0)); -} - -RefPtr AudioStreamTrack::create(MediaStreamTrack& track) -{ - return adoptRef(new AudioStreamTrack(track)); -} - -AudioStreamTrack::AudioStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack, const Dictionary* audioConstraints) - : MediaStreamTrack(context, privateTrack, audioConstraints) -{ -} - -AudioStreamTrack::AudioStreamTrack(MediaStreamTrack& track) - : MediaStreamTrack(track) -{ -} - -const AtomicString& AudioStreamTrack::kind() const -{ - static NeverDestroyed audioKind("audio", AtomicString::ConstructFromLiteral); - return audioKind; -} - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/AudioStreamTrack.h b/Source/WebCore/Modules/mediastream/AudioStreamTrack.h deleted file mode 100644 index b6e28f90e89e7..0000000000000 --- a/Source/WebCore/Modules/mediastream/AudioStreamTrack.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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. - */ - -#ifndef AudioStreamTrack_h -#define AudioStreamTrack_h - -#if ENABLE(MEDIA_STREAM) - -#include "MediaStreamTrack.h" -#include -#include - -namespace WebCore { - -class RealtimeMediaSource; -class ScriptExecutionContext; - -class AudioStreamTrack final : public MediaStreamTrack { -public: - static RefPtr create(ScriptExecutionContext&, const Dictionary&); - static RefPtr create(ScriptExecutionContext&, MediaStreamTrackPrivate&); - static RefPtr create(MediaStreamTrack&); - - virtual ~AudioStreamTrack() { } - - virtual const AtomicString& kind() const override; - -private: - AudioStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&, const Dictionary*); - explicit AudioStreamTrack(MediaStreamTrack&); -}; - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) - -#endif // AudioStreamTrack_h diff --git a/Source/WebCore/Modules/mediastream/AudioStreamTrack.idl b/Source/WebCore/Modules/mediastream/AudioStreamTrack.idl deleted file mode 100644 index 469b079993627..0000000000000 --- a/Source/WebCore/Modules/mediastream/AudioStreamTrack.idl +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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. - */ - -[ - Conditional=MEDIA_STREAM, - Constructor(optional Dictionary audioConstraints), - ConstructorCallWith=ScriptExecutionContext, -] interface AudioStreamTrack : MediaStreamTrack { -}; diff --git a/Source/WebCore/Modules/mediastream/MediaStream.cpp b/Source/WebCore/Modules/mediastream/MediaStream.cpp index 6a9ab18c589b6..9fbfb8267e2e1 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStream.cpp @@ -30,13 +30,11 @@ #if ENABLE(MEDIA_STREAM) -#include "AudioStreamTrack.h" #include "Event.h" #include "ExceptionCode.h" #include "MediaStreamRegistry.h" #include "MediaStreamTrackEvent.h" #include "RealtimeMediaSource.h" -#include "VideoStreamTrack.h" #include namespace WebCore { @@ -94,7 +92,7 @@ MediaStream::MediaStream(ScriptExecutionContext& context, PassRefPtrnumberOfAudioTracks(); m_audioTracks.reserveCapacity(numberOfAudioTracks); for (size_t i = 0; i < numberOfAudioTracks; i++) { - track = AudioStreamTrack::create(context, *m_private->audioTracks(i)); + track = MediaStreamTrack::create(context, *m_private->audioTracks(i)); track->addObserver(this); m_audioTracks.append(track.release()); } @@ -102,7 +100,7 @@ MediaStream::MediaStream(ScriptExecutionContext& context, PassRefPtrnumberOfVideoTracks(); m_videoTracks.reserveCapacity(numberOfVideoTracks); for (size_t i = 0; i < numberOfVideoTracks; i++) { - track = VideoStreamTrack::create(context, *m_private->videoTracks(i)); + track = MediaStreamTrack::create(context, *m_private->videoTracks(i)); track->addObserver(this); m_videoTracks.append(track.release()); } @@ -324,10 +322,8 @@ void MediaStream::addRemoteTrack(MediaStreamTrackPrivate* privateTrack) RefPtr track; switch (privateTrack->type()) { case RealtimeMediaSource::Audio: - track = AudioStreamTrack::create(*scriptExecutionContext(), *privateTrack); - break; case RealtimeMediaSource::Video: - track = VideoStreamTrack::create(*scriptExecutionContext(), *privateTrack); + track = MediaStreamTrack::create(*scriptExecutionContext(), *privateTrack); break; case RealtimeMediaSource::None: ASSERT_NOT_REACHED(); diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index d90d58597cd2b..4010e207ce57e 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -32,7 +32,6 @@ #include "AllAudioCapabilities.h" #include "AllVideoCapabilities.h" -#include "AudioStreamTrack.h" #include "Dictionary.h" #include "Event.h" #include "ExceptionCode.h" @@ -46,13 +45,22 @@ #include "MediaTrackConstraints.h" #include "NotImplemented.h" #include "RealtimeMediaSourceCenter.h" -#include "VideoStreamTrack.h" #include #include namespace WebCore { -MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack, const Dictionary* constraints) +RefPtr MediaStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) +{ + return adoptRef(new MediaStreamTrack(context, privateTrack)); +} + +RefPtr MediaStreamTrack::create(MediaStreamTrack& track) +{ + return adoptRef(new MediaStreamTrack(track)); +} + +MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) : RefCounted() , ActiveDOMObject(&context) , m_privateTrack(privateTrack) @@ -62,9 +70,6 @@ MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamT suspendIfNeeded(); m_privateTrack->setClient(this); - - if (constraints) - applyConstraints(*constraints); } MediaStreamTrack::MediaStreamTrack(MediaStreamTrack& other) @@ -89,6 +94,16 @@ void MediaStreamTrack::setSource(PassRefPtr newSource) m_privateTrack->setSource(newSource); } +const AtomicString& MediaStreamTrack::kind() const +{ + static NeverDestroyed audioKind("audio", AtomicString::ConstructFromLiteral); + static NeverDestroyed videoKind("video", AtomicString::ConstructFromLiteral); + + if (m_privateTrack->type() == RealtimeMediaSource::Audio) + return audioKind; + return videoKind; +} + const String& MediaStreamTrack::id() const { return m_privateTrack->id(); @@ -194,10 +209,7 @@ void MediaStreamTrack::applyConstraints(PassRefPtr) RefPtr MediaStreamTrack::clone() { - if (m_privateTrack->type() == RealtimeMediaSource::Audio) - return AudioStreamTrack::create(*this); - - return VideoStreamTrack::create(*this); + return MediaStreamTrack::create(*this); } void MediaStreamTrack::stopProducingData() diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 708f0af7dc52e..cef1f3dfd5f08 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -49,7 +49,7 @@ class MediaStreamTrackSourcesCallback; class MediaStreamCapabilities; class MediaTrackConstraints; -class MediaStreamTrack : public RefCounted, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public MediaStreamTrackPrivateClient { +class MediaStreamTrack final : public RefCounted, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public MediaStreamTrackPrivateClient { public: class Observer { public: @@ -57,9 +57,11 @@ class MediaStreamTrack : public RefCounted, public ScriptWrapp virtual void trackDidEnd() = 0; }; + static RefPtr create(ScriptExecutionContext&, MediaStreamTrackPrivate&); + static RefPtr create(MediaStreamTrack&); virtual ~MediaStreamTrack(); - virtual const AtomicString& kind() const = 0; + const AtomicString& kind() const; const String& id() const; const String& label() const; @@ -99,13 +101,12 @@ class MediaStreamTrack : public RefCounted, public ScriptWrapp using RefCounted::ref; using RefCounted::deref; -protected: +private: + MediaStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&); explicit MediaStreamTrack(MediaStreamTrack&); - MediaStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&, const Dictionary*); void setSource(PassRefPtr); -private: void configureTrackRendering(); void trackDidEnd(); void scheduleEventDispatch(PassRefPtr); diff --git a/Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp b/Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp deleted file mode 100644 index e067d96313564..0000000000000 --- a/Source/WebCore/Modules/mediastream/VideoStreamTrack.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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" - -#if ENABLE(MEDIA_STREAM) - -#include "VideoStreamTrack.h" - -#include "Dictionary.h" -#include "ScriptExecutionContext.h" -#include - -namespace WebCore { - -RefPtr VideoStreamTrack::create(ScriptExecutionContext& context, const Dictionary& videoConstraints) -{ - return adoptRef(new VideoStreamTrack(context, *MediaStreamTrackPrivate::create(0), &videoConstraints)); -} - -RefPtr VideoStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) -{ - return adoptRef(new VideoStreamTrack(context, privateTrack, 0)); -} - -RefPtr VideoStreamTrack::create(MediaStreamTrack& track) -{ - return adoptRef(new VideoStreamTrack(track)); -} - -VideoStreamTrack::VideoStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack, const Dictionary* videoConstraints) - : MediaStreamTrack(context, privateTrack, videoConstraints) -{ -} - -VideoStreamTrack::VideoStreamTrack(MediaStreamTrack& track) - : MediaStreamTrack(track) -{ -} - -const AtomicString& VideoStreamTrack::kind() const -{ - static NeverDestroyed videoKind("video", AtomicString::ConstructFromLiteral); - return videoKind; -} - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/VideoStreamTrack.h b/Source/WebCore/Modules/mediastream/VideoStreamTrack.h deleted file mode 100644 index ef61e14f330ff..0000000000000 --- a/Source/WebCore/Modules/mediastream/VideoStreamTrack.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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. - */ - -#ifndef VideoStreamTrack_h -#define VideoStreamTrack_h - -#if ENABLE(MEDIA_STREAM) - -#include "MediaStreamTrack.h" -#include -#include - -namespace WebCore { - -class RealtimeMediaSource; -class ScriptExecutionContext; - -class VideoStreamTrack final : public MediaStreamTrack { -public: - static RefPtr create(ScriptExecutionContext&, const Dictionary&); - static RefPtr create(ScriptExecutionContext&, MediaStreamTrackPrivate&); - static RefPtr create(MediaStreamTrack&); - - virtual ~VideoStreamTrack() { } - - virtual const AtomicString& kind() const override; - -private: - VideoStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&, const Dictionary*); - explicit VideoStreamTrack(MediaStreamTrack&); -}; - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) - -#endif // VideoStreamTrack_h diff --git a/Source/WebCore/Modules/mediastream/VideoStreamTrack.idl b/Source/WebCore/Modules/mediastream/VideoStreamTrack.idl deleted file mode 100644 index 321b9bdbf1766..0000000000000 --- a/Source/WebCore/Modules/mediastream/VideoStreamTrack.idl +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2013 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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. - */ - -[ - Conditional=MEDIA_STREAM, - ConstructorCallWith=ScriptExecutionContext, - Constructor(optional Dictionary videoConstraints), -] interface VideoStreamTrack : MediaStreamTrack { -}; - From a81b41d9710d90f4699e691538343b015f4a7b70 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 6 Apr 2015 11:29:15 +0200 Subject: [PATCH 005/155] MediaStream API: Initial import of updated MediaStream API --- .../Modules/mediastream/MediaStream.cpp | 356 ++++++------------ .../WebCore/Modules/mediastream/MediaStream.h | 64 ++-- .../Modules/mediastream/MediaStream.idl | 4 +- .../Modules/mediastream/MediaStreamTrack.cpp | 35 +- .../Modules/mediastream/MediaStreamTrack.h | 6 +- .../Modules/mediastream/MediaStreamTrack.idl | 3 - .../Modules/mediastream/RTCPeerConnection.cpp | 1 - .../mediastream/MediaStreamPrivate.cpp | 167 +++----- .../platform/mediastream/MediaStreamPrivate.h | 60 +-- .../mediastream/MediaStreamTrackPrivate.cpp | 21 +- .../mediastream/MediaStreamTrackPrivate.h | 5 +- .../mediastream/RealtimeMediaSource.cpp | 47 +-- .../mediastream/RealtimeMediaSource.h | 6 +- 13 files changed, 247 insertions(+), 528 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStream.cpp b/Source/WebCore/Modules/mediastream/MediaStream.cpp index 9fbfb8267e2e1..fb8f00a39eed4 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStream.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. - * Copyright (C) 2011, 2012 Ericsson AB. All rights reserved. + * Copyright (C) 2011, 2012, 2015 Ericsson AB. All rights reserved. * Copyright (C) 2013 Apple Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). * @@ -39,70 +39,61 @@ namespace WebCore { -PassRefPtr MediaStream::create(ScriptExecutionContext& context) +RefPtr MediaStream::create(ScriptExecutionContext& context) { - return MediaStream::create(context, MediaStreamPrivate::create(Vector>(), Vector>())); + return MediaStream::create(context, MediaStreamPrivate::create()); } -PassRefPtr MediaStream::create(ScriptExecutionContext& context, PassRefPtr stream) +RefPtr MediaStream::create(ScriptExecutionContext& context, MediaStream* stream) { ASSERT(stream); - Vector> audioTracks; - Vector> videoTracks; - - for (size_t i = 0; i < stream->m_audioTracks.size(); ++i) - audioTracks.append(&stream->m_audioTracks[i]->privateTrack()); - - for (size_t i = 0; i < stream->m_videoTracks.size(); ++i) - videoTracks.append(&stream->m_videoTracks[i]->privateTrack()); - - return MediaStream::create(context, MediaStreamPrivate::create(audioTracks, videoTracks)); + return adoptRef(new MediaStream(context, stream->getTracks())); } -PassRefPtr MediaStream::create(ScriptExecutionContext& context, const Vector>& tracks) +RefPtr MediaStream::create(ScriptExecutionContext& context, const Vector>& tracks) { - Vector> audioTracks; - Vector> videoTracks; - - for (size_t i = 0; i < tracks.size(); ++i) { - if (tracks[i]->kind() == "audio") - audioTracks.append(&tracks[i]->privateTrack()); - else - videoTracks.append(&tracks[i]->privateTrack()); - } - - return MediaStream::create(context, MediaStreamPrivate::create(audioTracks, videoTracks)); + return adoptRef(new MediaStream(context, tracks)); } -PassRefPtr MediaStream::create(ScriptExecutionContext& context, PassRefPtr privateStream) +RefPtr MediaStream::create(ScriptExecutionContext& context, RefPtr&& streamPrivate) { - return adoptRef(new MediaStream(context, privateStream)); + return adoptRef(new MediaStream(context, WTF::move(streamPrivate))); } -MediaStream::MediaStream(ScriptExecutionContext& context, PassRefPtr privateStream) +MediaStream::MediaStream(ScriptExecutionContext& context, const Vector>& tracks) : ContextDestructionObserver(&context) - , m_private(privateStream) - , m_scheduledEventTimer(*this, &MediaStream::scheduledEventTimerFired) + , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired) { - ASSERT(m_private); - m_private->setClient(this); + // This constructor preserves MediaStreamTrack instances and must be used by calls originating + // from the JavaScript MediaStream constructor. + Vector> trackPrivates; + trackPrivates.reserveCapacity(tracks.size()); - RefPtr track; - size_t numberOfAudioTracks = m_private->numberOfAudioTracks(); - m_audioTracks.reserveCapacity(numberOfAudioTracks); - for (size_t i = 0; i < numberOfAudioTracks; i++) { - track = MediaStreamTrack::create(context, *m_private->audioTracks(i)); + for (auto& track : tracks) { track->addObserver(this); - m_audioTracks.append(track.release()); + m_trackSet.add(track->id(), track); + trackPrivates.append(&track->privateTrack()); } - size_t numberOfVideoTracks = m_private->numberOfVideoTracks(); - m_videoTracks.reserveCapacity(numberOfVideoTracks); - for (size_t i = 0; i < numberOfVideoTracks; i++) { - track = MediaStreamTrack::create(context, *m_private->videoTracks(i)); + m_private = MediaStreamPrivate::create(trackPrivates); + m_isActive = m_private->active(); + m_private->setClient(this); +} + +MediaStream::MediaStream(ScriptExecutionContext& context, RefPtr&& streamPrivate) + : ContextDestructionObserver(&context) + , m_private(streamPrivate) + , m_isActive(m_private->active()) + , m_activityEventTimer(*this, &MediaStream::activityEventTimerFired) +{ + ASSERT(m_private); + m_private->setClient(this); + + for (auto& trackPrivate : m_private->tracks()) { + RefPtr track = MediaStreamTrack::create(context, *trackPrivate); track->addObserver(this); - m_videoTracks.append(track.release()); + m_trackSet.add(track->id(), WTF::move(track)); } } @@ -113,256 +104,143 @@ MediaStream::~MediaStream() bool MediaStream::active() const { - return m_private->active(); -} - -void MediaStream::setActive(bool isActive) -{ - if (active() == isActive) - return; - m_private->setActive(isActive); + return m_isActive; } -PassRefPtr MediaStream::clone() +RefPtr MediaStream::clone() { - Vector> trackSet; + Vector> clonedTracks; + clonedTracks.reserveCapacity(m_trackSet.size()); - cloneMediaStreamTrackVector(trackSet, getAudioTracks()); - cloneMediaStreamTrackVector(trackSet, getVideoTracks()); - return MediaStream::create(*scriptExecutionContext(), trackSet); -} + for (auto& track : m_trackSet.values()) + clonedTracks.append(track->clone()); -void MediaStream::cloneMediaStreamTrackVector(Vector>& destination, const Vector>& source) -{ - for (auto it = source.begin(), end = source.end(); it != end; ++it) - destination.append((*it)->clone()); + return MediaStream::create(*scriptExecutionContext(), clonedTracks); } -void MediaStream::addTrack(PassRefPtr prpTrack, ExceptionCode& ec) +void MediaStream::addTrack(RefPtr&& track) { - if (!prpTrack) { - ec = TYPE_MISMATCH_ERR; + if (!internalAddTrack(WTF::move(track), StreamModifiedByDOMAPI)) return; - } - if (addTrack(prpTrack)) { - for (auto observer = m_observers.begin(), end = m_observers.end(); observer != end; ++observer) - (*observer)->didAddOrRemoveTrack(); - } + for (auto& observer : m_observers) + observer->didAddOrRemoveTrack(); } -bool MediaStream::addTrack(PassRefPtr prpTrack) +void MediaStream::removeTrack(MediaStreamTrack* track) { - // This is a common part used by addTrack called by JavaScript - // and addRemoteTrack and only addRemoteTrack must fire addtrack event - RefPtr track = prpTrack; - if (getTrackById(track->id())) - return false; - - Vector>* tracks = trackVectorForType(track->source()->type()); + if (!internalRemoveTrack(track, StreamModifiedByDOMAPI)) + return; - tracks->append(track); - track->addObserver(this); - m_private->addTrack(&track->privateTrack()); - setActive(true); - return true; + for (auto& observer : m_observers) + observer->didAddOrRemoveTrack(); } -void MediaStream::removeTrack(PassRefPtr prpTrack, ExceptionCode& ec) +MediaStreamTrack* MediaStream::getTrackById(String id) { - if (!active()) { - ec = INVALID_STATE_ERR; - return; - } - - if (!prpTrack) { - ec = TYPE_MISMATCH_ERR; - return; - } + auto it = m_trackSet.find(id); + if (it != m_trackSet.end()) + return it->value.get(); - if (removeTrack(prpTrack)) { - for (auto observer = m_observers.begin(), end = m_observers.end(); observer != end; ++observer) - (*observer)->didAddOrRemoveTrack(); - } + return nullptr; } -bool MediaStream::removeTrack(PassRefPtr prpTrack) +Vector> MediaStream::getAudioTracks() const { - // This is a common part used by removeTrack called by JavaScript - // and removeRemoteTrack and only removeRemoteTrack must fire removetrack event - RefPtr track = prpTrack; - Vector>* tracks = trackVectorForType(track->source()->type()); - - size_t pos = tracks->find(track); - if (pos == notFound) - return false; - - tracks->remove(pos); - m_private->removeTrack(&track->privateTrack()); - // There can be other tracks using the same source in the same MediaStream, - // like when MediaStreamTrack::clone() is called, for instance. - // Spec says that a source can be shared, so we must assure that there is no - // other track using it. - if (!haveTrackWithSource(track->source())) - m_private->removeSource(track->source()); - - track->removeObserver(this); - if (!m_audioTracks.size() && !m_videoTracks.size()) - setActive(false); - - return true; + return trackVectorForType(RealtimeMediaSource::Audio); } -bool MediaStream::haveTrackWithSource(PassRefPtr source) +Vector> MediaStream::getVideoTracks() const { - if (source->type() == RealtimeMediaSource::Audio) { - for (auto it = m_audioTracks.begin(), end = m_audioTracks.end(); it != end; ++it) { - if ((*it)->source() == source.get()) - return true; - } - return false; - } - - for (auto it = m_videoTracks.begin(), end = m_videoTracks.end(); it != end; ++it) { - if ((*it)->source() == source.get()) - return true; - } - - return false; + return trackVectorForType(RealtimeMediaSource::Video); } -MediaStreamTrack* MediaStream::getTrackById(String id) +Vector> MediaStream::getTracks() const { - for (auto it = m_audioTracks.begin(), end = m_audioTracks.end(); it != end; ++it) { - if ((*it)->id() == id) - return (*it).get(); - } - - for (auto it = m_videoTracks.begin(), end = m_videoTracks.end(); it != end; ++it) { - if ((*it)->id() == id) - return (*it).get(); - } - - return nullptr; + return trackVectorForType(); } -Vector> MediaStream::getTracks() +void MediaStream::contextDestroyed() { - Vector> tracks; - for (auto it = m_audioTracks.begin(), end = m_audioTracks.end(); it != end; ++it) - tracks.append((*it).get()); - for (auto it = m_videoTracks.begin(), end = m_videoTracks.end(); it != end; ++it) - tracks.append((*it).get()); - - return tracks; + ContextDestructionObserver::contextDestroyed(); } void MediaStream::trackDidEnd() { - for (auto it = m_audioTracks.begin(), end = m_audioTracks.end(); it != end; ++it) { - if (!(*it)->ended()) - return; - } - for (auto it = m_videoTracks.begin(), end = m_videoTracks.end(); it != end; ++it) { - if (!(*it)->ended()) - return; - } - - if (!m_audioTracks.size() && !m_videoTracks.size()) - setActive(false); + m_private->updateActiveState(MediaStreamPrivate::NotifyClient); } -void MediaStream::setStreamIsActive(bool streamActive) +void MediaStream::activeStatusChanged() { - if (streamActive) - scheduleDispatchEvent(Event::create(eventNames().activeEvent, false, false)); - else - scheduleDispatchEvent(Event::create(eventNames().inactiveEvent, false, false)); + // Schedule the active state change and event dispatch since this callback may be called + // synchronously from the DOM API (e.g. as a result of addTrack()). + scheduleActiveStateChange(); } -void MediaStream::contextDestroyed() +void MediaStream::didAddTrackToPrivate(MediaStreamTrackPrivate& trackPrivate) { - ContextDestructionObserver::contextDestroyed(); + ScriptExecutionContext* context = scriptExecutionContext(); + if (!context) + return; + + internalAddTrack(MediaStreamTrack::create(*context, trackPrivate), StreamModifiedByPlatform); } -void MediaStream::addRemoteSource(RealtimeMediaSource* source) +void MediaStream::didRemoveTrackFromPrivate(MediaStreamTrackPrivate& trackPrivate) { - ASSERT(source); - addRemoteTrack(MediaStreamTrackPrivate::create(source).get()); + RefPtr track = getTrackById(trackPrivate.id()); + internalRemoveTrack(WTF::move(track), StreamModifiedByPlatform); } -void MediaStream::removeRemoteSource(RealtimeMediaSource* source) +bool MediaStream::internalAddTrack(RefPtr&& track, StreamModifier streamModifier) { - ASSERT(source); - if (!active()) - return; - - Vector>* tracks = trackVectorForType(source->type()); + if (getTrackById(track->id())) + return false; - for (int i = tracks->size() - 1; i >= 0; --i) { - if ((*tracks)[i]->source() != source) - continue; + m_trackSet.add(track->id(), track); + track->addObserver(this); - RefPtr track = (*tracks)[i]; - track->removeObserver(this); - tracks->remove(i); - m_private->removeTrack(&track->privateTrack()); - scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release())); - } + if (streamModifier == StreamModifiedByDOMAPI) + m_private->addTrack(&track->privateTrack(), MediaStreamPrivate::DontNotifyClient); + else + dispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, WTF::move(track))); - m_private->removeSource(source); + return true; } -void MediaStream::addRemoteTrack(MediaStreamTrackPrivate* privateTrack) +bool MediaStream::internalRemoveTrack(RefPtr&& track, StreamModifier streamModifier) { - ASSERT(privateTrack); - if (!active()) - return; - - RefPtr track; - switch (privateTrack->type()) { - case RealtimeMediaSource::Audio: - case RealtimeMediaSource::Video: - track = MediaStreamTrack::create(*scriptExecutionContext(), *privateTrack); - break; - case RealtimeMediaSource::None: - ASSERT_NOT_REACHED(); - break; - } - - if (!track) - return; + if (!m_trackSet.remove(track->id())) + return false; - if (addTrack(track)) - scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().addtrackEvent, false, false, track)); -} + track->removeObserver(this); -void MediaStream::removeRemoteTrack(MediaStreamTrackPrivate* privateTrack) -{ - ASSERT(privateTrack); - if (!active()) - return; + if (streamModifier == StreamModifiedByDOMAPI) + m_private->removeTrack(track->privateTrack(), MediaStreamPrivate::DontNotifyClient); + else + dispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, WTF::move(track))); - RefPtr track = getTrackById(privateTrack->id()); - if (removeTrack(track)) - scheduleDispatchEvent(MediaStreamTrackEvent::create(eventNames().removetrackEvent, false, false, track.release())); + return true; } -void MediaStream::scheduleDispatchEvent(PassRefPtr event) +void MediaStream::scheduleActiveStateChange() { - m_scheduledEvents.append(event); + const AtomicString& eventName = m_isActive ? eventNames().inactiveEvent : eventNames().activeEvent; + m_scheduledActivityEvents.append(Event::create(eventName, false, false)); - if (!m_scheduledEventTimer.isActive()) - m_scheduledEventTimer.startOneShot(0); + if (!m_activityEventTimer.isActive()) + m_activityEventTimer.startOneShot(0); } -void MediaStream::scheduledEventTimerFired() +void MediaStream::activityEventTimerFired() { Vector> events; - events.swap(m_scheduledEvents); + events.swap(m_scheduledActivityEvents); - for (auto it = events.begin(), end = events.end(); it != end; ++it) - dispatchEvent((*it).release()); + for (auto& event : events) { + m_isActive = event->type() == eventNames().activeEvent; + dispatchEvent(event.release()); + } events.clear(); } @@ -372,17 +250,17 @@ URLRegistry& MediaStream::registry() const return MediaStreamRegistry::registry(); } -Vector>* MediaStream::trackVectorForType(RealtimeMediaSource::Type type) +Vector> MediaStream::trackVectorForType(RealtimeMediaSource::Type filterType) const { - switch (type) { - case RealtimeMediaSource::Audio: - return &m_audioTracks; - case RealtimeMediaSource::Video: - return &m_videoTracks; - case RealtimeMediaSource::None: - ASSERT_NOT_REACHED(); + Vector> tracks; + for (auto& track : m_trackSet.values()) { + if (filterType == RealtimeMediaSource::None) + tracks.append(track); + else if (track->source()->type() == filterType) + tracks.append(track); } - return nullptr; + + return tracks; } void MediaStream::addObserver(MediaStream::Observer* observer) diff --git a/Source/WebCore/Modules/mediastream/MediaStream.h b/Source/WebCore/Modules/mediastream/MediaStream.h index f4586635051fe..b420d0de49439 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.h +++ b/Source/WebCore/Modules/mediastream/MediaStream.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. - * Copyright (C) 2011 Ericsson AB. All rights reserved. + * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved. * Copyright (C) 2013 Apple Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). * @@ -38,12 +38,13 @@ #include "ScriptWrappable.h" #include "Timer.h" #include "URLRegistry.h" +#include #include #include namespace WebCore { -class MediaStream final : public RefCounted, public URLRegistrable, public ScriptWrappable, public MediaStreamPrivateClient, public EventTargetWithInlineData, public ContextDestructionObserver { +class MediaStream final : public RefCounted, public URLRegistrable, public ScriptWrappable, public MediaStreamPrivateClient, public EventTargetWithInlineData, public ContextDestructionObserver, public MediaStreamTrack::Observer { public: class Observer { public: @@ -51,26 +52,25 @@ class MediaStream final : public RefCounted, public URLRegistrable, virtual void didAddOrRemoveTrack() = 0; }; - static PassRefPtr create(ScriptExecutionContext&); - static PassRefPtr create(ScriptExecutionContext&, PassRefPtr); - static PassRefPtr create(ScriptExecutionContext&, const Vector>&); - static PassRefPtr create(ScriptExecutionContext&, PassRefPtr); + static RefPtr create(ScriptExecutionContext&); + static RefPtr create(ScriptExecutionContext&, MediaStream*); + static RefPtr create(ScriptExecutionContext&, const Vector>&); + static RefPtr create(ScriptExecutionContext&, RefPtr&&); virtual ~MediaStream(); String id() const { return m_private->id(); } - void addTrack(PassRefPtr, ExceptionCode&); - void removeTrack(PassRefPtr, ExceptionCode&); + void addTrack(RefPtr&&); + void removeTrack(MediaStreamTrack*); MediaStreamTrack* getTrackById(String); - Vector> getAudioTracks() const { return m_audioTracks; } - Vector> getVideoTracks() const { return m_videoTracks; } - Vector> getTracks(); + Vector> getAudioTracks() const; + Vector> getVideoTracks() const; + Vector> getTracks() const; - PassRefPtr clone(); + RefPtr clone(); bool active() const; - void setActive(bool); MediaStreamPrivate* privateStream() const { return m_private.get(); } @@ -88,42 +88,42 @@ class MediaStream final : public RefCounted, public URLRegistrable, void removeObserver(Observer*); protected: - MediaStream(ScriptExecutionContext&, PassRefPtr); + MediaStream(ScriptExecutionContext&, const Vector>&); + MediaStream(ScriptExecutionContext&, RefPtr&&); // ContextDestructionObserver virtual void contextDestroyed() override final; private: + enum StreamModifier { StreamModifiedByDOMAPI, StreamModifiedByPlatform }; + // EventTarget virtual void refEventTarget() override final { ref(); } virtual void derefEventTarget() override final { deref(); } - // MediaStreamPrivateClient + // MediaStreamTrack::Observer virtual void trackDidEnd() override final; - virtual void setStreamIsActive(bool) override final; - virtual void addRemoteSource(RealtimeMediaSource*) override final; - virtual void removeRemoteSource(RealtimeMediaSource*) override final; - virtual void addRemoteTrack(MediaStreamTrackPrivate*) override final; - virtual void removeRemoteTrack(MediaStreamTrackPrivate*) override final; - - bool removeTrack(PassRefPtr); - bool addTrack(PassRefPtr); - bool haveTrackWithSource(PassRefPtr); + // MediaStreamPrivateClient + virtual void activeStatusChanged() override final; + virtual void didAddTrackToPrivate(MediaStreamTrackPrivate&) override final; + virtual void didRemoveTrackFromPrivate(MediaStreamTrackPrivate&) override final; - void scheduleDispatchEvent(PassRefPtr); - void scheduledEventTimerFired(); + bool internalAddTrack(RefPtr&&, StreamModifier); + bool internalRemoveTrack(RefPtr&&, StreamModifier); - void cloneMediaStreamTrackVector(Vector>&, const Vector>&); + void scheduleActiveStateChange(); + void activityEventTimerFired(); - Vector>* trackVectorForType(RealtimeMediaSource::Type); + Vector> trackVectorForType(RealtimeMediaSource::Type filterType = RealtimeMediaSource::None) const; RefPtr m_private; - Vector> m_audioTracks; - Vector> m_videoTracks; - Timer m_scheduledEventTimer; - Vector> m_scheduledEvents; + bool m_isActive; + HashMap> m_trackSet; + + Timer m_activityEventTimer; + Vector> m_scheduledActivityEvents; Vector m_observers; }; diff --git a/Source/WebCore/Modules/mediastream/MediaStream.idl b/Source/WebCore/Modules/mediastream/MediaStream.idl index 55a90e53bb028..25253dec2e18d 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.idl +++ b/Source/WebCore/Modules/mediastream/MediaStream.idl @@ -38,8 +38,8 @@ sequence getVideoTracks(); sequence getTracks(); - [RaisesException] void addTrack(MediaStreamTrack track); - [RaisesException] void removeTrack(MediaStreamTrack track); + void addTrack(MediaStreamTrack track); + void removeTrack(MediaStreamTrack track); MediaStreamTrack getTrackById(DOMString trackId); MediaStream clone(); diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 4010e207ce57e..eb60d2f12b073 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -40,11 +40,8 @@ #include "MediaSourceStates.h" #include "MediaStream.h" #include "MediaStreamPrivate.h" -#include "MediaStreamTrackSourcesCallback.h" -#include "MediaStreamTrackSourcesRequest.h" #include "MediaTrackConstraints.h" #include "NotImplemented.h" -#include "RealtimeMediaSourceCenter.h" #include #include @@ -148,13 +145,10 @@ const AtomicString& MediaStreamTrack::readyState() const { static NeverDestroyed ended("ended", AtomicString::ConstructFromLiteral); static NeverDestroyed live("live", AtomicString::ConstructFromLiteral); - static NeverDestroyed newState("new", AtomicString::ConstructFromLiteral); switch (m_privateTrack->readyState()) { case RealtimeMediaSource::Live: return live; - case RealtimeMediaSource::New: - return newState; case RealtimeMediaSource::Ended: return ended; } @@ -163,13 +157,6 @@ const AtomicString& MediaStreamTrack::readyState() const return emptyAtom; } -void MediaStreamTrack::getSources(ScriptExecutionContext* context, PassRefPtr callback, ExceptionCode& ec) -{ - RefPtr request = MediaStreamTrackSourcesRequest::create(context, callback); - if (!RealtimeMediaSourceCenter::singleton().getMediaStreamTrackSources(request.release())) - ec = NOT_SUPPORTED_ERR; -} - RefPtr MediaStreamTrack::getConstraints() const { // FIXME: https://bugs.webkit.org/show_bug.cgi?id=122428 @@ -185,11 +172,11 @@ RefPtr MediaStreamTrack::states() const RefPtr MediaStreamTrack::getCapabilities() const { // The source may be shared by multiple tracks, so its states is not necessarily - // in sync with the track state. A track that is new or has ended always has a source + // in sync with the track state. A track that has ended always has a source // type of "none". RefPtr sourceCapabilities = m_privateTrack->capabilities(); RealtimeMediaSource::ReadyState readyState = m_privateTrack->readyState(); - if (readyState == RealtimeMediaSource::New || readyState == RealtimeMediaSource::Ended) + if (readyState == RealtimeMediaSource::Ended) sourceCapabilities->setSourceType(RealtimeMediaSourceStates::None); return MediaStreamCapabilities::create(sourceCapabilities.release()); @@ -242,17 +229,17 @@ void MediaStreamTrack::removeObserver(MediaStreamTrack::Observer* observer) m_observers.remove(pos); } -void MediaStreamTrack::trackReadyStateChanged() +void MediaStreamTrack::trackEnded() { if (stopped()) return; - RealtimeMediaSource::ReadyState readyState = m_privateTrack->readyState(); - if (readyState == RealtimeMediaSource::Live) - scheduleEventDispatch(Event::create(eventNames().startedEvent, false, false)); - else if (readyState == RealtimeMediaSource::Ended && !m_stoppingTrack) + if (!m_stoppingTrack) scheduleEventDispatch(Event::create(eventNames().endedEvent, false, false)); + for (auto& observer : m_observers) + observer->trackDidEnd(); + configureTrackRendering(); } @@ -287,14 +274,6 @@ void MediaStreamTrack::configureTrackRendering() // ... media from the source only flows when a MediaStreamTrack object is both unmuted and enabled } -void MediaStreamTrack::trackDidEnd() -{ - m_privateTrack->setReadyState(RealtimeMediaSource::Ended); - - for (Vector::iterator i = m_observers.begin(); i != m_observers.end(); ++i) - (*i)->trackDidEnd(); -} - void MediaStreamTrack::stop() { m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackOnly); diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index cef1f3dfd5f08..9be386fcc2473 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -45,7 +45,6 @@ namespace WebCore { class Dictionary; class MediaConstraintsImpl; class MediaSourceStates; -class MediaStreamTrackSourcesCallback; class MediaStreamCapabilities; class MediaTrackConstraints; @@ -75,8 +74,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip const AtomicString& readyState() const; - static void getSources(ScriptExecutionContext*, PassRefPtr, ExceptionCode&); - RefPtr getConstraints() const; RefPtr states() const; RefPtr getCapabilities() const; @@ -108,7 +105,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip void setSource(PassRefPtr); void configureTrackRendering(); - void trackDidEnd(); void scheduleEventDispatch(PassRefPtr); // ActiveDOMObject API. @@ -121,7 +117,7 @@ class MediaStreamTrack final : public RefCounted, public Scrip virtual void derefEventTarget() override final { deref(); } // MediaStreamTrackPrivateClient - void trackReadyStateChanged(); + void trackEnded(); void trackMutedChanged(); void trackEnabledChanged(); diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl b/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl index e821f35776754..b93538da8db3f 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl @@ -41,11 +41,8 @@ enum MediaStreamTrackState { "new", "live", "ended" }; readonly attribute boolean _readonly; readonly attribute boolean remote; readonly attribute MediaStreamTrackState readyState; - attribute EventHandler onstarted; attribute EventHandler onended; - [CallWith=ScriptExecutionContext, RaisesException] static void getSources(MediaStreamTrackSourcesCallback callback); - MediaTrackConstraints getConstraints(); MediaSourceStates states(); diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index e8433e5e7cfeb..cd30173d66824 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -651,7 +651,6 @@ void RTCPeerConnection::didRemoveRemoteStream(MediaStreamPrivate* privateStream) // FIXME: this class shouldn't know that the private stream client is a MediaStream! RefPtr stream = static_cast(privateStream->client()); - stream->setActive(false); if (m_signalingState == SignalingStateClosed) return; diff --git a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp index 9e2735258a08c..6d1ffb6e1a2f7 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Ericsson AB. All rights reserved. + * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved. * Copyright (C) 2013 Google Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). * @@ -42,160 +42,95 @@ namespace WebCore { -PassRefPtr MediaStreamPrivate::create(const Vector>& audioSources, const Vector>& videoSources) +RefPtr MediaStreamPrivate::create(const Vector>& audioSources, const Vector>& videoSources) { - return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), audioSources, videoSources)); -} - -PassRefPtr MediaStreamPrivate::create(const Vector>& audioPrivateTracks, const Vector>& videoPrivateTracks) -{ - return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), audioPrivateTracks, videoPrivateTracks)); -} - -void MediaStreamPrivate::addSource(PassRefPtr prpSource) -{ - RefPtr source = prpSource; - switch (source->type()) { - case RealtimeMediaSource::Audio: - if (m_audioStreamSources.find(source) == notFound) - m_audioStreamSources.append(source); - break; - case RealtimeMediaSource::Video: - if (m_videoStreamSources.find(source) == notFound) - m_videoStreamSources.append(source); - break; - case RealtimeMediaSource::None: - ASSERT_NOT_REACHED(); - break; - } -} + Vector> tracks; + tracks.reserveCapacity(audioSources.size() + videoSources.size()); -void MediaStreamPrivate::removeSource(PassRefPtr source) -{ - size_t pos = notFound; - switch (source->type()) { - case RealtimeMediaSource::Audio: - pos = m_audioStreamSources.find(source); - if (pos == notFound) - return; - m_audioStreamSources.remove(pos); - break; - case RealtimeMediaSource::Video: - pos = m_videoStreamSources.find(source); - if (pos == notFound) - return; - m_videoStreamSources.remove(pos); - break; - case RealtimeMediaSource::None: - ASSERT_NOT_REACHED(); - break; - } -} + for (auto& source : audioSources) + tracks.append(MediaStreamTrackPrivate::create(source)); -void MediaStreamPrivate::addRemoteSource(RealtimeMediaSource* source) -{ - if (m_client) - m_client->addRemoteSource(source); - else - addSource(source); -} + for (auto& source : videoSources) + tracks.append(MediaStreamTrackPrivate::create(source)); -void MediaStreamPrivate::removeRemoteSource(RealtimeMediaSource* source) -{ - if (m_client) - m_client->removeRemoteSource(source); - else - removeSource(source); + return MediaStreamPrivate::create(tracks); } -void MediaStreamPrivate::addRemoteTrack(MediaStreamTrackPrivate* track) +RefPtr MediaStreamPrivate::create(const Vector>& tracks) { - if (m_client) - m_client->addRemoteTrack(track); - else - addTrack(track); + return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), tracks)); } -void MediaStreamPrivate::removeRemoteTrack(MediaStreamTrackPrivate* track) +RefPtr MediaStreamPrivate::create() { - if (m_client) - m_client->removeRemoteTrack(track); - else - removeTrack(track); + return MediaStreamPrivate::create(Vector>()); } -MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector>& audioSources, const Vector>& videoSources) +MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector>& tracks) : m_client(0) , m_id(id) , m_isActive(false) { ASSERT(m_id.length()); - for (size_t i = 0; i < audioSources.size(); i++) - addTrack(MediaStreamTrackPrivate::create(audioSources[i])); - for (size_t i = 0; i < videoSources.size(); i++) - addTrack(MediaStreamTrackPrivate::create(videoSources[i])); + for (auto& track : tracks) + m_trackSet.add(track->id(), track); - unsigned providedSourcesSize = audioSources.size() + videoSources.size(); - unsigned tracksSize = m_audioPrivateTracks.size() + m_videoPrivateTracks.size(); - - if (providedSourcesSize > 0 && tracksSize > 0) - m_isActive = true; + updateActiveState(DontNotifyClient); } -MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector>& audioPrivateTracks, const Vector>& videoPrivateTracks) - : m_client(0) - , m_id(id) - , m_isActive(false) +Vector> MediaStreamPrivate::tracks() const { - ASSERT(m_id.length()); - for (size_t i = 0; i < audioPrivateTracks.size(); i++) - addTrack(audioPrivateTracks[i]); - - for (size_t i = 0; i < videoPrivateTracks.size(); i++) - addTrack(videoPrivateTracks[i]); + Vector> tracks; + tracks.reserveCapacity(m_trackSet.size()); - unsigned providedTracksSize = audioPrivateTracks.size() + videoPrivateTracks.size(); - unsigned tracksSize = m_audioPrivateTracks.size() + m_videoPrivateTracks.size(); + for (auto& track : m_trackSet.values()) + tracks.append(track); - if (providedTracksSize > 0 && tracksSize > 0) - m_isActive = true; + return tracks; } -void MediaStreamPrivate::setActive(bool active) +void MediaStreamPrivate::updateActiveState(NotifyClientOption notifyClientOption) { - if (m_isActive == active) - return; + // A stream is active if it has at least one un-ended track. + bool newActiveState = false; + for (auto& track : m_trackSet.values()) { + if (!track->ended()) { + newActiveState = true; + break; + } + } - m_isActive = active; + if (newActiveState == m_isActive) + return; + m_isActive = newActiveState; - if (m_client) - m_client->setStreamIsActive(active); + if (m_client && notifyClientOption == NotifyClient) + m_client->activeStatusChanged(); } -void MediaStreamPrivate::addTrack(PassRefPtr prpTrack) +void MediaStreamPrivate::addTrack(RefPtr&& track, NotifyClientOption notifyClientOption) { - RefPtr track = prpTrack; - Vector>& tracks = track->type() == RealtimeMediaSource::Audio ? m_audioPrivateTracks : m_videoPrivateTracks; - - size_t pos = tracks.find(track); - if (pos != notFound) + if (m_trackSet.contains(track->id())) return; - tracks.append(track); - if (track->source()) - addSource(track->source()); + m_trackSet.add(track->id(), WTF::move(track)); + + if (m_client && notifyClientOption == NotifyClient) + m_client->didAddTrackToPrivate(*track.get()); + + updateActiveState(NotifyClient); } -void MediaStreamPrivate::removeTrack(PassRefPtr track) +void MediaStreamPrivate::removeTrack(MediaStreamTrackPrivate& track, NotifyClientOption notifyClientOption) { - Vector>& tracks = track->type() == RealtimeMediaSource::Audio ? m_audioPrivateTracks : m_videoPrivateTracks; - - size_t pos = tracks.find(track); - if (pos == notFound) + if (!m_trackSet.remove(track.id())) return; - tracks.remove(pos); + if (m_client && notifyClientOption == NotifyClient) + m_client->didRemoveTrackFromPrivate(track); + + updateActiveState(NotifyClient); } } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/MediaStreamPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamPrivate.h index de69c24b34cc9..87686d18a9a34 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Ericsson AB. All rights reserved. + * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved. * Copyright (C) 2012 Google Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). * @@ -37,7 +37,7 @@ #include "MediaStreamTrack.h" #include "MediaStreamTrackPrivate.h" -#include "RealtimeMediaSource.h" +#include #include #include @@ -45,70 +45,46 @@ namespace WebCore { class MediaStreamTrackPrivate; -class MediaStreamPrivateClient : public MediaStreamTrack::Observer { +class MediaStreamPrivateClient { public: virtual ~MediaStreamPrivateClient() { } - virtual void setStreamIsActive(bool) = 0; - virtual void addRemoteSource(RealtimeMediaSource*) = 0; - virtual void removeRemoteSource(RealtimeMediaSource*) = 0; - virtual void addRemoteTrack(MediaStreamTrackPrivate*) = 0; - virtual void removeRemoteTrack(MediaStreamTrackPrivate*) = 0; + virtual void activeStatusChanged() = 0; + virtual void didAddTrackToPrivate(MediaStreamTrackPrivate&) = 0; + virtual void didRemoveTrackFromPrivate(MediaStreamTrackPrivate&) = 0; }; class MediaStreamPrivate : public RefCounted { public: - static PassRefPtr create(const Vector>& audioSources, const Vector>& videoSources); - static PassRefPtr create(const Vector>& audioPrivateTracks, const Vector>& videoPrivateTracks); + static RefPtr create(const Vector>& audioSources, const Vector>& videoSources); + static RefPtr create(const Vector>&); + static RefPtr create(); virtual ~MediaStreamPrivate() { } + enum NotifyClientOption { NotifyClient, DontNotifyClient }; + MediaStreamPrivateClient* client() const { return m_client; } void setClient(MediaStreamPrivateClient* client) { m_client = client; } String id() const { return m_id; } - unsigned numberOfAudioSources() const { return m_audioStreamSources.size(); } - RealtimeMediaSource* audioSources(unsigned index) const { return m_audioStreamSources[index].get(); } - - unsigned numberOfVideoSources() const { return m_videoStreamSources.size(); } - RealtimeMediaSource* videoSources(unsigned index) const { return m_videoStreamSources[index].get(); } - - unsigned numberOfAudioTracks() const { return m_audioPrivateTracks.size(); } - MediaStreamTrackPrivate* audioTracks(unsigned index) const { return m_audioPrivateTracks[index].get(); } - - unsigned numberOfVideoTracks() const { return m_videoPrivateTracks.size(); } - MediaStreamTrackPrivate* videoTracks(unsigned index) const { return m_videoPrivateTracks[index].get(); } - - void addSource(PassRefPtr); - void removeSource(PassRefPtr); - - void addRemoteSource(RealtimeMediaSource*); - void removeRemoteSource(RealtimeMediaSource*); + Vector> tracks() const; bool active() const { return m_isActive; } - void setActive(bool); - - void addTrack(PassRefPtr); - void removeTrack(PassRefPtr); + void updateActiveState(NotifyClientOption); - void addRemoteTrack(MediaStreamTrackPrivate*); - void removeRemoteTrack(MediaStreamTrackPrivate*); - - // FIXME: implement this. - Vector> tracks() const { return Vector>(); } + void addTrack(RefPtr&&, NotifyClientOption); + void removeTrack(MediaStreamTrackPrivate&, NotifyClientOption); private: - MediaStreamPrivate(const String& id, const Vector>& audioSources, const Vector>& videoSources); - MediaStreamPrivate(const String& id, const Vector>& audioPrivateTracks, const Vector>& videoPrivateTracks); + MediaStreamPrivate(const String& id, const Vector>&); MediaStreamPrivateClient* m_client; String m_id; - Vector> m_audioStreamSources; - Vector> m_videoStreamSources; - Vector> m_audioPrivateTracks; - Vector> m_videoPrivateTracks; + HashMap> m_trackSet; + bool m_isActive; }; diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 31a1b6d63283f..5e9512ccb84b9 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -58,7 +58,7 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr source) : m_source(nullptr) , m_client(nullptr) - , m_readyState(RealtimeMediaSource::New) + , m_readyState(RealtimeMediaSource::Live) , m_muted(false) , m_enabled(true) , m_stopped(false) @@ -166,9 +166,6 @@ void MediaStreamTrackPrivate::setEnabled(bool enabled) // changes value when set; it just doesn't do anything with that new value. m_enabled = enabled; - if (m_source) - m_source->setEnabled(enabled); - if (!m_client || m_ignoreMutations) return; @@ -200,14 +197,11 @@ void MediaStreamTrackPrivate::setReadyState(RealtimeMediaSource::ReadyState stat if (m_readyState == RealtimeMediaSource::Ended || m_readyState == state) return; - RealtimeMediaSource::ReadyState oldState = m_readyState; - m_readyState = state; - - if (!m_client || m_ignoreMutations) - return; + // We only have two states so it's Ended here. + m_readyState = RealtimeMediaSource::Ended; - if ((m_readyState == RealtimeMediaSource::Live && oldState == RealtimeMediaSource::New) || m_readyState == RealtimeMediaSource::Ended) - m_client->trackReadyStateChanged(); + if (m_client && !m_ignoreMutations) + m_client->trackEnded(); } RefPtr MediaStreamTrackPrivate::clone() @@ -271,10 +265,7 @@ void MediaStreamTrackPrivate::sourceMutedChanged() void MediaStreamTrackPrivate::sourceEnabledChanged() { - if (stopped()) - return; - - setEnabled(m_source->enabled()); + // FIXME: remove this function } bool MediaStreamTrackPrivate::observerIsEnabled() diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 54333fbb2dcaf..b03e46f54be19 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -42,7 +42,7 @@ class MediaStreamTrackPrivateClient { public: virtual ~MediaStreamTrackPrivateClient() { } - virtual void trackReadyStateChanged() = 0; + virtual void trackEnded() = 0; virtual void trackMutedChanged() = 0; virtual void trackEnabledChanged() = 0; }; @@ -67,7 +67,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ bool enabled() const { return m_enabled; } void setEnabled(bool); - void setReadyState(RealtimeMediaSource::ReadyState); RealtimeMediaSource::ReadyState readyState() const; RefPtr clone(); @@ -98,6 +97,8 @@ class MediaStreamTrackPrivate : public RefCounted, publ private: MediaStreamTrackPrivateClient* client() const { return m_client; } + void setReadyState(RealtimeMediaSource::ReadyState); + // RealtimeMediaSourceObserver virtual void sourceReadyStateChanged() override final; virtual void sourceMutedChanged() override final; diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp index b236d9191215c..2630248a6d5af 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp @@ -44,8 +44,7 @@ RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const Stri : m_id(id) , m_type(type) , m_name(name) - , m_readyState(New) - , m_enabled(true) + , m_readyState(Live) , m_muted(false) , m_readonly(false) , m_remote(false) @@ -54,12 +53,13 @@ RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const Stri return; m_id = createCanonicalUUIDString(); + + startProducingData(); } void RealtimeMediaSource::reset() { - m_readyState = New; - m_enabled = true; + m_readyState = Live; m_muted = false; m_readonly = false; m_remote = false; @@ -70,18 +70,14 @@ void RealtimeMediaSource::setReadyState(ReadyState readyState) if (m_readyState == Ended || m_readyState == readyState) return; - m_readyState = readyState; + // We only have two states so it's Ended here. + m_readyState = Ended; + for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer) (*observer)->sourceReadyStateChanged(); - if (m_readyState == Live) { - startProducingData(); - return; - } - // There are no more consumers of this source's data, shut it down as appropriate. - if (m_readyState == Ended) - stopProducingData(); + stopProducingData(); } void RealtimeMediaSource::addObserver(RealtimeMediaSource::Observer* observer) @@ -113,33 +109,6 @@ void RealtimeMediaSource::setMuted(bool muted) (*observer)->sourceMutedChanged(); } -void RealtimeMediaSource::setEnabled(bool enabled) -{ - if (!enabled) { - // Don't disable the source unless all observers are disabled. - for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer) { - if ((*observer)->observerIsEnabled()) - return; - } - } - - if (m_enabled == enabled) - return; - - m_enabled = enabled; - - if (m_readyState == Ended) - return; - - if (!enabled) - stopProducingData(); - else - startProducingData(); - - for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer) - (*observer)->sourceEnabledChanged(); -} - bool RealtimeMediaSource::readonly() const { return m_readonly; diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h index 4f9601fe823ee..41d0e3f14a961 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h @@ -58,6 +58,7 @@ class RealtimeMediaSource : public RefCounted { // Source state changes. virtual void sourceReadyStateChanged() = 0; virtual void sourceMutedChanged() = 0; + // FIMXE: remove the below callback virtual void sourceEnabledChanged() = 0; // Observer state queries. @@ -80,13 +81,10 @@ class RealtimeMediaSource : public RefCounted { virtual RefPtr capabilities() const = 0; virtual const RealtimeMediaSourceStates& states() = 0; - enum ReadyState { New = 0, Live = 1, Ended = 2 }; + enum ReadyState { Live = 0, Ended = 1 }; virtual ReadyState readyState() const { return m_readyState; } virtual void setReadyState(ReadyState); - virtual bool enabled() const { return m_enabled; } - virtual void setEnabled(bool); - virtual bool muted() const { return m_muted; } virtual void setMuted(bool); From e902e445af531e69a7e6e456e89848cb0fef3747 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 6 Apr 2015 14:23:15 +0200 Subject: [PATCH 006/155] RTCPeerConnection: Initial import of updated RTCPeerConnection and MediaEndpoint --- Source/WebCore/CMakeLists.txt | 5 +- .../Modules/mediastream/RTCIceCandidate.cpp | 27 +- .../Modules/mediastream/RTCIceCandidate.h | 13 +- .../mediastream/RTCIceCandidateEvent.cpp | 8 +- .../mediastream/RTCIceCandidateEvent.h | 4 +- .../Modules/mediastream/RTCPeerConnection.cpp | 477 ++++++------------ .../Modules/mediastream/RTCPeerConnection.h | 128 +++-- .../Modules/mediastream/RTCPeerConnection.idl | 32 +- .../Modules/mediastream/RTCRtpSender.cpp | 61 +++ .../Modules/mediastream/RTCRtpSender.h | 61 +++ .../Modules/mediastream/RTCRtpSender.idl | 35 ++ .../mediastream/RTCSessionDescription.cpp | 34 +- .../mediastream/RTCSessionDescription.h | 15 +- Source/WebCore/PlatformGTK.cmake | 1 + .../bindings/js/JSRTCPeerConnectionCustom.cpp | 176 ++++++- .../platform/mediastream/IceCandidate.h | 75 +++ .../platform/mediastream/MediaEndpoint.cpp | 21 + .../platform/mediastream/MediaEndpoint.h | 78 +++ .../mediastream/MediaEndpointConfiguration.h | 66 +++ .../MediaEndpointConfigurationConversions.cpp | 261 ++++++++++ .../MediaEndpointConfigurationConversions.h | 54 ++ .../platform/mediastream/MediaPayload.h | 69 +++ .../mediastream/PeerMediaDescription.h | 105 ++++ .../openwebrtc/MediaEndpointOwr.cpp | 200 ++++++++ .../mediastream/openwebrtc/MediaEndpointOwr.h | 83 +++ .../RealtimeMediaSourceCenterOwr.cpp | 1 - 26 files changed, 1653 insertions(+), 437 deletions(-) create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpSender.cpp create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpSender.h create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpSender.idl create mode 100644 Source/WebCore/platform/mediastream/IceCandidate.h create mode 100644 Source/WebCore/platform/mediastream/MediaEndpoint.cpp create mode 100644 Source/WebCore/platform/mediastream/MediaEndpoint.h create mode 100644 Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h create mode 100644 Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp create mode 100644 Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.h create mode 100644 Source/WebCore/platform/mediastream/MediaPayload.h create mode 100644 Source/WebCore/platform/mediastream/PeerMediaDescription.h create mode 100644 Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp create mode 100644 Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 1580931d1f9aa..df2bbac4a9197 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -250,6 +250,7 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/RTCIceCandidateEvent.idl Modules/mediastream/RTCIceServer.idl Modules/mediastream/RTCPeerConnection.idl + Modules/mediastream/RTCRtpSender.idl Modules/mediastream/RTCSessionDescription.idl Modules/mediastream/RTCSessionDescriptionCallback.idl Modules/mediastream/RTCStatsCallback.idl @@ -896,8 +897,9 @@ set(WebCore_SOURCES Modules/mediastream/RTCIceCandidateEvent.cpp Modules/mediastream/RTCOfferAnswerOptions.cpp Modules/mediastream/RTCPeerConnection.cpp + Modules/mediastream/RTCRtpSender.cpp Modules/mediastream/RTCSessionDescription.cpp - Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp + # Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp Modules/mediastream/RTCStatsReport.cpp Modules/mediastream/RTCStatsRequestImpl.cpp Modules/mediastream/RTCStatsResponse.cpp @@ -2188,6 +2190,7 @@ set(WebCore_SOURCES platform/graphics/transforms/TransformationMatrix.cpp platform/graphics/transforms/TranslateTransformOperation.cpp + platform/mediastream/MediaEndpointConfigurationConversions.cpp platform/mediastream/MediaStreamPrivate.cpp platform/mediastream/MediaStreamTrackPrivate.cpp platform/mediastream/RealtimeMediaSource.cpp diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp index 353e309dd855b..22afd132721e4 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,11 +38,10 @@ #include "Dictionary.h" #include "ExceptionCode.h" -#include "RTCIceCandidateDescriptor.h" namespace WebCore { -PassRefPtr RTCIceCandidate::create(const Dictionary& dictionary, ExceptionCode& ec) +RefPtr RTCIceCandidate::create(const Dictionary& dictionary, ExceptionCode& ec) { String candidate; bool ok = dictionary.get("candidate", candidate); @@ -71,16 +71,18 @@ PassRefPtr RTCIceCandidate::create(const Dictionary& dictionary } } - return adoptRef(new RTCIceCandidate(RTCIceCandidateDescriptor::create(candidate, sdpMid, sdpMLineIndex))); + return adoptRef(new RTCIceCandidate(candidate, sdpMid, sdpMLineIndex)); } -PassRefPtr RTCIceCandidate::create(PassRefPtr descriptor) +RefPtr RTCIceCandidate::create(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex) { - return adoptRef(new RTCIceCandidate(descriptor)); + return adoptRef(new RTCIceCandidate(candidate, sdpMid, sdpMLineIndex)); } -RTCIceCandidate::RTCIceCandidate(PassRefPtr descriptor) - : m_descriptor(descriptor) +RTCIceCandidate::RTCIceCandidate(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex) + : m_candidate(candidate) + , m_sdpMid(sdpMid) + , m_sdpMLineIndex(sdpMLineIndex) { } @@ -90,22 +92,17 @@ RTCIceCandidate::~RTCIceCandidate() const String& RTCIceCandidate::candidate() const { - return m_descriptor->candidate(); + return m_candidate; } const String& RTCIceCandidate::sdpMid() const { - return m_descriptor->sdpMid(); + return m_sdpMid; } unsigned short RTCIceCandidate::sdpMLineIndex() const { - return m_descriptor->sdpMLineIndex(); -} - -RTCIceCandidateDescriptor* RTCIceCandidate::descriptor() -{ - return m_descriptor.get(); + return m_sdpMLineIndex; } } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h index 0dad25c27d1ca..1cc8d91750352 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h @@ -35,7 +35,6 @@ #include "ExceptionBase.h" #include "ScriptWrappable.h" -#include #include #include #include @@ -47,20 +46,20 @@ class RTCIceCandidateDescriptor; class RTCIceCandidate : public RefCounted, public ScriptWrappable { public: - static PassRefPtr create(const Dictionary&, ExceptionCode&); - static PassRefPtr create(PassRefPtr); + static RefPtr create(const Dictionary&, ExceptionCode&); + static RefPtr create(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex); virtual ~RTCIceCandidate(); const String& candidate() const; const String& sdpMid() const; unsigned short sdpMLineIndex() const; - RTCIceCandidateDescriptor* descriptor(); - private: - explicit RTCIceCandidate(PassRefPtr); + explicit RTCIceCandidate(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex); - RefPtr m_descriptor; + String m_candidate; + String m_sdpMid; + unsigned short m_sdpMLineIndex; }; } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp index 178c5e02f3a26..b58ddf7b62f72 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.cpp @@ -38,18 +38,18 @@ Ref RTCIceCandidateEvent::create() return adoptRef(*new RTCIceCandidateEvent); } -Ref RTCIceCandidateEvent::create(bool canBubble, bool cancelable, PassRefPtr candidate) +Ref RTCIceCandidateEvent::create(bool canBubble, bool cancelable, RefPtr&& candidate) { - return adoptRef(*new RTCIceCandidateEvent(canBubble, cancelable, candidate)); + return adoptRef(*new RTCIceCandidateEvent(canBubble, cancelable, WTF::move(candidate))); } RTCIceCandidateEvent::RTCIceCandidateEvent() { } -RTCIceCandidateEvent::RTCIceCandidateEvent(bool canBubble, bool cancelable, PassRefPtr candidate) +RTCIceCandidateEvent::RTCIceCandidateEvent(bool canBubble, bool cancelable, RefPtr&& candidate) : Event(eventNames().icecandidateEvent, canBubble, cancelable) - , m_candidate(candidate) + , m_candidate(WTF::move(candidate)) { } diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h index df90ac08d263a..e0a804d515b83 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidateEvent.h @@ -38,7 +38,7 @@ class RTCIceCandidateEvent : public Event { virtual ~RTCIceCandidateEvent(); static Ref create(); - static Ref create(bool canBubble, bool cancelable, PassRefPtr); + static Ref create(bool canBubble, bool cancelable, RefPtr&&); RTCIceCandidate* candidate() const; @@ -46,7 +46,7 @@ class RTCIceCandidateEvent : public Event { private: RTCIceCandidateEvent(); - RTCIceCandidateEvent(bool canBubble, bool cancelable, PassRefPtr); + RTCIceCandidateEvent(bool canBubble, bool cancelable, RefPtr&&); RefPtr m_candidate; }; diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index cd30173d66824..7f79e3fb932fe 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,32 +37,22 @@ #include "RTCPeerConnection.h" #include "ArrayValue.h" +#include "DOMError.h" #include "Document.h" #include "Event.h" #include "ExceptionCode.h" #include "Frame.h" -#include "FrameLoader.h" -#include "FrameLoaderClient.h" -#include "MediaStreamEvent.h" +#include "MediaEndpointConfiguration.h" +#include "MediaEndpointConfigurationConversions.h" +#include "MediaStreamTrack.h" +#include "PeerMediaDescription.h" #include "RTCConfiguration.h" -#include "RTCDTMFSender.h" #include "RTCDataChannel.h" -#include "RTCDataChannelEvent.h" -#include "RTCDataChannelHandler.h" #include "RTCIceCandidate.h" -#include "RTCIceCandidateDescriptor.h" #include "RTCIceCandidateEvent.h" #include "RTCOfferAnswerOptions.h" -#include "RTCPeerConnectionErrorCallback.h" +#include "RTCRtpSender.h" #include "RTCSessionDescription.h" -#include "RTCSessionDescriptionCallback.h" -#include "RTCSessionDescriptionDescriptor.h" -#include "RTCSessionDescriptionRequestImpl.h" -#include "RTCStatsCallback.h" -#include "RTCStatsRequestImpl.h" -#include "RTCVoidRequestImpl.h" -#include "ScriptExecutionContext.h" -#include "VoidCallback.h" #include namespace WebCore { @@ -157,15 +148,20 @@ PassRefPtr RTCPeerConnection::parseConfiguration(const Diction PassRefPtr RTCPeerConnection::create(ScriptExecutionContext& context, const Dictionary& rtcConfiguration, ExceptionCode& ec) { + printf("-> RTCConfiguration::create\n"); + RefPtr configuration = parseConfiguration(rtcConfiguration, ec); if (ec) return nullptr; + printf("RTCPeerConnection: config was ok\n"); + RefPtr peerConnection = adoptRef(new RTCPeerConnection(context, configuration.release(), ec)); peerConnection->suspendIfNeeded(); if (ec) return nullptr; + printf("RTCPeerConnection: before release\n"); return peerConnection.release(); } @@ -178,6 +174,8 @@ RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr , m_configuration(configuration) , m_stopped(false) { + printf("-> RTCConfiguration::RTCConfiguration\n"); + Document& document = downcast(context); if (!document.frame()) { @@ -185,174 +183,163 @@ RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr return; } - m_peerHandler = RTCPeerConnectionHandler::create(this); - if (!m_peerHandler) { + m_mediaEndpoint = MediaEndpoint::create(this); + if (!m_mediaEndpoint) { ec = NOT_SUPPORTED_ERR; return; } - document.frame()->loader().client().dispatchWillStartUsingPeerConnectionHandler(m_peerHandler.get()); - - if (!m_peerHandler->initialize(m_configuration->privateConfiguration())) { - ec = NOT_SUPPORTED_ERR; - return; - } + m_mediaEndpoint->setConfiguration(m_configuration->privateConfiguration()); } RTCPeerConnection::~RTCPeerConnection() { stop(); +} - for (auto stream = m_localStreams.begin(), end = m_localStreams.end(); stream != end; ++stream) - (*stream)->removeObserver(this); +Vector> RTCPeerConnection::getSenders() const +{ + return m_senders; } -void RTCPeerConnection::createOffer(PassRefPtr successCallback, PassRefPtr errorCallback, const Dictionary& offerOptions, ExceptionCode& ec) +RefPtr RTCPeerConnection::addTrack(RefPtr&& track, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; - return; + return nullptr; } - if (!successCallback) { - ec = TYPE_MISMATCH_ERR; + RefPtr sender = RTCRtpSender::create(WTF::move(track)); + m_senders.append(sender); + + return sender; +} + +void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) +{ + if (m_signalingState == SignalingStateClosed) { + ec = INVALID_STATE_ERR; return; } RefPtr options = RTCOfferOptions::create(offerOptions, ec); if (ec) { - callOnMainThread([=] { + callOnMainThread([rejectCallback] { RefPtr error = DOMError::create("Invalid createOffer argument."); - errorCallback->handleEvent(error.get()); + rejectCallback(error.get()); }); return; } - RefPtr request = RTCSessionDescriptionRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback); - m_peerHandler->createOffer(request.release(), options->privateOfferOptions()); + RefPtr configurationSnapshot = m_localConfiguration ? + MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); + + Vector localTracks; + for (auto sender : m_senders) + localTracks.append(sender->track()); + + // FIXME: update existing media descriptions with tracks + + for (auto track : localTracks) { + RefPtr mediaDescription = PeerMediaDescription::create(); + + mediaDescription->setMediaStreamId("fix me"); + mediaDescription->setMediaStreamTrackId(track->id()); + mediaDescription->setType(track->kind()); + // FIXME: payloads + mediaDescription->setRtcpMux(true); + mediaDescription->setDtlsSetup("actpass"); + + configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); + } + + RefPtr offer = RTCSessionDescription::create("offer", MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get())); + resolveCallback(WTF::move(offer)); } -void RTCPeerConnection::createAnswer(PassRefPtr successCallback, PassRefPtr errorCallback, const Dictionary& answerOptions, ExceptionCode& ec) +void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; return; } - if (!successCallback) { - ec = TYPE_MISMATCH_ERR; - return; - } - RefPtr options = RTCOfferAnswerOptions::create(answerOptions, ec); if (ec) { - callOnMainThread([=] { + callOnMainThread([rejectCallback] { RefPtr error = DOMError::create("Invalid createAnswer argument."); - errorCallback->handleEvent(error.get()); + rejectCallback(error.get()); }); return; } - RefPtr request = RTCSessionDescriptionRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback); - m_peerHandler->createAnswer(request.release(), options->privateOfferAnswerOptions()); -} - -bool RTCPeerConnection::checkStateForLocalDescription(RTCSessionDescription* localDescription) -{ - if (localDescription->type() == "offer") - return m_signalingState == SignalingStateStable || m_signalingState == SignalingStateHaveLocalOffer; - if (localDescription->type() == "answer") - return m_signalingState == SignalingStateHaveRemoteOffer || m_signalingState == SignalingStateHaveLocalPrAnswer; - if (localDescription->type() == "pranswer") - return m_signalingState == SignalingStateHaveLocalPrAnswer || m_signalingState == SignalingStateHaveRemoteOffer; - - return false; -} - -bool RTCPeerConnection::checkStateForRemoteDescription(RTCSessionDescription* remoteDescription) -{ - if (remoteDescription->type() == "offer") - return m_signalingState == SignalingStateStable || m_signalingState == SignalingStateHaveRemoteOffer; - if (remoteDescription->type() == "answer") - return m_signalingState == SignalingStateHaveLocalOffer || m_signalingState == SignalingStateHaveRemotePrAnswer; - if (remoteDescription->type() == "pranswer") - return m_signalingState == SignalingStateHaveRemotePrAnswer || m_signalingState == SignalingStateHaveLocalOffer; - - return false; + // TODO } -void RTCPeerConnection::setLocalDescription(PassRefPtr prpSessionDescription, PassRefPtr successCallback, PassRefPtr errorCallback, ExceptionCode& ec) +void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; return; } - RefPtr sessionDescription = prpSessionDescription; - if (!sessionDescription) { - ec = TYPE_MISMATCH_ERR; + DescriptionType descriptionType = parseDescriptionType(description->type()); + if (descriptionType == DescriptionTypeInvalid) { + // FIXME: rejectCallback return; } - if (!checkStateForLocalDescription(sessionDescription.get())) { - callOnMainThread([=] { - RefPtr error = DOMError::create(RTCPeerConnectionHandler::invalidSessionDescriptionErrorName()); - errorCallback->handleEvent(error.get()); - }); + SignalingState targetState = targetSignalingState(SetterTypeLocal, descriptionType); + if (targetState == SignalingStateInvalid) { + // FIXME: rejectCallback return; } - RefPtr request = RTCVoidRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback); - m_peerHandler->setLocalDescription(request.release(), sessionDescription->descriptor()); + unsigned previousNumberOfMediaDescriptions = m_localConfiguration ? m_localConfiguration->mediaDescriptions().size() : 0; + + m_localConfiguration = MediaEndpointConfigurationConversions::fromJSON(description->sdp()); + m_localConfigurationType = description->type(); + + bool hasNewMediaDescriptions = m_localConfiguration->mediaDescriptions().size() > previousNumberOfMediaDescriptions; + bool isInitiator = descriptionType == DescriptionTypeOffer; + + RefPtr protectedThis(this); + m_completeSetLocalDescription = [targetState, resolveCallback, protectedThis]() mutable { + protectedThis->m_signalingState = targetState; + resolveCallback(); + }; + + if (hasNewMediaDescriptions) + m_mediaEndpoint->prepareToReceive(m_localConfiguration.get(), isInitiator); + + if (m_remoteConfiguration) + m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); } -PassRefPtr RTCPeerConnection::localDescription(ExceptionCode& ec) +RefPtr RTCPeerConnection::localDescription() const { - RefPtr descriptor = m_peerHandler->localDescription(); - if (!descriptor) { - ec = INVALID_STATE_ERR; + if (!m_localConfiguration) return nullptr; - } - RefPtr sessionDescription = RTCSessionDescription::create(descriptor.release()); - return sessionDescription.release(); + return RTCSessionDescription::create(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get()), m_localConfigurationType); } -void RTCPeerConnection::setRemoteDescription(PassRefPtr prpSessionDescription, PassRefPtr successCallback, PassRefPtr errorCallback, ExceptionCode& ec) +void RTCPeerConnection::setRemoteDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; return; } - RefPtr sessionDescription = prpSessionDescription; - if (!sessionDescription) { - ec = TYPE_MISMATCH_ERR; - return; - } - - if (!checkStateForRemoteDescription(sessionDescription.get())) { - callOnMainThread([=] { - RefPtr error = DOMError::create(RTCPeerConnectionHandler::invalidSessionDescriptionErrorName()); - errorCallback->handleEvent(error.get()); - }); - return; - } - - RefPtr request = RTCVoidRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback); - m_peerHandler->setRemoteDescription(request.release(), sessionDescription->descriptor()); + // TODO } -PassRefPtr RTCPeerConnection::remoteDescription(ExceptionCode& ec) +RefPtr RTCPeerConnection::remoteDescription() const { - RefPtr descriptor = m_peerHandler->remoteDescription(); - if (!descriptor) { - ec = INVALID_STATE_ERR; + if (!m_remoteConfiguration) return nullptr; - } - RefPtr desc = RTCSessionDescription::create(descriptor.release()); - return desc.release(); + return RTCSessionDescription::create(MediaEndpointConfigurationConversions::toJSON(m_remoteConfiguration.get()), m_remoteConfigurationType); } void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionCode& ec) @@ -366,28 +353,28 @@ void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionC if (ec) return; - bool valid = m_peerHandler->updateIce(m_configuration->privateConfiguration()); - if (!valid) - ec = SYNTAX_ERR; + // FIXME: use configuration } -void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, PassRefPtr successCallback, PassRefPtr errorCallback, ExceptionCode& ec) +void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; return; } - if (!iceCandidate || !successCallback || !errorCallback) { - ec = TYPE_MISMATCH_ERR; + RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(iceCandidate->candidate()); + if (!candidate) { + rejectCallback(DOMError::create("FIXME: bad candidate")); return; } - RefPtr request = RTCVoidRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback); + printf("RTCPeerConnection::addIceCandidate: candidate: type %s, foundation: %s, componentId: %d, transport: %s\n", + candidate->type().ascii().data(), candidate->foundation().ascii().data(), candidate->componentId(), candidate->transport().ascii().data()); + + m_mediaEndpoint->addRemoteCandidate(candidate.get()); - bool implemented = m_peerHandler->addIceCandidate(request.release(), iceCandidate->descriptor()); - if (!implemented) - ec = SYNTAX_ERR; + resolveCallback(); } String RTCPeerConnection::signalingState() const @@ -405,6 +392,8 @@ String RTCPeerConnection::signalingState() const return ASCIILiteral("have-remote-pranswer"); case SignalingStateClosed: return ASCIILiteral("closed"); + case SignalingStateInvalid: + break; } ASSERT_NOT_REACHED(); @@ -449,230 +438,67 @@ String RTCPeerConnection::iceConnectionState() const return String(); } -void RTCPeerConnection::addStream(PassRefPtr prpStream, ExceptionCode& ec) -{ - if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; - return; - } - - RefPtr stream = prpStream; - if (!stream) { - ec = TYPE_MISMATCH_ERR; - return; - } - - if (m_localStreams.contains(stream)) - return; - - bool valid = m_peerHandler->addStream(stream->privateStream()); - if (!valid) - ec = SYNTAX_ERR; - else { - m_localStreams.append(stream); - stream->addObserver(this); - } -} - -void RTCPeerConnection::removeStream(PassRefPtr prpStream, ExceptionCode& ec) -{ - if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; - return; - } - - if (!prpStream) { - ec = TYPE_MISMATCH_ERR; - return; - } - - RefPtr stream = prpStream; - - size_t pos = m_localStreams.find(stream); - if (pos == notFound) - return; - - m_localStreams.remove(pos); - stream->removeObserver(this); - m_peerHandler->removeStream(stream->privateStream()); -} - RTCConfiguration* RTCPeerConnection::getConfiguration() const { return m_configuration.get(); } -Vector> RTCPeerConnection::getLocalStreams() const -{ - return m_localStreams; -} - -Vector> RTCPeerConnection::getRemoteStreams() const -{ - return m_remoteStreams; -} - -MediaStream* RTCPeerConnection::getStreamById(const String& streamId) -{ - for (auto iter = m_localStreams.begin(); iter != m_localStreams.end(); ++iter) { - if ((*iter)->id() == streamId) - return iter->get(); - } - - for (auto iter = m_remoteStreams.begin(); iter != m_remoteStreams.end(); ++iter) { - if ((*iter)->id() == streamId) - return iter->get(); - } - - return nullptr; -} - -void RTCPeerConnection::getStats(PassRefPtr successCallback, PassRefPtr errorCallback, PassRefPtr selector) -{ - RefPtr statsRequest = RTCStatsRequestImpl::create(scriptExecutionContext(), successCallback, errorCallback, &selector->privateTrack()); - // FIXME: Add passing selector as part of the statsRequest. - m_peerHandler->getStats(statsRequest.release()); -} - -PassRefPtr RTCPeerConnection::createDataChannel(String label, const Dictionary& options, ExceptionCode& ec) -{ - if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; - return nullptr; - } - - RefPtr channel = RTCDataChannel::create(scriptExecutionContext(), m_peerHandler.get(), label, options, ec); - if (ec) - return nullptr; - - m_dataChannels.append(channel); - return channel.release(); -} - -bool RTCPeerConnection::hasLocalStreamWithTrackId(const String& trackId) +void RTCPeerConnection::getStats(PassRefPtr, PassRefPtr, PassRefPtr) { - for (auto iter = m_localStreams.begin(); iter != m_localStreams.end(); ++iter) { - if ((*iter)->getTrackById(trackId)) - return true; - } - return false; } -PassRefPtr RTCPeerConnection::createDTMFSender(PassRefPtr prpTrack, ExceptionCode& ec) +PassRefPtr RTCPeerConnection::createDataChannel(String, const Dictionary&, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; return nullptr; } - if (!prpTrack) { - ec = TypeError; - return nullptr; - } - - RefPtr track = prpTrack; - - if (!hasLocalStreamWithTrackId(track->id())) { - ec = SYNTAX_ERR; - return nullptr; - } - - RefPtr dtmfSender = RTCDTMFSender::create(scriptExecutionContext(), m_peerHandler.get(), track.release(), ec); - if (ec) - return nullptr; - return dtmfSender.release(); + return nullptr; } -void RTCPeerConnection::close(ExceptionCode& ec) +void RTCPeerConnection::close() { - if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; + if (m_signalingState == SignalingStateClosed) return; - } - m_peerHandler->stop(); + m_mediaEndpoint->stop(); - changeIceConnectionState(IceConnectionStateClosed); - changeIceGatheringState(IceGatheringStateComplete); - changeSignalingState(SignalingStateClosed); + m_signalingState = SignalingStateClosed; } -void RTCPeerConnection::negotiationNeeded() +void RTCPeerConnection::gotSendSSRC(unsigned, const String&, const String&) { - scheduleDispatchEvent(Event::create(eventNames().negotiationneededEvent, false, false)); } -void RTCPeerConnection::didGenerateIceCandidate(PassRefPtr iceCandidateDescriptor) +void RTCPeerConnection::gotDtlsFingerprint(unsigned, const String&, const String&) { - ASSERT(scriptExecutionContext()->isContextThread()); - if (!iceCandidateDescriptor) - scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, 0)); - else { - RefPtr iceCandidate = RTCIceCandidate::create(iceCandidateDescriptor); - scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, iceCandidate.release())); - } } -void RTCPeerConnection::didChangeSignalingState(SignalingState newState) +void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate) { - ASSERT(scriptExecutionContext()->isContextThread()); - changeSignalingState(newState); -} + printf("-> RTCPeerConnection::gotIceCandidate\n"); + printf("is context thread: %d\n", scriptExecutionContext()->isContextThread()); -void RTCPeerConnection::didChangeIceGatheringState(IceGatheringState newState) -{ ASSERT(scriptExecutionContext()->isContextThread()); - changeIceGatheringState(newState); -} -void RTCPeerConnection::didChangeIceConnectionState(IceConnectionState newState) -{ - ASSERT(scriptExecutionContext()->isContextThread()); - changeIceConnectionState(newState); + String candidateString = MediaEndpointConfigurationConversions::iceCandidateToJSON(candidate.get()); + RefPtr iceCandidate = RTCIceCandidate::create(candidateString, "", mdescIndex); + scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, WTF::move(iceCandidate))); } -void RTCPeerConnection::didAddRemoteStream(PassRefPtr privateStream) +void RTCPeerConnection::doneGatheringCandidates(unsigned) { - ASSERT(scriptExecutionContext()->isContextThread()); - - if (m_signalingState == SignalingStateClosed) - return; - - RefPtr stream = MediaStream::create(*scriptExecutionContext(), privateStream); - m_remoteStreams.append(stream); + printf("-> RTCPeerConnection::doneGatheringCandidates\n"); + printf("is context thread: %d\n", scriptExecutionContext()->isContextThread()); - scheduleDispatchEvent(MediaStreamEvent::create(eventNames().addstreamEvent, false, false, stream.release())); -} - -void RTCPeerConnection::didRemoveRemoteStream(MediaStreamPrivate* privateStream) -{ ASSERT(scriptExecutionContext()->isContextThread()); - ASSERT(privateStream->client()); - - // FIXME: this class shouldn't know that the private stream client is a MediaStream! - RefPtr stream = static_cast(privateStream->client()); - if (m_signalingState == SignalingStateClosed) - return; - - size_t pos = m_remoteStreams.find(stream); - ASSERT(pos != notFound); - m_remoteStreams.remove(pos); - - scheduleDispatchEvent(MediaStreamEvent::create(eventNames().removestreamEvent, false, false, stream.release())); + scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, 0)); } -void RTCPeerConnection::didAddRemoteDataChannel(std::unique_ptr handler) +void RTCPeerConnection::gotRemoteSource(unsigned, RefPtr&&) { - ASSERT(scriptExecutionContext()->isContextThread()); - - if (m_signalingState == SignalingStateClosed) - return; - - RefPtr channel = RTCDataChannel::create(scriptExecutionContext(), WTF::move(handler)); - m_dataChannels.append(channel); - - scheduleDispatchEvent(RTCDataChannelEvent::create(eventNames().datachannelEvent, false, false, channel.release())); } void RTCPeerConnection::stop() @@ -683,10 +509,44 @@ void RTCPeerConnection::stop() m_stopped = true; m_iceConnectionState = IceConnectionStateClosed; m_signalingState = SignalingStateClosed; +} - Vector>::iterator i = m_dataChannels.begin(); - for (; i != m_dataChannels.end(); ++i) - (*i)->stop(); +RTCPeerConnection::SignalingState RTCPeerConnection::targetSignalingState(SetterType setter, DescriptionType description) const +{ + // "map" describing the valid state transitions + switch (m_signalingState) { + case SignalingStateStable: + if (setter == SetterTypeLocal && description == DescriptionTypeOffer) + return SignalingStateHaveLocalOffer; + if (setter == SetterTypeRemote && description == DescriptionTypeOffer) + return SignalingStateHaveRemoteOffer; + break; + case SignalingStateHaveLocalOffer: + if (setter == SetterTypeLocal && description == DescriptionTypeOffer) + return SignalingStateHaveLocalOffer; + if (setter == SetterTypeRemote && description == DescriptionTypeAnswer) + return SignalingStateStable; + break; + case SignalingStateHaveRemoteOffer: + if (setter == SetterTypeLocal && description == DescriptionTypeAnswer) + return SignalingStateStable; + if (setter == SetterTypeRemote && description == DescriptionTypeOffer) + return SignalingStateHaveRemoteOffer; + break; + default: + break; + }; + return SignalingStateInvalid; +} + +RTCPeerConnection::DescriptionType RTCPeerConnection::parseDescriptionType(const String& typeName) const +{ + if (typeName == "offer") + return DescriptionTypeOffer; + if (typeName == "answer") + return DescriptionTypeAnswer; + + return DescriptionTypeInvalid; } const char* RTCPeerConnection::activeDOMObjectName() const @@ -700,11 +560,6 @@ bool RTCPeerConnection::canSuspend() const return false; } -void RTCPeerConnection::didAddOrRemoveTrack() -{ - negotiationNeeded(); -} - void RTCPeerConnection::changeSignalingState(SignalingState signalingState) { if (m_signalingState != SignalingStateClosed && m_signalingState != signalingState) { diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index d3d339f970c2e..5249da4cf6f4f 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,99 +38,121 @@ #include "ActiveDOMObject.h" #include "Dictionary.h" #include "EventTarget.h" -#include "ExceptionBase.h" -#include "MediaStream.h" -#include "RTCIceCandidate.h" -#include "RTCPeerConnectionHandler.h" -#include "RTCPeerConnectionHandlerClient.h" +#include "MediaEndpoint.h" #include "ScriptWrappable.h" #include "Timer.h" #include namespace WebCore { +class MediaEndpointConfiguration; class MediaStreamTrack; class RTCConfiguration; -class RTCDTMFSender; class RTCDataChannel; +class RTCIceCandidate; class RTCPeerConnectionErrorCallback; +class RTCRtpSender; class RTCSessionDescription; -class RTCSessionDescriptionCallback; class RTCStatsCallback; -class VoidCallback; -class RTCPeerConnection final : public RefCounted, public ScriptWrappable, public RTCPeerConnectionHandlerClient, public EventTargetWithInlineData, public ActiveDOMObject, public MediaStream::Observer { +class RTCPeerConnection final : public RefCounted, public ScriptWrappable, public MediaEndpointClient, public EventTargetWithInlineData, public ActiveDOMObject { public: static PassRefPtr create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, ExceptionCode&); ~RTCPeerConnection(); - void createOffer(PassRefPtr, PassRefPtr, const Dictionary& offerOptions, ExceptionCode&); + typedef std::function)> OfferAnswerResolveCallback; + typedef std::function VoidResolveCallback; + typedef std::function)> RejectCallback; - void createAnswer(PassRefPtr, PassRefPtr, const Dictionary& answerOptions, ExceptionCode&); + Vector> getSenders() const; - void setLocalDescription(PassRefPtr, PassRefPtr, PassRefPtr, ExceptionCode&); - PassRefPtr localDescription(ExceptionCode&); + RefPtr addTrack(RefPtr&&, ExceptionCode&); - void setRemoteDescription(PassRefPtr, PassRefPtr, PassRefPtr, ExceptionCode&); - PassRefPtr remoteDescription(ExceptionCode&); + void createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback, RejectCallback, ExceptionCode&); + void createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback, RejectCallback, ExceptionCode&); + + void setLocalDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback, ExceptionCode&); + RefPtr localDescription() const; + + void setRemoteDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback, ExceptionCode&); + RefPtr remoteDescription() const; String signalingState() const; void updateIce(const Dictionary& rtcConfiguration, ExceptionCode&); - - void addIceCandidate(RTCIceCandidate*, PassRefPtr, PassRefPtr, ExceptionCode&); + void addIceCandidate(RTCIceCandidate*, VoidResolveCallback, RejectCallback, ExceptionCode&); String iceGatheringState() const; - String iceConnectionState() const; RTCConfiguration* getConfiguration() const; - Vector> getLocalStreams() const; - - Vector> getRemoteStreams() const; - - MediaStream* getStreamById(const String& streamId); - - void addStream(PassRefPtr, ExceptionCode&); - - void removeStream(PassRefPtr, ExceptionCode&); - void getStats(PassRefPtr successCallback, PassRefPtr, PassRefPtr selector); PassRefPtr createDataChannel(String label, const Dictionary& dataChannelDict, ExceptionCode&); - PassRefPtr createDTMFSender(PassRefPtr, ExceptionCode&); + void close(); - void close(ExceptionCode&); - - // RTCPeerConnectionHandlerClient - virtual void negotiationNeeded() override; - virtual void didGenerateIceCandidate(PassRefPtr) override; - virtual void didChangeSignalingState(SignalingState) override; - virtual void didChangeIceGatheringState(IceGatheringState) override; - virtual void didChangeIceConnectionState(IceConnectionState) override; - virtual void didAddRemoteStream(PassRefPtr) override; - virtual void didRemoveRemoteStream(MediaStreamPrivate*) override; - virtual void didAddRemoteDataChannel(std::unique_ptr) override; + // MediaEndpointClient + virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) override; + virtual void gotDtlsFingerprint(unsigned mdescIndex, const String& fingerprint, const String& hashFunction) override; + virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) override; + virtual void doneGatheringCandidates(unsigned mdescIndex) override; + virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; // EventTarget virtual EventTargetInterface eventTargetInterface() const override { return RTCPeerConnectionEventTargetInterfaceType; } virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } - // MediaStream::Observer - virtual void didAddOrRemoveTrack() override; - using RefCounted::ref; using RefCounted::deref; private: + enum SetterType { + SetterTypeLocal = 1, + SetterTypeRemote = 2 + }; + + enum DescriptionType { + DescriptionTypeOffer = 1, + DescriptionTypeAnswer = 2, + DescriptionTypeInvalid = 3 + }; + + enum SignalingState { + SignalingStateStable = 1, + SignalingStateHaveLocalOffer = 2, + SignalingStateHaveRemoteOffer = 3, + SignalingStateHaveLocalPrAnswer = 4, + SignalingStateHaveRemotePrAnswer = 5, + SignalingStateClosed = 6, + SignalingStateInvalid = 7 + }; + + enum IceConnectionState { + IceConnectionStateNew = 1, + IceConnectionStateChecking = 2, + IceConnectionStateConnected = 3, + IceConnectionStateCompleted = 4, + IceConnectionStateFailed = 5, + IceConnectionStateDisconnected = 6, + IceConnectionStateClosed = 7 + }; + + enum IceGatheringState { + IceGatheringStateNew = 1, + IceGatheringStateGathering = 2, + IceGatheringStateComplete = 3 + }; + RTCPeerConnection(ScriptExecutionContext&, PassRefPtr, ExceptionCode&); static PassRefPtr parseConfiguration(const Dictionary& configuration, ExceptionCode&); + SignalingState targetSignalingState(SetterType, DescriptionType) const; + DescriptionType parseDescriptionType(const String& typeName) const; + void scheduleDispatchEvent(PassRefPtr); void scheduledEventTimerFired(); - bool hasLocalStreamWithTrackId(const String& trackId); // EventTarget implementation. virtual void refEventTarget() override { ref(); } @@ -144,19 +167,24 @@ class RTCPeerConnection final : public RefCounted, public Scr void changeIceGatheringState(IceGatheringState); void changeIceConnectionState(IceConnectionState); - bool checkStateForLocalDescription(RTCSessionDescription*); - bool checkStateForRemoteDescription(RTCSessionDescription*); - SignalingState m_signalingState; IceGatheringState m_iceGatheringState; IceConnectionState m_iceConnectionState; - Vector> m_localStreams; - Vector> m_remoteStreams; + Vector> m_senders; + // TODO m_receivers + + RefPtr m_localConfiguration; + RefPtr m_remoteConfiguration; + + String m_localConfigurationType; + String m_remoteConfigurationType; + + std::function m_completeSetLocalDescription; Vector> m_dataChannels; - std::unique_ptr m_peerHandler; + std::unique_ptr m_mediaEndpoint; Timer m_scheduledEventTimer; Vector> m_scheduledEvents; diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl index 8b2207e9fac53..18dc8353c2adf 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl @@ -1,6 +1,7 @@ /* * Copyright (C) 2012 Google Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,45 +36,38 @@ CustomConstructor(Dictionary rtcConfiguration), ConstructorCallWith=ScriptExecutionContext, ConstructorRaisesException, - ConstructorCallWith=ScriptExecutionContext, EventTarget, InterfaceName=webkitRTCPeerConnection, ] interface RTCPeerConnection { - [RaisesException] void createOffer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional Dictionary offerOptions); - [RaisesException] void createAnswer(RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional Dictionary answerOptions); + [Custom, RaisesException] Promise createOffer(optional Dictionary offerOptions); + [Custom, RaisesException] Promise createAnswer(optional Dictionary answerOptions); + + sequence getSenders(); - [RaisesException] void setLocalDescription(RTCSessionDescription description, VoidCallback successCallback, RTCPeerConnectionErrorCallback failureCallback); - [GetterRaisesException] readonly attribute RTCSessionDescription localDescription; + [StrictTypeChecking, RaisesException] RTCRtpSender addTrack(MediaStreamTrack track); - [RaisesException] void setRemoteDescription(RTCSessionDescription description, VoidCallback successCallback, RTCPeerConnectionErrorCallback failureCallback); - [GetterRaisesException] readonly attribute RTCSessionDescription remoteDescription; + [Custom, RaisesException] Promise setLocalDescription(RTCSessionDescription description); + readonly attribute RTCSessionDescription localDescription; + + [Custom, RaisesException] Promise setRemoteDescription(RTCSessionDescription description); + readonly attribute RTCSessionDescription remoteDescription; readonly attribute DOMString signalingState; [RaisesException] void updateIce(Dictionary configuration); - - [RaisesException] void addIceCandidate(RTCIceCandidate candidate, VoidCallback successCallback, RTCPeerConnectionErrorCallback failureCallback); + [Custom, RaisesException] Promise addIceCandidate(RTCIceCandidate candidate); readonly attribute DOMString iceGatheringState; readonly attribute DOMString iceConnectionState; - sequence getLocalStreams(); - sequence getRemoteStreams(); - MediaStream getStreamById(DOMString streamId); - RTCConfiguration getConfiguration(); - [StrictTypeChecking, RaisesException] void addStream(MediaStream stream); - [StrictTypeChecking, RaisesException] void removeStream(MediaStream stream); - void getStats(RTCStatsCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, [Default=Undefined] optional MediaStreamTrack selector); [RaisesException] RTCDataChannel createDataChannel([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString label, optional Dictionary options); - [RaisesException] RTCDTMFSender createDTMFSender(MediaStreamTrack track); - - [RaisesException] void close(); + void close(); attribute EventHandler onnegotiationneeded; attribute EventHandler onicecandidate; diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp new file mode 100644 index 0000000000000..e7983048d9287 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "RTCRtpSender.h" + +#if ENABLE(MEDIA_STREAM) + +#include "MediaStreamTrack.h" + +namespace WebCore { + +RefPtr RTCRtpSender::create(RefPtr&& track) +{ + return adoptRef(new RTCRtpSender(WTF::move(track))); +} + +RTCRtpSender::RTCRtpSender(RefPtr&& track) + : m_track(track) +{ +} + +RTCRtpSender::~RTCRtpSender() +{ +} + +MediaStreamTrack* RTCRtpSender::track() const +{ + return m_track.get(); +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.h b/Source/WebCore/Modules/mediastream/RTCRtpSender.h new file mode 100644 index 0000000000000..ba8509e166c73 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef RTCRtpSender_h +#define RTCRtpSender_h + +#if ENABLE(MEDIA_STREAM) + +#include "ScriptWrappable.h" +#include +#include + +namespace WebCore { + +class MediaStreamTrack; + +class RTCRtpSender : public RefCounted, public ScriptWrappable { +public: + static RefPtr create(RefPtr&&); + virtual ~RTCRtpSender(); + + MediaStreamTrack* track() const; + +private: + RTCRtpSender(RefPtr&&); + + RefPtr m_track; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // RTCRtpSender_h diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.idl b/Source/WebCore/Modules/mediastream/RTCRtpSender.idl new file mode 100644 index 0000000000000..8cb275537173b --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.idl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +[ + Conditional=MEDIA_STREAM +] interface RTCRtpSender { + readonly attribute MediaStreamTrack track; +}; diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp index 85bfb5c31e764..ef0b61747d256 100644 --- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp +++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp @@ -32,12 +32,10 @@ #include "config.h" #if ENABLE(MEDIA_STREAM) - #include "RTCSessionDescription.h" #include "Dictionary.h" #include "ExceptionCode.h" -#include "RTCSessionDescriptionDescriptor.h" namespace WebCore { @@ -46,7 +44,7 @@ static bool verifyType(const String& type) return type == "offer" || type == "pranswer" || type == "answer"; } -PassRefPtr RTCSessionDescription::create(const Dictionary& dictionary, ExceptionCode& ec) +RefPtr RTCSessionDescription::create(const Dictionary& dictionary, ExceptionCode& ec) { String type; bool ok = dictionary.get("type", type); @@ -62,17 +60,22 @@ PassRefPtr RTCSessionDescription::create(const Dictionary return nullptr; } - return adoptRef(new RTCSessionDescription(RTCSessionDescriptionDescriptor::create(type, sdp))); + return adoptRef(new RTCSessionDescription(type, sdp)); +} + +RefPtr RTCSessionDescription::create(const RTCSessionDescription* description) +{ + return adoptRef(new RTCSessionDescription(description->type(), description->sdp())); } -PassRefPtr RTCSessionDescription::create(PassRefPtr descriptor) +RefPtr RTCSessionDescription::create(const String& type, const String& sdp) { - ASSERT(descriptor); - return adoptRef(new RTCSessionDescription(descriptor)); + return adoptRef(new RTCSessionDescription(type, sdp)); } -RTCSessionDescription::RTCSessionDescription(PassRefPtr descriptor) - : m_descriptor(descriptor) +RTCSessionDescription::RTCSessionDescription(const String& type, const String& sdp) + : m_type(type) + , m_sdp(sdp) { } @@ -82,30 +85,25 @@ RTCSessionDescription::~RTCSessionDescription() const String& RTCSessionDescription::type() const { - return m_descriptor->type(); + return m_type; } void RTCSessionDescription::setType(const String& type, ExceptionCode& ec) { if (verifyType(type)) - m_descriptor->setType(type); + m_type = type; else ec = TYPE_MISMATCH_ERR; } const String& RTCSessionDescription::sdp() const { - return m_descriptor->sdp(); + return m_sdp; } void RTCSessionDescription::setSdp(const String& sdp) { - m_descriptor->setSdp(sdp); -} - -RTCSessionDescriptionDescriptor* RTCSessionDescription::descriptor() -{ - return m_descriptor.get(); + m_sdp = sdp; } } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h index fafe2b65a6b87..f6f1eec9e9881 100644 --- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h +++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h @@ -35,19 +35,19 @@ #include "ExceptionBase.h" #include "ScriptWrappable.h" -#include #include +#include #include namespace WebCore { class Dictionary; -class RTCSessionDescriptionDescriptor; class RTCSessionDescription : public RefCounted, public ScriptWrappable { public: - static PassRefPtr create(const Dictionary&, ExceptionCode&); - static PassRefPtr create(PassRefPtr); + static RefPtr create(const Dictionary&, ExceptionCode&); + static RefPtr create(const RTCSessionDescription*); + static RefPtr create(const String& type, const String& sdp); virtual ~RTCSessionDescription(); const String& type() const; @@ -56,12 +56,11 @@ class RTCSessionDescription : public RefCounted, public S const String& sdp() const; void setSdp(const String&); - RTCSessionDescriptionDescriptor* descriptor(); - private: - explicit RTCSessionDescription(PassRefPtr); + explicit RTCSessionDescription(const String& type, const String& sdp); - RefPtr m_descriptor; + String m_type; + String m_sdp; }; } // namespace WebCore diff --git a/Source/WebCore/PlatformGTK.cmake b/Source/WebCore/PlatformGTK.cmake index f2771425ed6cf..ef590ea2496eb 100644 --- a/Source/WebCore/PlatformGTK.cmake +++ b/Source/WebCore/PlatformGTK.cmake @@ -153,6 +153,7 @@ list(APPEND WebCore_SOURCES platform/linux/GamepadDeviceLinux.cpp platform/linux/MemoryPressureHandlerLinux.cpp + platform/mediastream/openwebrtc/MediaEndpointOwr.cpp platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp diff --git a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp index e5fe2aa154604..10951b3a67754 100644 --- a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp +++ b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,11 +27,18 @@ #include "config.h" #if ENABLE(MEDIA_STREAM) - #include "JSRTCPeerConnection.h" +#include "Dictionary.h" #include "ExceptionCode.h" #include "JSDOMBinding.h" +#include "JSDOMError.h" +#include "JSDOMPromise.h" +#include "JSRTCIceCandidate.h" +#include "JSRTCPeerConnectionErrorCallback.h" +#include "JSRTCSessionDescription.h" +#include "JSRTCSessionDescriptionCallback.h" +#include "JSVoidCallback.h" using namespace JSC; @@ -69,6 +77,172 @@ EncodedJSValue JSC_HOST_CALL constructJSRTCPeerConnection(ExecState* exec) return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), RTCPeerConnection, peerConnection.get())); } +static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnection::*implFunction)(const Dictionary&, RTCPeerConnection::OfferAnswerResolveCallback, RTCPeerConnection::RejectCallback, ExceptionCode&), JSDOMGlobalObject* globalObject, ExecState* exec) +{ + Dictionary options; + ExceptionCode ec = 0; + + if (exec->argumentCount() > 1 && exec->argument(0).isFunction() && exec->argument(1).isFunction()) { + // legacy callbacks mode + if (exec->argumentCount() > 2) { + options = Dictionary(exec, exec->argument(2)); + if (!options.isObject()) { + throwVMError(exec, createTypeError(exec, "Third argument must be a valid Dictionary")); + return jsUndefined(); + } + } + + RefPtr sessionDescriptionCallback = JSRTCSessionDescriptionCallback::create(asObject(exec->argument(0)), globalObject); + RefPtr errorCallback = JSRTCPeerConnectionErrorCallback::create(asObject(exec->argument(1)), globalObject); + + auto resolveCallback = [sessionDescriptionCallback](RefPtr description) mutable { + sessionDescriptionCallback->handleEvent(description.get()); + }; + auto rejectCallback = [errorCallback](RefPtr error) mutable { + errorCallback->handleEvent(error.get()); + }; + + (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + // Promised-based mode + if (exec->argumentCount()) { + options = Dictionary(exec, exec->argument(0)); + if (!options.isObject()) { + throwVMError(exec, createTypeError(exec, "First argument must be a valid Dictionary")); + return jsUndefined(); + } + } + + DeferredWrapper wrapper(exec, globalObject); + auto resolveCallback = [wrapper](RefPtr description) mutable { + wrapper.resolve(description.get()); + }; + auto rejectCallback = [wrapper](RefPtr error) mutable { + wrapper.reject(error.get()); + }; + + (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + + return wrapper.promise(); +} + +JSValue JSRTCPeerConnection::createOffer(ExecState* exec) +{ + return createOfferOrAnswer(impl(), &RTCPeerConnection::createOffer, globalObject(), exec); +} + +JSValue JSRTCPeerConnection::createAnswer(ExecState* exec) +{ + return createOfferOrAnswer(impl(), &RTCPeerConnection::createAnswer, globalObject(), exec); +} + +static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPeerConnection::*implFunction)(RTCSessionDescription*, RTCPeerConnection::VoidResolveCallback, RTCPeerConnection::RejectCallback, ExceptionCode&), JSDOMGlobalObject* globalObject, ExecState* exec) +{ + ExceptionCode ec = 0; + + RefPtr description = JSRTCSessionDescription::toWrapped(exec->argument(0)); + if (!description) { + throwVMError(exec, createTypeError(exec, "First argument must be a RTCSessionDescription")); + return jsUndefined(); + } + + if (exec->argumentCount() > 2 && exec->argument(1).isFunction() && exec->argument(2).isFunction()) { + // legacy callbacks mode + RefPtr voidCallback = JSVoidCallback::create(asObject(exec->argument(1)), globalObject); + RefPtr errorCallback = JSRTCPeerConnectionErrorCallback::create(asObject(exec->argument(2)), globalObject); + + auto resolveCallback = [voidCallback]() mutable { + voidCallback->handleEvent(); + }; + auto rejectCallback = [errorCallback](RefPtr error) mutable { + errorCallback->handleEvent(error.get()); + }; + + (impl.*implFunction)(description.get() , WTF::move(resolveCallback), WTF::move(rejectCallback), ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + // Promised-based mode + DeferredWrapper wrapper(exec, globalObject); + auto resolveCallback = [wrapper]() mutable { + wrapper.resolve(false); + }; + auto rejectCallback = [wrapper](RefPtr error) mutable { + wrapper.reject(error.get()); + }; + + (impl.*implFunction)(description.get(), WTF::move(resolveCallback), WTF::move(rejectCallback), ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + + return wrapper.promise(); +} + +JSValue JSRTCPeerConnection::setLocalDescription(ExecState* exec) +{ + return setLocalOrRemoteDescription(impl(), &RTCPeerConnection::setLocalDescription, globalObject(), exec); +} + +JSValue JSRTCPeerConnection::setRemoteDescription(ExecState* exec) +{ + return setLocalOrRemoteDescription(impl(), &RTCPeerConnection::setRemoteDescription, globalObject(), exec); +} + +JSValue JSRTCPeerConnection::addIceCandidate(ExecState* exec) +{ + ExceptionCode ec = 0; + + RefPtr candidate = JSRTCIceCandidate::toWrapped(exec->argument(0)); + if (!candidate) { + throwVMError(exec, createTypeError(exec, "First argument must be a RTCIceCandidate")); + return jsUndefined(); + } + + if (exec->argumentCount() > 2 && exec->argument(1).isFunction() && exec->argument(2).isFunction()) { + // legacy callbacks mode + RefPtr voidCallback = JSVoidCallback::create(asObject(exec->argument(1)), globalObject()); + RefPtr errorCallback = JSRTCPeerConnectionErrorCallback::create(asObject(exec->argument(2)), globalObject()); + + auto resolveCallback = [voidCallback]() mutable { + voidCallback->handleEvent(); + }; + auto rejectCallback = [errorCallback](RefPtr error) mutable { + errorCallback->handleEvent(error.get()); + }; + + impl().addIceCandidate(candidate.get() , WTF::move(resolveCallback), WTF::move(rejectCallback), ec); + setDOMException(exec, ec); + return jsUndefined(); + } + + // Promised-based mode + DeferredWrapper wrapper(exec, globalObject()); + auto resolveCallback = [wrapper]() mutable { + wrapper.resolve(false); + }; + auto rejectCallback = [wrapper](RefPtr error) mutable { + wrapper.reject(error.get()); + }; + + impl().addIceCandidate(candidate.get(), WTF::move(resolveCallback), WTF::move(rejectCallback), ec); + if (ec) { + setDOMException(exec, ec); + return jsUndefined(); + } + + return wrapper.promise(); +} + } // namespace WebCore #endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/platform/mediastream/IceCandidate.h b/Source/WebCore/platform/mediastream/IceCandidate.h new file mode 100644 index 0000000000000..b904f9a9965b1 --- /dev/null +++ b/Source/WebCore/platform/mediastream/IceCandidate.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef IceCandidate_h +#define IceCandidate_h + +#if ENABLE(MEDIA_STREAM) + +#include +#include +#include + +namespace WebCore { + +class IceCandidate : public RefCounted { +public: + static RefPtr create() + { + return adoptRef(new IceCandidate()); + } + virtual ~IceCandidate() { } + + const String& type() const { return m_type; } + void setType(const String& type) { m_type = type; } + + const String& foundation() const { return m_foundation; } + void setFoundation(const String& foundation) { m_foundation = foundation; } + + unsigned componentId() const { return m_componentId; } + void setComponentId(unsigned componentId) { m_componentId = componentId; } + + const String& transport() const { return m_transport; } + void setTransport(const String& transport) { m_transport = transport; } + +private: + IceCandidate() { } + + String m_type; + String m_foundation; + unsigned m_componentId; + String m_transport; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // IceCandidate_h diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.cpp b/Source/WebCore/platform/mediastream/MediaEndpoint.cpp new file mode 100644 index 0000000000000..e1f5d7e438f32 --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.cpp @@ -0,0 +1,21 @@ +/* + * + */ + +#include "config.h" + +#if ENABLE(MEDIA_STREAM) +#include "MediaEndpoint.h" + +namespace WebCore { + +static std::unique_ptr createMediaEndpoint(MediaEndpointClient*) +{ + return nullptr; +} + +CreateMediaEndpoint MediaEndpoint::create = createMediaEndpoint; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h new file mode 100644 index 0000000000000..b29f0be07851e --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef MediaEndpoint_h +#define MediaEndpoint_h + +#if ENABLE(MEDIA_STREAM) + +#include "RTCConfigurationPrivate.h" +#include + +namespace WebCore { + +class IceCandidate; +class MediaEndpoint; +class MediaEndpointConfiguration; +class RealTimeMediaSource; // not implemented + +class MediaEndpointClient { +public: + virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) = 0; + virtual void gotDtlsFingerprint(unsigned mdescIndex, const String& fingerprint, const String& hashFunction) = 0; + virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) = 0; + virtual void doneGatheringCandidates(unsigned mdescIndex) = 0; + virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) = 0; + + virtual ~MediaEndpointClient() { } +}; + +typedef std::unique_ptr (*CreateMediaEndpoint)(MediaEndpointClient*); + +class MediaEndpoint { +public: + WEBCORE_EXPORT static CreateMediaEndpoint create; + virtual ~MediaEndpoint() { } + + virtual void setConfiguration(RefPtr&&) = 0; + + virtual void prepareToReceive(MediaEndpointConfiguration*, bool isInitiator) = 0; + virtual void prepareToSend(MediaEndpointConfiguration*, bool isInitiator) = 0; + + virtual void addRemoteCandidate(IceCandidate *) = 0; + + virtual void stop() = 0; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // MediaEndpoint_h diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h new file mode 100644 index 0000000000000..32f3341ee595f --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef MediaEndpointConfiguration_h +#define MediaEndpointConfiguration_h + +#if ENABLE(MEDIA_STREAM) + +#include "PeerMediaDescription.h" + +namespace WebCore { + +class MediaEndpointConfiguration : public RefCounted { +public: + static RefPtr create() + { + return adoptRef(new MediaEndpointConfiguration()); + } + virtual ~MediaEndpointConfiguration() { } + + unsigned long sessionId() const { return m_sessionId; } + void setSessionId(unsigned long sessionId) { m_sessionId = sessionId; } + + const Vector>& mediaDescriptions() const { return m_mediaDescriptions; } + void addMediaDescription(RefPtr&& description) { m_mediaDescriptions.append(WTF::move(description)); } + +private: + MediaEndpointConfiguration() { } + + unsigned long m_sessionId; + + Vector> m_mediaDescriptions; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // MediaEndpointConfiguration_h diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp new file mode 100644 index 0000000000000..5218cd3303095 --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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" + +#if ENABLE(MEDIA_STREAM) +#include "MediaEndpointConfigurationConversions.h" + +#include "inspector/InspectorValues.h" + +using namespace JSC; +using namespace Inspector; + +namespace WebCore { + +namespace MediaEndpointConfigurationConversions { + +// Note that MediaEndpointConfiguration is a "flatter" structure that the JSON representation. For +// example, the JSON representation has an "ice" object which collects a set of properties under a +// namespace. MediaEndpointConfiguration has "ice"-prefixes on the corresponding properties. + +static RefPtr createCandidateObject(IceCandidate* candidate) +{ + RefPtr candidateObject = InspectorObject::create(); + + candidateObject->setString(ASCIILiteral("type"), candidate->type()); + candidateObject->setString(ASCIILiteral("foundation"), candidate->foundation()); + candidateObject->setInteger(ASCIILiteral("componentId"), candidate->componentId()); + candidateObject->setString(ASCIILiteral("transport"), candidate->transport()); + + return candidateObject; +} + +static RefPtr createCandidate(InspectorObject* candidateObject) +{ + RefPtr candidate = IceCandidate::create(); + String stringValue; + unsigned intValue; + + if (candidateObject->getString(ASCIILiteral("type"), stringValue)) + candidate->setType(stringValue); + + if (candidateObject->getString(ASCIILiteral("foundation"), stringValue)) + candidate->setFoundation(stringValue); + + if (candidateObject->getInteger(ASCIILiteral("componentId"), intValue)) + candidate->setComponentId(intValue); + + if (candidateObject->getString(ASCIILiteral("transport"), stringValue)) + candidate->setTransport(stringValue); + + return candidate; +} + +RefPtr fromJSON(const String& json) +{ + RefPtr value; + if (!InspectorValue::parseJSON(json, value)) + return nullptr; + + RefPtr object; + if (!value->asObject(object)) + return nullptr; + + RefPtr configuration = MediaEndpointConfiguration::create(); + + String stringValue; + unsigned intValue; + unsigned long longValue; + bool boolValue; + + RefPtr originatorObject = InspectorObject::create(); + if (object->getObject(ASCIILiteral("originator"), originatorObject)) { + if (originatorObject->getInteger(ASCIILiteral("sessionId"), longValue)) + configuration->setSessionId(longValue); + } + + RefPtr mediaDescriptionsArray = InspectorArray::create(); + object->getArray(ASCIILiteral("mediaDescriptions"), mediaDescriptionsArray); + + for (unsigned i = 0; i < mediaDescriptionsArray->length(); ++i) { + RefPtr mdescObject = InspectorObject::create(); + mediaDescriptionsArray->get(i)->asObject(mdescObject); + + RefPtr mdesc = PeerMediaDescription::create(); + + if (mdescObject->getString(ASCIILiteral("type"), stringValue)) + mdesc->setType(stringValue); + + if (mdescObject->getInteger(ASCIILiteral("port"), intValue)) + mdesc->setPort(intValue); + + RefPtr payloadsArray = InspectorArray::create(); + mdescObject->getArray(ASCIILiteral("payloads"), payloadsArray); + + for (unsigned j = 0; j < payloadsArray->length(); ++j) { + RefPtr payloadsObject = InspectorObject::create(); + payloadsArray->get(j)->asObject(payloadsObject); + + RefPtr payload = MediaPayload::create(); + + if (payloadsObject->getInteger(ASCIILiteral("type"), intValue)) + payload->setType(intValue); + + if (payloadsObject->getString(ASCIILiteral("encodingName"), stringValue)) + payload->setEncodingName(stringValue); + + mdesc->addPayload(WTF::move(payload)); + } + + RefPtr rtcpObject = InspectorObject::create(); + if (mdescObject->getObject(ASCIILiteral("rtcp"), rtcpObject)) { + if (rtcpObject->getBoolean(ASCIILiteral("mux"), boolValue)) + mdesc->setRtcpMux(boolValue); + } + + if (mdescObject->getString(ASCIILiteral("mediaStreamId"), stringValue)) + mdesc->setMediaStreamId(stringValue); + + if (mdescObject->getString(ASCIILiteral("mediaStreamTrackId"), stringValue)) + mdesc->setMediaStreamTrackId(stringValue); + + RefPtr dtlsObject = InspectorObject::create(); + if (mdescObject->getObject(ASCIILiteral("dtls"), dtlsObject)) { + if (dtlsObject->getString(ASCIILiteral("setup"), stringValue)) + mdesc->setDtlsSetup(stringValue); + } + + RefPtr iceObject = InspectorObject::create(); + if (mdescObject->getObject(ASCIILiteral("ice"), iceObject)) { + if (iceObject->getString(ASCIILiteral("ufrag"), stringValue)) + mdesc->setIceUfrag(stringValue); + + if (iceObject->getString(ASCIILiteral("password"), stringValue)) + mdesc->setIcePassword(stringValue); + + RefPtr candidatesArray = InspectorArray::create(); + iceObject->getArray(ASCIILiteral("candidates"), candidatesArray); + + for (unsigned j = 0; j < candidatesArray->length(); ++j) { + RefPtr candidateObject = InspectorObject::create(); + candidatesArray->get(j)->asObject(candidateObject); + + mdesc->addIceCandidate(createCandidate(candidateObject.get())); + } + } + + configuration->addMediaDescription(WTF::move(mdesc)); + } + + return configuration; +} + +RefPtr iceCandidateFromJSON(const String& json) +{ + RefPtr value; + if (!InspectorValue::parseJSON(json, value)) + return nullptr; + + RefPtr candidateObject; + if (!value->asObject(candidateObject)) + return nullptr; + + return createCandidate(candidateObject.get()); +} + +String toJSON(MediaEndpointConfiguration* configuration) +{ + RefPtr object = InspectorObject::create(); + + RefPtr originatorObject = InspectorObject::create(); + originatorObject->setInteger(ASCIILiteral("sessionId"), configuration->sessionId()); + object->setObject(ASCIILiteral("originator"), originatorObject); + + RefPtr mediaDescriptionsArray = InspectorArray::create(); + + for (const RefPtr& mdesc : configuration->mediaDescriptions()) { + RefPtr mdescObject = InspectorObject::create(); + + mdescObject->setString(ASCIILiteral("type"), mdesc->type()); + mdescObject->setInteger(ASCIILiteral("port"), mdesc->port()); + + RefPtr payloadsArray = InspectorArray::create(); + + for (RefPtr payload : mdesc->payloads()) { + RefPtr payloadObject = InspectorObject::create(); + + payloadObject->setInteger(ASCIILiteral("type"), payload->type()); + payloadObject->setString(ASCIILiteral("encodingName"), payload->encodingName()); + + payloadsArray->pushObject(payloadObject); + } + mdescObject->setArray(ASCIILiteral("payloads"), payloadsArray); + + RefPtr rtcpObject = InspectorObject::create(); + rtcpObject->setBoolean(ASCIILiteral("mux"), mdesc->rtcpMux()); + mdescObject->setObject(ASCIILiteral("rtcp"), rtcpObject); + + mdescObject->setString(ASCIILiteral("mediaStreamId"), mdesc->mediaStreamId()); + mdescObject->setString(ASCIILiteral("mediaStreamTrackId"), mdesc->mediaStreamTrackId()); + + RefPtr dtlsObject = InspectorObject::create(); + dtlsObject->setString(ASCIILiteral("setup"), mdesc->dtlsSetup()); + mdescObject->setObject(ASCIILiteral("dtls"), dtlsObject); + + RefPtr iceObject = InspectorObject::create(); + iceObject->setString(ASCIILiteral("ufrag"), mdesc->iceUfrag()); + iceObject->setString(ASCIILiteral("password"), mdesc->icePassword()); + + RefPtr candidatesArray = InspectorArray::create(); + + for (RefPtr candidate : mdesc->iceCandidates()) + candidatesArray->pushObject(createCandidateObject(candidate.get())); + + iceObject->setArray(ASCIILiteral("candidates"), candidatesArray); + mdescObject->setObject(ASCIILiteral("ice"), iceObject); + + mediaDescriptionsArray->pushObject(mdescObject); + } + object->setArray(ASCIILiteral("mediaDescriptions"), mediaDescriptionsArray); + + return object->toJSONString(); +} + +String iceCandidateToJSON(IceCandidate* candidate) +{ + return createCandidateObject(candidate)->toJSONString(); +} + +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.h b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.h new file mode 100644 index 0000000000000..a1499ebdde397 --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef MediaEndpointConfigurationConversions_h +#define MediaEndpointConfigurationConversions_h + +#if ENABLE(MEDIA_STREAM) + +#include "MediaEndpointConfiguration.h" + +namespace WebCore { + +namespace MediaEndpointConfigurationConversions { + +RefPtr fromJSON(const String&); +String toJSON(MediaEndpointConfiguration*); + +RefPtr iceCandidateFromJSON(const String&); +String iceCandidateToJSON(IceCandidate*); + +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // MediaEndpointConfigurationConversions_h diff --git a/Source/WebCore/platform/mediastream/MediaPayload.h b/Source/WebCore/platform/mediastream/MediaPayload.h new file mode 100644 index 0000000000000..64d62098d381f --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaPayload.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef MediaPayload_h +#define MediaPayload_h + +#if ENABLE(MEDIA_STREAM) + +#include +#include + +namespace WebCore { + +class MediaPayload : public RefCounted { +public: + static RefPtr create() + { + return adoptRef(new MediaPayload()); + } + virtual ~MediaPayload() { } + + unsigned type() const { return m_type; } + void setType(unsigned type) { m_type = type; } + + const String& encodingName() const { return m_encodingName; } + void setEncodingName(const String & encodingName) { m_encodingName = encodingName; } + + unsigned clockRate() const { return m_clockRate; } + +private: + MediaPayload() { } + + unsigned m_type; + String m_encodingName; + unsigned m_clockRate; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // MediaPayload_h diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h new file mode 100644 index 0000000000000..b88bdb14b43c8 --- /dev/null +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef PeerMediaDescription_h +#define PeerMediaDescription_h + +#if ENABLE(MEDIA_STREAM) + +#include "IceCandidate.h" +#include "MediaPayload.h" +#include +#include + +namespace WebCore { + +class PeerMediaDescription : public RefCounted { +public: + static RefPtr create() + { + return adoptRef(new PeerMediaDescription()); + } + virtual ~PeerMediaDescription() { } + + const String& type() const { return m_type; } + void setType(const String& type) { m_type = type; } + + unsigned short port() const { return m_port; } + void setPort(unsigned short port) { m_port = port; } + + const Vector>& payloads() const { return m_payloads; } + void addPayload(RefPtr&& payload) { m_payloads.append(WTF::move(payload)); } + + bool rtcpMux() const { return m_rtcpMux; } + void setRtcpMux(bool rtcpMux) { m_rtcpMux = rtcpMux; } + + const String& mediaStreamId() const { return m_mediaStreamId; } + void setMediaStreamId(const String& mediaStreamId) { m_mediaStreamId = mediaStreamId; } + + const String& mediaStreamTrackId() const { return m_mediaStreamTrackId; } + void setMediaStreamTrackId(const String& mediaStreamTrackId) { m_mediaStreamTrackId = mediaStreamTrackId; } + + const String& dtlsSetup() const { return m_dtlsSetup; } + void setDtlsSetup(const String& dtlsSetup) { m_dtlsSetup = dtlsSetup; } + + const String& iceUfrag() const { return m_iceUfrag; } + void setIceUfrag(const String& iceUfrag) { m_iceUfrag = iceUfrag; } + + const String& icePassword() const { return m_icePassword; } + void setIcePassword(const String& icePassword) { m_icePassword = icePassword; } + + const Vector>& iceCandidates() const { return m_iceCandidates; } + void addIceCandidate(RefPtr&& candidate) { m_iceCandidates.append(WTF::move(candidate)); } + +private: + PeerMediaDescription() { } + + String m_type; + unsigned short m_port; + + Vector> m_payloads; + + bool m_rtcpMux; + + String m_mediaStreamId; + String m_mediaStreamTrackId; + + String m_dtlsSetup; + + String m_iceUfrag; + String m_icePassword; + Vector> m_iceCandidates; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // PeerMediaDescription_h diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp new file mode 100644 index 0000000000000..a4e57a09a0771 --- /dev/null +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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" + +#if ENABLE(MEDIA_STREAM) +#include "MediaEndpointOwr.h" + +#include "MediaEndpointConfiguration.h" +#include "OpenWebRTCUtilities.h" +#include +#include + +namespace WebCore { + +static void gotCandidate(OwrMediaSession*, OwrCandidate*, MediaEndpointOwr*); +static void candidateGatheringDone(OwrMediaSession*, MediaEndpointOwr*); + +static char* iceCandidateTypes[] = { "host", "srflx", "relay", nullptr }; + +static std::unique_ptr createMediaEndpointOwr(MediaEndpointClient* client) +{ + return std::unique_ptr(new MediaEndpointOwr(client)); +} + +CreateMediaEndpoint MediaEndpoint::create = createMediaEndpointOwr; + +MediaEndpointOwr::MediaEndpointOwr(MediaEndpointClient* client) + : m_transportAgent(nullptr) + , m_client(client) + , m_numberOfReceivePreparedMediaSessions(0) + , m_numberOfSendPreparedMediaSessions(0) +{ + initializeOpenWebRTC(); +} + +MediaEndpointOwr::~MediaEndpointOwr() +{ + if (m_transportAgent) + g_object_unref(m_transportAgent); +} + +void MediaEndpointOwr::setConfiguration(RefPtr&& configuration) +{ + m_configuration = configuration; +} + +void MediaEndpointOwr::prepareToReceive(MediaEndpointConfiguration* configuration, bool isInitiator) +{ + Vector dtlsRoles; + for (unsigned i = m_mediaSessions.size(); i < configuration->mediaDescriptions().size(); ++i) + dtlsRoles.append(configuration->mediaDescriptions()[i]->dtlsSetup()); + + ensureTransportAgentAndMediaSessions(isInitiator, dtlsRoles); + + // prepare the new media sessions + for (unsigned i = m_numberOfReceivePreparedMediaSessions; i < m_mediaSessions.size(); ++i) + prepareMediaSession(i, m_mediaSessions[i], configuration->mediaDescriptions()[i].get()); + + m_numberOfReceivePreparedMediaSessions = m_mediaSessions.size(); +} + +void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration* configuration, bool isInitiator) +{ + printf("-> MediaEndpointOwr::prepareToSend\n"); +} + +void MediaEndpointOwr::addRemoteCandidate(IceCandidate* candidate) +{ + OwrCandidateType candidateType; + OwrComponentType componentType = (OwrComponentType) candidate->componentId(); + + if (candidate->type() == "host") + candidateType = OWR_CANDIDATE_TYPE_HOST; + else if (candidate->type() == "srflx") + candidateType = OWR_CANDIDATE_TYPE_SERVER_REFLEXIVE; + else + candidateType = OWR_CANDIDATE_TYPE_RELAY; + + OwrCandidate* remoteCandidate = owr_candidate_new(candidateType, componentType); + + printf("MediaEndpointOwr::addRemoteCandidate: created candidate: %p\n", remoteCandidate); +} + +void MediaEndpointOwr::stop() +{ + printf("MediaEndpointOwr::stop\n"); +} + +unsigned MediaEndpointOwr::mediaSessionIndex(OwrMediaSession* mediaSession) const +{ + unsigned index = m_mediaSessions.find(mediaSession); + ASSERT(index != notFound); + return index; +} + +void MediaEndpointOwr::dispatchNewIceCandidate(unsigned mediaSessionIndex, RefPtr&& iceCandidate) +{ + m_client->gotIceCandidate(mediaSessionIndex, WTF::move(iceCandidate)); +} + +void MediaEndpointOwr::dispatchGatheringDone(unsigned mediaSessionIndex) +{ + m_client->doneGatheringCandidates(mediaSessionIndex); +} + +void MediaEndpointOwr::prepareMediaSession(unsigned mdescIndex, OwrMediaSession* mediaSession, PeerMediaDescription*) +{ + g_signal_connect(mediaSession, "on-new-candidate", G_CALLBACK(gotCandidate), this); + g_signal_connect(mediaSession, "on-candidate-gathering-done", G_CALLBACK(candidateGatheringDone), this); + + owr_transport_agent_add_session(m_transportAgent, OWR_SESSION(mediaSession)); +} + +void MediaEndpointOwr::ensureTransportAgentAndMediaSessions(bool isInitiator, const Vector& newMediaSessionDtlsRoles) +{ + if (!m_transportAgent) { + m_transportAgent = owr_transport_agent_new(false); + + for (unsigned i = 0; i < m_configuration->numberOfServers(); ++i) { + RTCIceServerPrivate* server = m_configuration->server(i); + + // FIXME: parse url type and port + owr_transport_agent_add_helper_server(m_transportAgent, OWR_HELPER_SERVER_TYPE_STUN, + server->urls()[0].ascii().data(), 3478, nullptr, nullptr); + } + } + + g_object_set(m_transportAgent, "ice-controlling-mode", isInitiator, nullptr); + + for (auto role : newMediaSessionDtlsRoles) + m_mediaSessions.append(owr_media_session_new(role == "active")); +} + +static void gotCandidate(OwrMediaSession* mediaSession, OwrCandidate* candidate, MediaEndpointOwr* mediaEndpoint) +{ + OwrCandidateType candidateType; + OwrComponentType componentType; + OwrTransportType transportType; + gchar* foundation; + gchar* address; + gchar* relatedAddress; + gint port, priority, relatedPort; + + g_object_get(candidate, "type", &candidateType, + "component-type", &componentType, + "foundation", &foundation, + "transport-type", &transportType, + "address", &address, + "port", &port, + "priority", &priority, + "base-address", &relatedAddress, + "base-port", &relatedPort, nullptr); + + printf("candidateType: %d, foundation: %s, address: %s, port %d\n", candidateType, foundation, address, port); + + RefPtr iceCandidate = IceCandidate::create(); + iceCandidate->setType(iceCandidateTypes[candidateType]); + iceCandidate->setFoundation(foundation); + iceCandidate->setTransport(transportType == OWR_TRANSPORT_TYPE_UDP ? "UDP" : "TCP"); + // FIXME: set the rest + + mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->mediaSessionIndex(mediaSession), WTF::move(iceCandidate)); +} + +static void candidateGatheringDone(OwrMediaSession* mediaSession, MediaEndpointOwr* mediaEndpoint) +{ + mediaEndpoint->dispatchGatheringDone(mediaEndpoint->mediaSessionIndex(mediaSession)); +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h new file mode 100644 index 0000000000000..0ace34849cbf0 --- /dev/null +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef MediaEndpointOwr_h +#define MediaEndpointOwr_h + +#if ENABLE(MEDIA_STREAM) + +#include "MediaEndpoint.h" +#include +#include + +namespace WebCore { + +class PeerMediaDescription; +class RTCConfigurationPrivate; + +class MediaEndpointOwr : public MediaEndpoint { +public: + MediaEndpointOwr(MediaEndpointClient*); + ~MediaEndpointOwr(); + + virtual void setConfiguration(RefPtr&&) override; + + virtual void prepareToReceive(MediaEndpointConfiguration*, bool isInitiator) override; + virtual void prepareToSend(MediaEndpointConfiguration*, bool isInitiator) override; + + virtual void addRemoteCandidate(IceCandidate*) override; + + virtual void stop() override; + + unsigned mediaSessionIndex(OwrMediaSession*) const; + + void dispatchNewIceCandidate(unsigned mediaSessionIndex, RefPtr&&); + void dispatchGatheringDone(unsigned mediaSessionIndex); + +private: + void prepareMediaSession(unsigned mdescIndex, OwrMediaSession*, PeerMediaDescription*); + void ensureTransportAgentAndMediaSessions(bool isInitiator, const Vector& newMediaSessionDtlsRoles); + + RefPtr m_configuration; + + OwrTransportAgent* m_transportAgent; + Vector m_mediaSessions; + + MediaEndpointClient* m_client; + + unsigned m_numberOfReceivePreparedMediaSessions; + unsigned m_numberOfSendPreparedMediaSessions; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // MediaEndpointOwr_h diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp index 0c37e99e75ade..8b889c33fe09e 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp @@ -164,7 +164,6 @@ void RealtimeMediaSourceCenterOwr::mediaSourcesAvailable(GList* sources) RealtimeMediaSourceOwrMap::iterator sourceIterator = m_sourceMap.find(id); if (sourceIterator == m_sourceMap.end()) m_sourceMap.add(id, mediaSource); - } // TODO: Make sure contraints are actually validated by checking source types. From 84be31acdbd1c694c4b7f019c9743fd022314060 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 30 Mar 2015 11:09:26 +0200 Subject: [PATCH 007/155] MediaStreamTrack: Align stop() function with spec (not 100% yet) --- .../Modules/mediastream/MediaStreamTrack.cpp | 13 +++++++------ .../mediastream/MediaStreamTrackPrivate.cpp | 12 ++++++++---- .../platform/mediastream/MediaStreamTrackPrivate.h | 3 +-- .../platform/mediastream/RealtimeMediaSource.cpp | 3 --- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index eb60d2f12b073..a144db79ec945 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -205,11 +205,12 @@ void MediaStreamTrack::stopProducingData() // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires // a "stop" method. - // The stop method should "Permanently stop the generation of data for track's source", but it - // should not post an 'ended' event. - m_stoppingTrack = true; - m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackAndStopSource); - m_stoppingTrack = false; + if (remote()) + return; + + // FIXME: This object needs its own ended member. + + m_privateTrack->detachSource(); } bool MediaStreamTrack::ended() const @@ -276,7 +277,7 @@ void MediaStreamTrack::configureTrackRendering() void MediaStreamTrack::stop() { - m_privateTrack->stop(MediaStreamTrackPrivate::StopTrackOnly); + stopProducingData(); } const char* MediaStreamTrack::activeDOMObjectName() const diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 5e9512ccb84b9..a8f808b083000 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -172,16 +172,20 @@ void MediaStreamTrackPrivate::setEnabled(bool enabled) m_client->trackEnabledChanged(); } -void MediaStreamTrackPrivate::stop(StopBehavior stopSource) +void MediaStreamTrackPrivate::detachSource() { if (m_stopped) return; - if (stopSource == StopTrackAndStopSource && m_source) - m_source->stop(); + // The source will stop itself when out of consumers (observers in this case). + m_source->removeObserver(this); + m_source = nullptr; - setReadyState(RealtimeMediaSource::Ended); m_stopped = true; + + m_ignoreMutations = true; + setReadyState(RealtimeMediaSource::Ended); + m_ignoreMutations = false; } RealtimeMediaSource::ReadyState MediaStreamTrackPrivate::readyState() const diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index b03e46f54be19..071dba340ef66 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -74,8 +74,7 @@ class MediaStreamTrackPrivate : public RefCounted, publ RealtimeMediaSource* source() const { return m_source.get(); } void setSource(PassRefPtr); - enum StopBehavior { StopTrackAndStopSource, StopTrackOnly }; - void stop(StopBehavior); + void detachSource(); bool stopped() const { return m_stopped; } void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; } diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp index 2630248a6d5af..ea7f6c4f6af78 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp @@ -116,9 +116,6 @@ bool RealtimeMediaSource::readonly() const void RealtimeMediaSource::stop() { - // This is called from the track.stop() method, which should "Permanently stop the generation of data - // for track's source", so go straight to ended. This will notify any other tracks using this source - // that it is no longer available. setReadyState(Ended); } From 4409b8e2158ef0bffc2e058c39687139a1e7e6f9 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 30 Mar 2015 11:30:28 +0200 Subject: [PATCH 008/155] MediaStreamTrackPrivateClient: Remove enabled notification (only south bound) --- Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp | 9 --------- Source/WebCore/Modules/mediastream/MediaStreamTrack.h | 1 - .../platform/mediastream/MediaStreamTrackPrivate.cpp | 5 ----- .../platform/mediastream/MediaStreamTrackPrivate.h | 1 - 4 files changed, 16 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index a144db79ec945..e84068f304eec 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -257,15 +257,6 @@ void MediaStreamTrack::trackMutedChanged() configureTrackRendering(); } -void MediaStreamTrack::trackEnabledChanged() -{ - if (stopped()) - return; - - setEnabled(m_privateTrack->enabled()); - configureTrackRendering(); -} - void MediaStreamTrack::configureTrackRendering() { if (stopped()) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 9be386fcc2473..d57cef9071776 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -119,7 +119,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip // MediaStreamTrackPrivateClient void trackEnded(); void trackMutedChanged(); - void trackEnabledChanged(); Vector> m_scheduledEvents; diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index a8f808b083000..3de70a61cab24 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -165,11 +165,6 @@ void MediaStreamTrackPrivate::setEnabled(bool enabled) // ... after a MediaStreamTrack is disassociated from its track, its enabled attribute still // changes value when set; it just doesn't do anything with that new value. m_enabled = enabled; - - if (!m_client || m_ignoreMutations) - return; - - m_client->trackEnabledChanged(); } void MediaStreamTrackPrivate::detachSource() diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 071dba340ef66..a982ba931a26c 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -44,7 +44,6 @@ class MediaStreamTrackPrivateClient { virtual void trackEnded() = 0; virtual void trackMutedChanged() = 0; - virtual void trackEnabledChanged() = 0; }; class MediaStreamTrackPrivate : public RefCounted, public RealtimeMediaSource::Observer { From ac0dc8c165a33c7b1559b0ca9d9a2c6b0500927c Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 30 Mar 2015 12:04:28 +0200 Subject: [PATCH 009/155] MediaStreamTrackPrivate: Removed stopped concept (same as having no source attached) --- .../Modules/mediastream/MediaStreamTrack.cpp | 14 ----------- .../Modules/mediastream/MediaStreamTrack.h | 1 - .../mediastream/MediaStreamTrackPrivate.cpp | 23 ++++--------------- .../mediastream/MediaStreamTrackPrivate.h | 2 -- 4 files changed, 5 insertions(+), 35 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index e84068f304eec..80e731b51b57b 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -121,11 +121,6 @@ void MediaStreamTrack::setEnabled(bool enabled) m_privateTrack->setEnabled(enabled); } -bool MediaStreamTrack::stopped() const -{ - return m_privateTrack->stopped(); -} - bool MediaStreamTrack::muted() const { return m_privateTrack->muted(); @@ -232,9 +227,6 @@ void MediaStreamTrack::removeObserver(MediaStreamTrack::Observer* observer) void MediaStreamTrack::trackEnded() { - if (stopped()) - return; - if (!m_stoppingTrack) scheduleEventDispatch(Event::create(eventNames().endedEvent, false, false)); @@ -246,9 +238,6 @@ void MediaStreamTrack::trackEnded() void MediaStreamTrack::trackMutedChanged() { - if (stopped()) - return; - if (muted()) scheduleEventDispatch(Event::create(eventNames().muteEvent, false, false)); else @@ -259,9 +248,6 @@ void MediaStreamTrack::trackMutedChanged() void MediaStreamTrack::configureTrackRendering() { - if (stopped()) - return; - // 4.3.1 // ... media from the source only flows when a MediaStreamTrack object is both unmuted and enabled } diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index d57cef9071776..ebeef6e688046 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -70,7 +70,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip bool muted() const; bool readonly() const; bool remote() const; - bool stopped() const; const AtomicString& readyState() const; diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 3de70a61cab24..579f0b07266f3 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -51,7 +51,6 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& m_readyState = other.readyState(); m_muted = other.muted(); m_enabled = other.enabled(); - m_stopped = other.stopped(); m_ignoreMutations = false; } @@ -61,7 +60,6 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr , m_readyState(RealtimeMediaSource::Live) , m_muted(false) , m_enabled(true) - , m_stopped(false) { m_ignoreMutations = true; setSource(source); @@ -116,12 +114,12 @@ const String& MediaStreamTrackPrivate::label() const bool MediaStreamTrackPrivate::ended() const { - return m_stopped || (m_source && m_source->readyState() == RealtimeMediaSource::Ended); + return m_source && m_source->readyState() == RealtimeMediaSource::Ended; } bool MediaStreamTrackPrivate::muted() const { - if (m_stopped || !m_source) + if (!m_source) return false; return m_source->muted(); @@ -142,7 +140,7 @@ void MediaStreamTrackPrivate::setMuted(bool muted) bool MediaStreamTrackPrivate::readonly() const { - if (m_stopped || !m_source) + if (!m_source) return true; return m_source->readonly(); @@ -158,7 +156,7 @@ bool MediaStreamTrackPrivate::remote() const void MediaStreamTrackPrivate::setEnabled(bool enabled) { - if (m_stopped || m_enabled == enabled) + if (m_enabled == enabled) return; // 4.3.3.1 @@ -169,15 +167,13 @@ void MediaStreamTrackPrivate::setEnabled(bool enabled) void MediaStreamTrackPrivate::detachSource() { - if (m_stopped) + if (!m_source) return; // The source will stop itself when out of consumers (observers in this case). m_source->removeObserver(this); m_source = nullptr; - m_stopped = true; - m_ignoreMutations = true; setReadyState(RealtimeMediaSource::Ended); m_ignoreMutations = false; @@ -185,9 +181,6 @@ void MediaStreamTrackPrivate::detachSource() RealtimeMediaSource::ReadyState MediaStreamTrackPrivate::readyState() const { - if (m_stopped) - return RealtimeMediaSource::Ended; - return m_readyState; } @@ -248,17 +241,11 @@ void MediaStreamTrackPrivate::applyConstraints(PassRefPtr) void MediaStreamTrackPrivate::sourceReadyStateChanged() { - if (stopped()) - return; - setReadyState(m_source->readyState()); } void MediaStreamTrackPrivate::sourceMutedChanged() { - if (stopped()) - return; - setMuted(m_source->muted()); } diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index a982ba931a26c..7a1efdaace867 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -74,7 +74,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ void setSource(PassRefPtr); void detachSource(); - bool stopped() const { return m_stopped; } void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; } @@ -111,7 +110,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ bool m_muted; bool m_enabled; - bool m_stopped; bool m_ignoreMutations; }; From df376f3bf5ad2bb54056ef07f6dd12c4de9151aa Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 30 Mar 2015 13:05:39 +0200 Subject: [PATCH 010/155] MediaStreamTrackPrivate: No source should equal muted = true --- Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 579f0b07266f3..6f74d3cc794e8 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -120,7 +120,7 @@ bool MediaStreamTrackPrivate::ended() const bool MediaStreamTrackPrivate::muted() const { if (!m_source) - return false; + return true; return m_source->muted(); } From 705efb47023b0128cb63a417303474aac8293ae8 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 30 Mar 2015 13:30:17 +0200 Subject: [PATCH 011/155] MediaStreamTrackPrivate: Don't keep internal muted state (use source state) --- .../mediastream/MediaStreamTrackPrivate.cpp | 19 ++----------------- .../mediastream/MediaStreamTrackPrivate.h | 2 -- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 6f74d3cc794e8..0f0e1e035f590 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -49,7 +49,6 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& m_id = createCanonicalUUIDString(); setSource(other.source()); m_readyState = other.readyState(); - m_muted = other.muted(); m_enabled = other.enabled(); m_ignoreMutations = false; } @@ -58,7 +57,6 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr : m_source(nullptr) , m_client(nullptr) , m_readyState(RealtimeMediaSource::Live) - , m_muted(false) , m_enabled(true) { m_ignoreMutations = true; @@ -82,7 +80,6 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) if (!m_source) return; - setMuted(m_source->muted()); setReadyState(m_source->readyState()); if (m_source) m_source->addObserver(this); @@ -125,19 +122,6 @@ bool MediaStreamTrackPrivate::muted() const return m_source->muted(); } -void MediaStreamTrackPrivate::setMuted(bool muted) -{ - if (m_muted == muted) - return; - - m_muted = muted; - - if (!m_client || m_ignoreMutations) - return; - - m_client->trackMutedChanged(); -} - bool MediaStreamTrackPrivate::readonly() const { if (!m_source) @@ -246,7 +230,8 @@ void MediaStreamTrackPrivate::sourceReadyStateChanged() void MediaStreamTrackPrivate::sourceMutedChanged() { - setMuted(m_source->muted()); + if (m_client) + m_client->trackMutedChanged(); } void MediaStreamTrackPrivate::sourceEnabledChanged() diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 7a1efdaace867..3ba2a05fe5000 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -58,7 +58,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ bool ended() const; bool muted() const; - void setMuted(bool); bool readonly() const; bool remote() const; @@ -108,7 +107,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ RealtimeMediaSource::ReadyState m_readyState; mutable String m_id; - bool m_muted; bool m_enabled; bool m_ignoreMutations; }; From be24d7cd460086a3f2f6e801d79df0d427cda46b Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 30 Mar 2015 14:26:52 +0200 Subject: [PATCH 012/155] MediaStreamTrackPrivate: Don't keep internal readyState (use sources state) --- .../mediastream/MediaStreamTrackPrivate.cpp | 32 +++---------------- .../mediastream/MediaStreamTrackPrivate.h | 4 --- 2 files changed, 5 insertions(+), 31 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 0f0e1e035f590..ffc60bcab35b6 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -45,23 +45,17 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& : RefCounted() , m_client(nullptr) { - m_ignoreMutations = true; m_id = createCanonicalUUIDString(); setSource(other.source()); - m_readyState = other.readyState(); m_enabled = other.enabled(); - m_ignoreMutations = false; } MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr source) : m_source(nullptr) , m_client(nullptr) - , m_readyState(RealtimeMediaSource::Live) , m_enabled(true) { - m_ignoreMutations = true; setSource(source); - m_ignoreMutations = false; } MediaStreamTrackPrivate::~MediaStreamTrackPrivate() @@ -77,10 +71,6 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) m_source = source; - if (!m_source) - return; - - setReadyState(m_source->readyState()); if (m_source) m_source->addObserver(this); } @@ -157,27 +147,14 @@ void MediaStreamTrackPrivate::detachSource() // The source will stop itself when out of consumers (observers in this case). m_source->removeObserver(this); m_source = nullptr; - - m_ignoreMutations = true; - setReadyState(RealtimeMediaSource::Ended); - m_ignoreMutations = false; } RealtimeMediaSource::ReadyState MediaStreamTrackPrivate::readyState() const { - return m_readyState; -} - -void MediaStreamTrackPrivate::setReadyState(RealtimeMediaSource::ReadyState state) -{ - if (m_readyState == RealtimeMediaSource::Ended || m_readyState == state) - return; - - // We only have two states so it's Ended here. - m_readyState = RealtimeMediaSource::Ended; + if (!m_source) + return RealtimeMediaSource::Ended; - if (m_client && !m_ignoreMutations) - m_client->trackEnded(); + return m_source->readyState(); } RefPtr MediaStreamTrackPrivate::clone() @@ -225,7 +202,8 @@ void MediaStreamTrackPrivate::applyConstraints(PassRefPtr) void MediaStreamTrackPrivate::sourceReadyStateChanged() { - setReadyState(m_source->readyState()); + if (m_client) + m_client->trackEnded(); } void MediaStreamTrackPrivate::sourceMutedChanged() diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 3ba2a05fe5000..829f70dd3ce90 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -93,8 +93,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ private: MediaStreamTrackPrivateClient* client() const { return m_client; } - void setReadyState(RealtimeMediaSource::ReadyState); - // RealtimeMediaSourceObserver virtual void sourceReadyStateChanged() override final; virtual void sourceMutedChanged() override final; @@ -104,11 +102,9 @@ class MediaStreamTrackPrivate : public RefCounted, publ RefPtr m_source; MediaStreamTrackPrivateClient* m_client; RefPtr m_constraints; - RealtimeMediaSource::ReadyState m_readyState; mutable String m_id; bool m_enabled; - bool m_ignoreMutations; }; } // namespace WebCore From d7986f6836290d77caee3bf54836b55209b8fbec Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 30 Mar 2015 14:35:21 +0200 Subject: [PATCH 013/155] MediaStreamTrackPrivate: Use initialization list in constructor --- .../WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index ffc60bcab35b6..857c375843770 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -44,10 +44,10 @@ PassRefPtr MediaStreamTrackPrivate::create(PassRefPtr source) From 4595938d6da10a4a175aec96a6528a4aec1c2523 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 31 Mar 2015 11:11:59 +0200 Subject: [PATCH 014/155] MediaStreamTrackPrivate: Always set or create id at construction --- .../mediastream/MediaStreamTrackPrivate.cpp | 26 ++++++------------- .../mediastream/MediaStreamTrackPrivate.h | 5 ++-- .../mediastream/RealtimeMediaSource.h | 1 - 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 857c375843770..3b681d0605c9e 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -38,7 +38,12 @@ namespace WebCore { PassRefPtr MediaStreamTrackPrivate::create(PassRefPtr source) { - return adoptRef(new MediaStreamTrackPrivate(source)); + return adoptRef(new MediaStreamTrackPrivate(source, createCanonicalUUIDString())); +} + +PassRefPtr MediaStreamTrackPrivate::create(PassRefPtr source, const String& id) +{ + return adoptRef(new MediaStreamTrackPrivate(source, id)); } MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& other) @@ -50,9 +55,10 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& setSource(other.source()); } -MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr source) +MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr source, const String& id) : m_source(nullptr) , m_client(nullptr) + , m_id(id) , m_enabled(true) { setSource(source); @@ -75,22 +81,6 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) m_source->addObserver(this); } -const String& MediaStreamTrackPrivate::id() const -{ - if (!m_id.isEmpty()) - return m_id; - - // The spec says: - // Unless a MediaStreamTrack object is created as a part a of special purpose algorithm that - // specifies how the track id must be initialized, the user agent must generate a globally - // unique identifier string and initialize the object's id attribute to that string. - if (m_source && m_source->useIDForTrackID()) - return m_source->id(); - - m_id = createCanonicalUUIDString(); - return m_id; -} - const String& MediaStreamTrackPrivate::label() const { if (m_source) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 829f70dd3ce90..f222d1f864068 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -49,10 +49,11 @@ class MediaStreamTrackPrivateClient { class MediaStreamTrackPrivate : public RefCounted, public RealtimeMediaSource::Observer { public: static PassRefPtr create(PassRefPtr); + static PassRefPtr create(PassRefPtr, const String& id); virtual ~MediaStreamTrackPrivate(); - const String& id() const; + const String& id() const { return m_id; } const String& label() const; bool ended() const; @@ -88,7 +89,7 @@ class MediaStreamTrackPrivate : public RefCounted, publ protected: explicit MediaStreamTrackPrivate(const MediaStreamTrackPrivate&); - MediaStreamTrackPrivate(PassRefPtr); + MediaStreamTrackPrivate(PassRefPtr, const String& id); private: MediaStreamTrackPrivateClient* client() const { return m_client; } diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h index 41d0e3f14a961..da5f20033142b 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h @@ -68,7 +68,6 @@ class RealtimeMediaSource : public RefCounted { virtual ~RealtimeMediaSource() { } bool isAudioStreamSource() const { return type() == Audio; } - virtual bool useIDForTrackID() const { return false; } const String& id() const { return m_id; } From 3a2a4a88213a5bd77c55bbf386fbaf226a213513 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 2 Apr 2015 17:13:49 +0200 Subject: [PATCH 015/155] MediaStreamTrack: Align dispatching of ended event with spec --- .../Modules/mediastream/MediaStreamTrack.cpp | 31 ++++++++++--------- .../Modules/mediastream/MediaStreamTrack.h | 2 ++ .../mediastream/MediaStreamTrackPrivate.cpp | 3 ++ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 80e731b51b57b..9aa15420de8fb 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -63,6 +63,7 @@ MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamT , m_privateTrack(privateTrack) , m_eventDispatchScheduled(false) , m_stoppingTrack(false) + , m_isEnded(m_privateTrack->ended()) { suspendIfNeeded(); @@ -75,6 +76,7 @@ MediaStreamTrack::MediaStreamTrack(MediaStreamTrack& other) , m_privateTrack(*other.privateTrack().clone()) , m_eventDispatchScheduled(false) , m_stoppingTrack(false) + , m_isEnded(m_privateTrack->ended()) { suspendIfNeeded(); @@ -138,18 +140,10 @@ bool MediaStreamTrack::remote() const const AtomicString& MediaStreamTrack::readyState() const { - static NeverDestroyed ended("ended", AtomicString::ConstructFromLiteral); - static NeverDestroyed live("live", AtomicString::ConstructFromLiteral); + static NeverDestroyed endedState("ended", AtomicString::ConstructFromLiteral); + static NeverDestroyed liveState("live", AtomicString::ConstructFromLiteral); - switch (m_privateTrack->readyState()) { - case RealtimeMediaSource::Live: - return live; - case RealtimeMediaSource::Ended: - return ended; - } - - ASSERT_NOT_REACHED(); - return emptyAtom; + return ended() ? endedState : liveState; } RefPtr MediaStreamTrack::getConstraints() const @@ -203,14 +197,14 @@ void MediaStreamTrack::stopProducingData() if (remote()) return; - // FIXME: This object needs its own ended member. + m_isEnded = true; m_privateTrack->detachSource(); } bool MediaStreamTrack::ended() const { - return m_privateTrack->ended(); + return m_isEnded; } void MediaStreamTrack::addObserver(MediaStreamTrack::Observer* observer) @@ -227,8 +221,15 @@ void MediaStreamTrack::removeObserver(MediaStreamTrack::Observer* observer) void MediaStreamTrack::trackEnded() { - if (!m_stoppingTrack) - scheduleEventDispatch(Event::create(eventNames().endedEvent, false, false)); + if (ended()) + return; + + m_isEnded = true; + + // The spec says "detach source" here, but the source is already detached by the + // platform object at this point. + + dispatchEvent(Event::create(eventNames().endedEvent, false, false)); for (auto& observer : m_observers) observer->trackDidEnd(); diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index ebeef6e688046..4603b38f3a7d6 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -130,6 +130,8 @@ class MediaStreamTrack final : public RefCounted, public Scrip bool m_eventDispatchScheduled; bool m_stoppingTrack; + + bool m_isEnded; }; } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 3b681d0605c9e..8a3f9163f9bc6 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -192,6 +192,9 @@ void MediaStreamTrackPrivate::applyConstraints(PassRefPtr) void MediaStreamTrackPrivate::sourceReadyStateChanged() { + // Don't depend on the client to detach the source. + detachSource(); + if (m_client) m_client->trackEnded(); } From fe50a44ec8a66f3bb4029da20ecfbba927eeb8ef Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 2 Apr 2015 17:40:07 +0200 Subject: [PATCH 016/155] MediaStreamTrack: Align dispatching of muted event with spec --- .../Modules/mediastream/MediaStreamTrack.cpp | 15 ++++++++++----- .../Modules/mediastream/MediaStreamTrack.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 9aa15420de8fb..5b48a0feb2931 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -63,6 +63,7 @@ MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamT , m_privateTrack(privateTrack) , m_eventDispatchScheduled(false) , m_stoppingTrack(false) + , m_isMuted(m_privateTrack->muted()) , m_isEnded(m_privateTrack->ended()) { suspendIfNeeded(); @@ -76,6 +77,7 @@ MediaStreamTrack::MediaStreamTrack(MediaStreamTrack& other) , m_privateTrack(*other.privateTrack().clone()) , m_eventDispatchScheduled(false) , m_stoppingTrack(false) + , m_isMuted(m_privateTrack->muted()) , m_isEnded(m_privateTrack->ended()) { suspendIfNeeded(); @@ -125,7 +127,7 @@ void MediaStreamTrack::setEnabled(bool enabled) bool MediaStreamTrack::muted() const { - return m_privateTrack->muted(); + return m_isMuted; } bool MediaStreamTrack::readonly() const @@ -239,10 +241,13 @@ void MediaStreamTrack::trackEnded() void MediaStreamTrack::trackMutedChanged() { - if (muted()) - scheduleEventDispatch(Event::create(eventNames().muteEvent, false, false)); - else - scheduleEventDispatch(Event::create(eventNames().unmuteEvent, false, false)); + if (muted()) { + m_isMuted = false; + dispatchEvent(Event::create(eventNames().unmuteEvent, false, false)); + } else { + m_isMuted = true; + dispatchEvent(Event::create(eventNames().muteEvent, false, false)); + } configureTrackRendering(); } diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 4603b38f3a7d6..c27d846905369 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -131,6 +131,7 @@ class MediaStreamTrack final : public RefCounted, public Scrip bool m_stoppingTrack; + bool m_isMuted; bool m_isEnded; }; From a94659eef16ae2c58436be3738fb915150b043cb Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 2 Apr 2015 19:20:20 +0200 Subject: [PATCH 017/155] MediaStreamTrackPrivate: Keep a type/kind member instead of reading it from the source --- .../mediastream/MediaStreamTrackPrivate.cpp | 14 +++++--------- .../platform/mediastream/MediaStreamTrackPrivate.h | 4 +++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 8a3f9163f9bc6..5acd7eef5e7a9 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -78,7 +78,11 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) m_source = source; if (m_source) - m_source->addObserver(this); + return; + + m_type = m_source->type(); + + m_source->addObserver(this); } const String& MediaStreamTrackPrivate::label() const @@ -168,14 +172,6 @@ const RealtimeMediaSourceStates& MediaStreamTrackPrivate::states() const return m_source->states(); } -RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const -{ - if (!m_source) - return RealtimeMediaSource::None; - - return m_source->type(); -} - RefPtr MediaStreamTrackPrivate::capabilities() const { if (!m_source) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index f222d1f864068..19c68caf56b33 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -77,7 +77,7 @@ class MediaStreamTrackPrivate : public RefCounted, publ void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; } - RealtimeMediaSource::Type type() const; + RealtimeMediaSource::Type type() const { return m_type; } const RealtimeMediaSourceStates& states() const; RefPtr capabilities() const; @@ -103,6 +103,8 @@ class MediaStreamTrackPrivate : public RefCounted, publ RefPtr m_source; MediaStreamTrackPrivateClient* m_client; RefPtr m_constraints; + + RealtimeMediaSource::Type m_type; mutable String m_id; bool m_enabled; From c9c77c6c8b6c1b993a63604e7fc87fbfab7ed110 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 2 Apr 2015 19:29:28 +0200 Subject: [PATCH 018/155] MediaStreamTrackPrivate: Keep a label member instead of reading it from the source --- .../platform/mediastream/MediaStreamTrackPrivate.cpp | 9 +-------- .../platform/mediastream/MediaStreamTrackPrivate.h | 4 ++-- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 5acd7eef5e7a9..4e52ff833ef2f 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -81,18 +81,11 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) return; m_type = m_source->type(); + m_label = m_source->name(); m_source->addObserver(this); } -const String& MediaStreamTrackPrivate::label() const -{ - if (m_source) - return m_source->name(); - - return emptyString(); -} - bool MediaStreamTrackPrivate::ended() const { return m_source && m_source->readyState() == RealtimeMediaSource::Ended; diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 19c68caf56b33..8cba6a207538d 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -54,7 +54,7 @@ class MediaStreamTrackPrivate : public RefCounted, publ virtual ~MediaStreamTrackPrivate(); const String& id() const { return m_id; } - const String& label() const; + const String& label() const { return m_label; } bool ended() const; @@ -106,7 +106,7 @@ class MediaStreamTrackPrivate : public RefCounted, publ RealtimeMediaSource::Type m_type; mutable String m_id; - + String m_label; bool m_enabled; }; From 2ed3d37aca70855929b8510f194b65278f2c1000 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 2 Apr 2015 20:09:26 +0200 Subject: [PATCH 019/155] MediaStreamTrackPrivate: Keep isReadonly and isRemote members instead of reading them from the source --- .../mediastream/MediaStreamTrackPrivate.cpp | 18 ++---------------- .../mediastream/MediaStreamTrackPrivate.h | 6 ++++-- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 4e52ff833ef2f..308b9b6bd55e7 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -82,6 +82,8 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) m_type = m_source->type(); m_label = m_source->name(); + m_isReadonly = m_source->readonly(); + m_isRemote = m_source->remote(); m_source->addObserver(this); } @@ -99,22 +101,6 @@ bool MediaStreamTrackPrivate::muted() const return m_source->muted(); } -bool MediaStreamTrackPrivate::readonly() const -{ - if (!m_source) - return true; - - return m_source->readonly(); -} - -bool MediaStreamTrackPrivate::remote() const -{ - if (!m_source) - return false; - - return m_source->remote(); -} - void MediaStreamTrackPrivate::setEnabled(bool enabled) { if (m_enabled == enabled) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 8cba6a207538d..8ba146fc1280c 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -60,8 +60,8 @@ class MediaStreamTrackPrivate : public RefCounted, publ bool muted() const; - bool readonly() const; - bool remote() const; + bool readonly() const { return m_isReadonly; } + bool remote() const { return m_isRemote; } bool enabled() const { return m_enabled; } void setEnabled(bool); @@ -108,6 +108,8 @@ class MediaStreamTrackPrivate : public RefCounted, publ mutable String m_id; String m_label; bool m_enabled; + bool m_isReadonly; + bool m_isRemote; }; } // namespace WebCore From 03632eee10b14bf2d39b68c8436d9ca8e993517c Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 11:44:27 +0200 Subject: [PATCH 020/155] MediaStreamTrackPrivate: Make ended() return true if source is detached --- Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 308b9b6bd55e7..ba88d548873b3 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -90,7 +90,7 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) bool MediaStreamTrackPrivate::ended() const { - return m_source && m_source->readyState() == RealtimeMediaSource::Ended; + return m_source ? m_source->readyState() == RealtimeMediaSource::Ended : true; } bool MediaStreamTrackPrivate::muted() const From 5f146badbfe31134982efd9621fd7ad7da87231d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 11:45:31 +0200 Subject: [PATCH 021/155] MediaStreamTrackPrivate: Remove readyState() since it provides the same info as ended() when we only have two states --- Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp | 3 +-- .../platform/mediastream/MediaStreamTrackPrivate.cpp | 8 -------- .../platform/mediastream/MediaStreamTrackPrivate.h | 2 -- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 5b48a0feb2931..387f66e49047f 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -166,8 +166,7 @@ RefPtr MediaStreamTrack::getCapabilities() const // in sync with the track state. A track that has ended always has a source // type of "none". RefPtr sourceCapabilities = m_privateTrack->capabilities(); - RealtimeMediaSource::ReadyState readyState = m_privateTrack->readyState(); - if (readyState == RealtimeMediaSource::Ended) + if (ended()) sourceCapabilities->setSourceType(RealtimeMediaSourceStates::None); return MediaStreamCapabilities::create(sourceCapabilities.release()); diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index ba88d548873b3..01b162c868375 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -122,14 +122,6 @@ void MediaStreamTrackPrivate::detachSource() m_source = nullptr; } -RealtimeMediaSource::ReadyState MediaStreamTrackPrivate::readyState() const -{ - if (!m_source) - return RealtimeMediaSource::Ended; - - return m_source->readyState(); -} - RefPtr MediaStreamTrackPrivate::clone() { return adoptRef(new MediaStreamTrackPrivate(*this)); diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 8ba146fc1280c..3e30e0c70fef4 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -66,8 +66,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ bool enabled() const { return m_enabled; } void setEnabled(bool); - RealtimeMediaSource::ReadyState readyState() const; - RefPtr clone(); RealtimeMediaSource* source() const { return m_source.get(); } From 775fc4ed8546b89d5479720ff33bad9c99866808 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 11:49:36 +0200 Subject: [PATCH 022/155] MediaStreamTrackPrivate: Update comment in setEnabled() and removed check --- .../platform/mediastream/MediaStreamTrackPrivate.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 01b162c868375..2429b77543b0a 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -103,12 +103,7 @@ bool MediaStreamTrackPrivate::muted() const void MediaStreamTrackPrivate::setEnabled(bool enabled) { - if (m_enabled == enabled) - return; - - // 4.3.3.1 - // ... after a MediaStreamTrack is disassociated from its track, its enabled attribute still - // changes value when set; it just doesn't do anything with that new value. + // Always update the enabled state regardless of the track being ended. m_enabled = enabled; } From 9e87a4fada5685af7c1bd9eb80f41aa3a7ea5a84 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 11:51:47 +0200 Subject: [PATCH 023/155] MediaStreamTrackPrivate: Aligned muted() implementation with the one of ended() --- .../WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 2429b77543b0a..9cfa4249613ac 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -95,10 +95,7 @@ bool MediaStreamTrackPrivate::ended() const bool MediaStreamTrackPrivate::muted() const { - if (!m_source) - return true; - - return m_source->muted(); + return m_source ? m_source->muted() : true; } void MediaStreamTrackPrivate::setEnabled(bool enabled) From d68d2637ab21c03632196229a796c1ce1367fa6f Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 12:01:06 +0200 Subject: [PATCH 024/155] MediaStreamTrack(Private): Only make source settable by MediaStreamTrackPrivate (in constructor) --- Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp | 5 ----- Source/WebCore/Modules/mediastream/MediaStreamTrack.h | 2 -- .../platform/mediastream/MediaStreamTrackPrivate.cpp | 7 +------ .../WebCore/platform/mediastream/MediaStreamTrackPrivate.h | 3 ++- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 387f66e49047f..01a2fcd0a7d60 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -90,11 +90,6 @@ MediaStreamTrack::~MediaStreamTrack() m_privateTrack->setClient(nullptr); } -void MediaStreamTrack::setSource(PassRefPtr newSource) -{ - m_privateTrack->setSource(newSource); -} - const AtomicString& MediaStreamTrack::kind() const { static NeverDestroyed audioKind("audio", AtomicString::ConstructFromLiteral); diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index c27d846905369..231843f7b8c4b 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -101,8 +101,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip MediaStreamTrack(ScriptExecutionContext&, MediaStreamTrackPrivate&); explicit MediaStreamTrack(MediaStreamTrack&); - void setSource(PassRefPtr); - void configureTrackRendering(); void scheduleEventDispatch(PassRefPtr); diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 9cfa4249613ac..4de2329b2cae1 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -72,13 +72,8 @@ MediaStreamTrackPrivate::~MediaStreamTrackPrivate() void MediaStreamTrackPrivate::setSource(PassRefPtr source) { - if (m_source) - m_source->removeObserver(this); - m_source = source; - - if (m_source) - return; + ASSERT(m_source); m_type = m_source->type(); m_label = m_source->name(); diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 3e30e0c70fef4..8a1abd78aea03 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -69,7 +69,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ RefPtr clone(); RealtimeMediaSource* source() const { return m_source.get(); } - void setSource(PassRefPtr); void detachSource(); @@ -92,6 +91,8 @@ class MediaStreamTrackPrivate : public RefCounted, publ private: MediaStreamTrackPrivateClient* client() const { return m_client; } + void setSource(PassRefPtr); + // RealtimeMediaSourceObserver virtual void sourceReadyStateChanged() override final; virtual void sourceMutedChanged() override final; From 85718236f3933c5e64c0c7ea35355545ebf4dd08 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 13:19:44 +0200 Subject: [PATCH 025/155] RealtimeMediaSource: Replace readyState() with stopped() since we only have two states and stopped is used in the spec --- .../mediastream/MediaStreamTrackPrivate.cpp | 2 +- .../mediastream/RealtimeMediaSource.cpp | 32 ++++++++----------- .../mediastream/RealtimeMediaSource.h | 7 ++-- .../RealtimeMediaSourceCenterOwr.cpp | 2 -- .../mock/MockRealtimeMediaSourceCenter.cpp | 2 -- 5 files changed, 17 insertions(+), 28 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 4de2329b2cae1..7329d00f8ef86 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -85,7 +85,7 @@ void MediaStreamTrackPrivate::setSource(PassRefPtr source) bool MediaStreamTrackPrivate::ended() const { - return m_source ? m_source->readyState() == RealtimeMediaSource::Ended : true; + return m_source ? m_source->stopped() : true; } bool MediaStreamTrackPrivate::muted() const diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp index ea7f6c4f6af78..d769cc169dfb7 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp @@ -44,7 +44,7 @@ RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const Stri : m_id(id) , m_type(type) , m_name(name) - , m_readyState(Live) + , m_stopped(false) , m_muted(false) , m_readonly(false) , m_remote(false) @@ -59,27 +59,12 @@ RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const Stri void RealtimeMediaSource::reset() { - m_readyState = Live; + m_stopped = false; m_muted = false; m_readonly = false; m_remote = false; } -void RealtimeMediaSource::setReadyState(ReadyState readyState) -{ - if (m_readyState == Ended || m_readyState == readyState) - return; - - // We only have two states so it's Ended here. - m_readyState = Ended; - - for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer) - (*observer)->sourceReadyStateChanged(); - - // There are no more consumers of this source's data, shut it down as appropriate. - stopProducingData(); -} - void RealtimeMediaSource::addObserver(RealtimeMediaSource::Observer* observer) { m_observers.append(observer); @@ -102,7 +87,7 @@ void RealtimeMediaSource::setMuted(bool muted) m_muted = muted; - if (m_readyState == Ended) + if (stopped()) return; for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer) @@ -116,7 +101,16 @@ bool RealtimeMediaSource::readonly() const void RealtimeMediaSource::stop() { - setReadyState(Ended); + if (stopped()) + return; + + m_stopped = true; + + for (auto& observer : m_observers) + observer->sourceReadyStateChanged(); + + // There are no more consumers of this source's data, shut it down as appropriate. + stopProducingData(); } } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h index da5f20033142b..184d99bb4f713 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h @@ -56,6 +56,7 @@ class RealtimeMediaSource : public RefCounted { virtual ~Observer() { } // Source state changes. + // FIXME: rename the below callback to sourceStopped() virtual void sourceReadyStateChanged() = 0; virtual void sourceMutedChanged() = 0; // FIMXE: remove the below callback @@ -80,9 +81,7 @@ class RealtimeMediaSource : public RefCounted { virtual RefPtr capabilities() const = 0; virtual const RealtimeMediaSourceStates& states() = 0; - enum ReadyState { Live = 0, Ended = 1 }; - virtual ReadyState readyState() const { return m_readyState; } - virtual void setReadyState(ReadyState); + bool stopped() const { return m_stopped; } virtual bool muted() const { return m_muted; } virtual void setMuted(bool); @@ -110,7 +109,7 @@ class RealtimeMediaSource : public RefCounted { String m_id; Type m_type; String m_name; - ReadyState m_readyState; + bool m_stopped; Vector m_observers; bool m_enabled; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp index 8b889c33fe09e..b8187bf67a9b7 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp @@ -115,7 +115,6 @@ void RealtimeMediaSourceCenterOwr::createMediaStream(PassRefPtr audioSource = firstSource(RealtimeMediaSource::Audio); if (audioSource) { audioSource->reset(); - audioSource->setReadyState(RealtimeMediaSource::Live); audioSources.append(audioSource.release()); } } @@ -126,7 +125,6 @@ void RealtimeMediaSourceCenterOwr::createMediaStream(PassRefPtr videoSource = firstSource(RealtimeMediaSource::Video); if (videoSource) { videoSource->reset(); - videoSource->setReadyState(RealtimeMediaSource::Live); videoSources.append(videoSource.release()); } } diff --git a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp index c386d81cfdaae..83e8723dc772b 100644 --- a/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp +++ b/Source/WebCore/platform/mock/MockRealtimeMediaSourceCenter.cpp @@ -174,7 +174,6 @@ void MockRealtimeMediaSourceCenter::createMediaStream(PassRefPtr audioSource = it->value; audioSource->reset(); - audioSource->setReadyState(RealtimeMediaSource::Live); audioSources.append(audioSource.release()); } @@ -190,7 +189,6 @@ void MockRealtimeMediaSourceCenter::createMediaStream(PassRefPtr videoSource = it->value; videoSource->reset(); - videoSource->setReadyState(RealtimeMediaSource::Live); videoSources.append(videoSource.release()); } From 3814cebb449d5604ee3a250fe5f7dca7ad78e382 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 13:27:21 +0200 Subject: [PATCH 026/155] RealtimeMediaSource: Remove unused m_enabled member --- Source/WebCore/platform/mediastream/RealtimeMediaSource.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h index 184d99bb4f713..879e1782f78a7 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h @@ -112,7 +112,6 @@ class RealtimeMediaSource : public RefCounted { bool m_stopped; Vector m_observers; - bool m_enabled; bool m_muted; bool m_readonly; bool m_remote; From d5c492f03bb3c85db25540a4efe0a448c46c6d36 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 5 Apr 2015 13:28:06 +0200 Subject: [PATCH 027/155] RealtimeMediaSource: Update observer loop to use range-based for loop --- Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp index d769cc169dfb7..ddda564d34973 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp @@ -90,8 +90,8 @@ void RealtimeMediaSource::setMuted(bool muted) if (stopped()) return; - for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer) - (*observer)->sourceMutedChanged(); + for (auto& observer : m_observers) + observer->sourceMutedChanged(); } bool RealtimeMediaSource::readonly() const From fcfb0784e67b2836ff4e00c7336d398e3d6f7b41 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 7 Apr 2015 10:00:06 +0200 Subject: [PATCH 028/155] MediaStreamTrack: Remove unused m_stoppingTrack --- Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp | 2 -- Source/WebCore/Modules/mediastream/MediaStreamTrack.h | 2 -- Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h | 1 - 3 files changed, 5 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 01a2fcd0a7d60..ceaa35d8210c1 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -62,7 +62,6 @@ MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamT , ActiveDOMObject(&context) , m_privateTrack(privateTrack) , m_eventDispatchScheduled(false) - , m_stoppingTrack(false) , m_isMuted(m_privateTrack->muted()) , m_isEnded(m_privateTrack->ended()) { @@ -76,7 +75,6 @@ MediaStreamTrack::MediaStreamTrack(MediaStreamTrack& other) , ActiveDOMObject(other.scriptExecutionContext()) , m_privateTrack(*other.privateTrack().clone()) , m_eventDispatchScheduled(false) - , m_stoppingTrack(false) , m_isMuted(m_privateTrack->muted()) , m_isEnded(m_privateTrack->ended()) { diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 231843f7b8c4b..cde016680dbc2 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -127,8 +127,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip Ref m_privateTrack; bool m_eventDispatchScheduled; - bool m_stoppingTrack; - bool m_isMuted; bool m_isEnded; }; diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 8a1abd78aea03..83eadc9c600a6 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -104,7 +104,6 @@ class MediaStreamTrackPrivate : public RefCounted, publ RefPtr m_constraints; RealtimeMediaSource::Type m_type; - mutable String m_id; String m_label; bool m_enabled; bool m_isReadonly; From 235884fa69606f5047562f4daab2d82c73722650 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 7 Apr 2015 10:00:39 +0200 Subject: [PATCH 029/155] MediaStreamTrack: Remove mutable from m_id (String) --- Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 83eadc9c600a6..6e94475212b1e 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -104,6 +104,7 @@ class MediaStreamTrackPrivate : public RefCounted, publ RefPtr m_constraints; RealtimeMediaSource::Type m_type; + String m_id; String m_label; bool m_enabled; bool m_isReadonly; From 2e730a3295d95a41af7ebded1bbd17e98434d773 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 7 Apr 2015 11:03:38 +0200 Subject: [PATCH 030/155] MediaStreamTrack: Remove redundant constructor --- .../Modules/mediastream/MediaStreamTrack.cpp | 20 +------------------ .../Modules/mediastream/MediaStreamTrack.h | 1 - 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index ceaa35d8210c1..4923f51f01e14 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -52,11 +52,6 @@ RefPtr MediaStreamTrack::create(ScriptExecutionContext& contex return adoptRef(new MediaStreamTrack(context, privateTrack)); } -RefPtr MediaStreamTrack::create(MediaStreamTrack& track) -{ - return adoptRef(new MediaStreamTrack(track)); -} - MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) : RefCounted() , ActiveDOMObject(&context) @@ -70,19 +65,6 @@ MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamT m_privateTrack->setClient(this); } -MediaStreamTrack::MediaStreamTrack(MediaStreamTrack& other) - : RefCounted() - , ActiveDOMObject(other.scriptExecutionContext()) - , m_privateTrack(*other.privateTrack().clone()) - , m_eventDispatchScheduled(false) - , m_isMuted(m_privateTrack->muted()) - , m_isEnded(m_privateTrack->ended()) -{ - suspendIfNeeded(); - - m_privateTrack->setClient(this); -} - MediaStreamTrack::~MediaStreamTrack() { m_privateTrack->setClient(nullptr); @@ -179,7 +161,7 @@ void MediaStreamTrack::applyConstraints(PassRefPtr) RefPtr MediaStreamTrack::clone() { - return MediaStreamTrack::create(*this); + return MediaStreamTrack::create(*scriptExecutionContext(), *m_privateTrack->clone()); } void MediaStreamTrack::stopProducingData() diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index cde016680dbc2..7f6ddee6c473d 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -57,7 +57,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip }; static RefPtr create(ScriptExecutionContext&, MediaStreamTrackPrivate&); - static RefPtr create(MediaStreamTrack&); virtual ~MediaStreamTrack(); const AtomicString& kind() const; From 36caf9d40d04783529f74f40d2a56695c70325fa Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 7 Apr 2015 15:52:22 +0200 Subject: [PATCH 031/155] MediaStreamTrackPrivate: Fix cloning of MediaStreamTrack(Private) with detached source --- .../mediastream/MediaStreamTrackPrivate.cpp | 35 ++++++++++--------- .../mediastream/MediaStreamTrackPrivate.h | 5 +-- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 7329d00f8ef86..842d1c61d1656 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -48,20 +48,33 @@ PassRefPtr MediaStreamTrackPrivate::create(PassRefPtraddObserver(this); } MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr source, const String& id) - : m_source(nullptr) + : RefCounted() + , m_source(source) , m_client(nullptr) + , m_type(m_source->type()) , m_id(id) + , m_label(m_source->name()) , m_enabled(true) + , m_isReadonly(m_source->readonly()) + , m_isRemote(m_source->remote()) { - setSource(source); + m_source->addObserver(this); } MediaStreamTrackPrivate::~MediaStreamTrackPrivate() @@ -70,19 +83,6 @@ MediaStreamTrackPrivate::~MediaStreamTrackPrivate() m_source->removeObserver(this); } -void MediaStreamTrackPrivate::setSource(PassRefPtr source) -{ - m_source = source; - ASSERT(m_source); - - m_type = m_source->type(); - m_label = m_source->name(); - m_isReadonly = m_source->readonly(); - m_isRemote = m_source->remote(); - - m_source->addObserver(this); -} - bool MediaStreamTrackPrivate::ended() const { return m_source ? m_source->stopped() : true; @@ -107,6 +107,8 @@ void MediaStreamTrackPrivate::detachSource() // The source will stop itself when out of consumers (observers in this case). m_source->removeObserver(this); m_source = nullptr; + + printf("source evals to: %d\n", !!m_source); } RefPtr MediaStreamTrackPrivate::clone() @@ -114,7 +116,6 @@ RefPtr MediaStreamTrackPrivate::clone() return adoptRef(new MediaStreamTrackPrivate(*this)); } - RefPtr MediaStreamTrackPrivate::constraints() const { return m_constraints; diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 6e94475212b1e..5b900d76000ad 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -84,15 +84,12 @@ class MediaStreamTrackPrivate : public RefCounted, publ void configureTrackRendering(); -protected: +private: explicit MediaStreamTrackPrivate(const MediaStreamTrackPrivate&); MediaStreamTrackPrivate(PassRefPtr, const String& id); -private: MediaStreamTrackPrivateClient* client() const { return m_client; } - void setSource(PassRefPtr); - // RealtimeMediaSourceObserver virtual void sourceReadyStateChanged() override final; virtual void sourceMutedChanged() override final; From 89e2c8a2110ea5e32f0de5ac4c5aaed64c1ac28b Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 8 Apr 2015 13:12:14 +0200 Subject: [PATCH 032/155] MediaStreamTrack: Move away from using PassRefPtr --- Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp | 4 ++-- Source/WebCore/Modules/mediastream/MediaStreamTrack.h | 4 ++-- Source/WebCore/Modules/mediastream/UserMediaRequest.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 4923f51f01e14..d0e5273ded03e 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -153,7 +153,7 @@ void MediaStreamTrack::applyConstraints(const Dictionary& constraints) m_privateTrack->applyConstraints(m_constraints); } -void MediaStreamTrack::applyConstraints(PassRefPtr) +void MediaStreamTrack::applyConstraints(const MediaConstraints&) { // FIXME: apply the new constraints to the track // https://bugs.webkit.org/show_bug.cgi?id=122428 @@ -248,7 +248,7 @@ bool MediaStreamTrack::canSuspend() const return false; } -void MediaStreamTrack::scheduleEventDispatch(PassRefPtr event) +void MediaStreamTrack::scheduleEventDispatch(RefPtr&& event) { { MutexLocker locker(m_mutex); diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 7f6ddee6c473d..0fcff2afc1f69 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -76,7 +76,7 @@ class MediaStreamTrack final : public RefCounted, public Scrip RefPtr states() const; RefPtr getCapabilities() const; void applyConstraints(const Dictionary&); - void applyConstraints(PassRefPtr); + void applyConstraints(const MediaConstraints&); RefPtr clone(); void stopProducingData(); @@ -101,7 +101,7 @@ class MediaStreamTrack final : public RefCounted, public Scrip explicit MediaStreamTrack(MediaStreamTrack&); void configureTrackRendering(); - void scheduleEventDispatch(PassRefPtr); + void scheduleEventDispatch(RefPtr&&); // ActiveDOMObject API. void stop() override final; diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp index d796145bebb89..02faf303cb3e1 100644 --- a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp +++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp @@ -174,9 +174,9 @@ void UserMediaRequest::didCreateStream(PassRefPtr privateStr // 4 - Create the MediaStream and pass it to the success callback. RefPtr stream = MediaStream::create(*protectedThis->m_scriptExecutionContext, privateStream); for (auto& track : stream->getAudioTracks()) - track->applyConstraints(protectedThis->m_audioConstraints); + track->applyConstraints(*protectedThis->m_audioConstraints); for (auto& track : stream->getVideoTracks()) - track->applyConstraints(protectedThis->m_videoConstraints); + track->applyConstraints(*protectedThis->m_videoConstraints); protectedThis->m_resolveCallback(stream.get()); }); From 13988fee64d48905c857f959c88989bc99846393 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 8 Apr 2015 14:22:44 +0200 Subject: [PATCH 033/155] MediaStreamTrackPrivate: Move away from using PassRefPtr --- .../WebCore/Modules/mediastream/MediaStreamTrack.cpp | 2 +- .../platform/mediastream/MediaStreamPrivate.cpp | 8 ++++---- .../platform/mediastream/MediaStreamTrackPrivate.cpp | 12 ++++++------ .../platform/mediastream/MediaStreamTrackPrivate.h | 9 ++++----- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index d0e5273ded03e..838abaa999f52 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -150,7 +150,7 @@ RefPtr MediaStreamTrack::getCapabilities() const void MediaStreamTrack::applyConstraints(const Dictionary& constraints) { m_constraints->initialize(constraints); - m_privateTrack->applyConstraints(m_constraints); + m_privateTrack->applyConstraints(*m_constraints); } void MediaStreamTrack::applyConstraints(const MediaConstraints&) diff --git a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp index 6d1ffb6e1a2f7..a563ad55f7661 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp @@ -47,11 +47,11 @@ RefPtr MediaStreamPrivate::create(const Vector> tracks; tracks.reserveCapacity(audioSources.size() + videoSources.size()); - for (auto& source : audioSources) - tracks.append(MediaStreamTrackPrivate::create(source)); + for (auto source : audioSources) + tracks.append(MediaStreamTrackPrivate::create(WTF::move(source))); - for (auto& source : videoSources) - tracks.append(MediaStreamTrackPrivate::create(source)); + for (auto source : videoSources) + tracks.append(MediaStreamTrackPrivate::create(WTF::move(source))); return MediaStreamPrivate::create(tracks); } diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 842d1c61d1656..4cff67731a18a 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -36,14 +36,14 @@ namespace WebCore { -PassRefPtr MediaStreamTrackPrivate::create(PassRefPtr source) +RefPtr MediaStreamTrackPrivate::create(RefPtr&& source) { - return adoptRef(new MediaStreamTrackPrivate(source, createCanonicalUUIDString())); + return adoptRef(new MediaStreamTrackPrivate(WTF::move(source), createCanonicalUUIDString())); } -PassRefPtr MediaStreamTrackPrivate::create(PassRefPtr source, const String& id) +RefPtr MediaStreamTrackPrivate::create(RefPtr&& source, const String& id) { - return adoptRef(new MediaStreamTrackPrivate(source, id)); + return adoptRef(new MediaStreamTrackPrivate(WTF::move(source), id)); } MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& other) @@ -63,7 +63,7 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& m_source->addObserver(this); } -MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr source, const String& id) +MediaStreamTrackPrivate::MediaStreamTrackPrivate(RefPtr&& source, const String& id) : RefCounted() , m_source(source) , m_client(nullptr) @@ -139,7 +139,7 @@ RefPtr MediaStreamTrackPrivate::capabilities() return m_source->capabilities(); } -void MediaStreamTrackPrivate::applyConstraints(PassRefPtr) +void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&) { // FIXME: apply the new constraints to the track // https://bugs.webkit.org/show_bug.cgi?id=122428 diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 5b900d76000ad..a1da3ad4ad445 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -29,7 +29,6 @@ #if ENABLE(MEDIA_STREAM) #include "RealtimeMediaSource.h" -#include #include #include @@ -48,8 +47,8 @@ class MediaStreamTrackPrivateClient { class MediaStreamTrackPrivate : public RefCounted, public RealtimeMediaSource::Observer { public: - static PassRefPtr create(PassRefPtr); - static PassRefPtr create(PassRefPtr, const String& id); + static RefPtr create(RefPtr&&); + static RefPtr create(RefPtr&&, const String& id); virtual ~MediaStreamTrackPrivate(); @@ -80,13 +79,13 @@ class MediaStreamTrackPrivate : public RefCounted, publ RefPtr capabilities() const; RefPtr constraints() const; - void applyConstraints(PassRefPtr); + void applyConstraints(const MediaConstraints&); void configureTrackRendering(); private: explicit MediaStreamTrackPrivate(const MediaStreamTrackPrivate&); - MediaStreamTrackPrivate(PassRefPtr, const String& id); + MediaStreamTrackPrivate(RefPtr&&, const String& id); MediaStreamTrackPrivateClient* client() const { return m_client; } From d3324e045dedb7b3f1f270a29ef0db52d81dfe44 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 8 Apr 2015 14:33:07 +0200 Subject: [PATCH 034/155] MediaStreamTrack: Rename private (m_privateTrack -> m_private) to align with MediaStream and others --- .../Modules/mediastream/MediaStreamTrack.cpp | 34 +++++++++---------- .../Modules/mediastream/MediaStreamTrack.h | 6 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 838abaa999f52..5e4f2a5a9ff4b 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -55,19 +55,19 @@ RefPtr MediaStreamTrack::create(ScriptExecutionContext& contex MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) : RefCounted() , ActiveDOMObject(&context) - , m_privateTrack(privateTrack) + , m_private(privateTrack) , m_eventDispatchScheduled(false) - , m_isMuted(m_privateTrack->muted()) - , m_isEnded(m_privateTrack->ended()) + , m_isMuted(m_private->muted()) + , m_isEnded(m_private->ended()) { suspendIfNeeded(); - m_privateTrack->setClient(this); + m_private->setClient(this); } MediaStreamTrack::~MediaStreamTrack() { - m_privateTrack->setClient(nullptr); + m_private->setClient(nullptr); } const AtomicString& MediaStreamTrack::kind() const @@ -75,29 +75,29 @@ const AtomicString& MediaStreamTrack::kind() const static NeverDestroyed audioKind("audio", AtomicString::ConstructFromLiteral); static NeverDestroyed videoKind("video", AtomicString::ConstructFromLiteral); - if (m_privateTrack->type() == RealtimeMediaSource::Audio) + if (m_private->type() == RealtimeMediaSource::Audio) return audioKind; return videoKind; } const String& MediaStreamTrack::id() const { - return m_privateTrack->id(); + return m_private->id(); } const String& MediaStreamTrack::label() const { - return m_privateTrack->label(); + return m_private->label(); } bool MediaStreamTrack::enabled() const { - return m_privateTrack->enabled(); + return m_private->enabled(); } void MediaStreamTrack::setEnabled(bool enabled) { - m_privateTrack->setEnabled(enabled); + m_private->setEnabled(enabled); } bool MediaStreamTrack::muted() const @@ -107,12 +107,12 @@ bool MediaStreamTrack::muted() const bool MediaStreamTrack::readonly() const { - return m_privateTrack->readonly(); + return m_private->readonly(); } bool MediaStreamTrack::remote() const { - return m_privateTrack->remote(); + return m_private->remote(); } const AtomicString& MediaStreamTrack::readyState() const @@ -132,7 +132,7 @@ RefPtr MediaStreamTrack::getConstraints() const RefPtr MediaStreamTrack::states() const { - return MediaSourceStates::create(m_privateTrack->states()); + return MediaSourceStates::create(m_private->states()); } RefPtr MediaStreamTrack::getCapabilities() const @@ -140,7 +140,7 @@ RefPtr MediaStreamTrack::getCapabilities() const // The source may be shared by multiple tracks, so its states is not necessarily // in sync with the track state. A track that has ended always has a source // type of "none". - RefPtr sourceCapabilities = m_privateTrack->capabilities(); + RefPtr sourceCapabilities = m_private->capabilities(); if (ended()) sourceCapabilities->setSourceType(RealtimeMediaSourceStates::None); @@ -150,7 +150,7 @@ RefPtr MediaStreamTrack::getCapabilities() const void MediaStreamTrack::applyConstraints(const Dictionary& constraints) { m_constraints->initialize(constraints); - m_privateTrack->applyConstraints(*m_constraints); + m_private->applyConstraints(*m_constraints); } void MediaStreamTrack::applyConstraints(const MediaConstraints&) @@ -161,7 +161,7 @@ void MediaStreamTrack::applyConstraints(const MediaConstraints&) RefPtr MediaStreamTrack::clone() { - return MediaStreamTrack::create(*scriptExecutionContext(), *m_privateTrack->clone()); + return MediaStreamTrack::create(*scriptExecutionContext(), *m_private->clone()); } void MediaStreamTrack::stopProducingData() @@ -175,7 +175,7 @@ void MediaStreamTrack::stopProducingData() m_isEnded = true; - m_privateTrack->detachSource(); + m_private->detachSource(); } bool MediaStreamTrack::ended() const diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 0fcff2afc1f69..51a13679df768 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -81,8 +81,8 @@ class MediaStreamTrack final : public RefCounted, public Scrip RefPtr clone(); void stopProducingData(); - RealtimeMediaSource* source() const { return m_privateTrack->source(); } - MediaStreamTrackPrivate& privateTrack() { return m_privateTrack.get(); } + RealtimeMediaSource* source() const { return m_private->source(); } + MediaStreamTrackPrivate& privateTrack() { return m_private.get(); } bool ended() const; @@ -123,7 +123,7 @@ class MediaStreamTrack final : public RefCounted, public Scrip Vector m_observers; - Ref m_privateTrack; + Ref m_private; bool m_eventDispatchScheduled; bool m_isMuted; From bab3b12b97748bfa9b9d119b7cf8a705b758a363 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 8 Apr 2015 15:21:33 +0200 Subject: [PATCH 035/155] MediaStreamTrack Refactoring: Tidy up and reorder (to match idl and spec) --- .../Modules/mediastream/MediaStreamTrack.cpp | 40 +++++++++---------- .../Modules/mediastream/MediaStreamTrack.h | 13 +++--- .../Modules/mediastream/MediaStreamTrack.idl | 8 ++-- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 5e4f2a5a9ff4b..ab33b716cbae4 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -55,8 +55,8 @@ RefPtr MediaStreamTrack::create(ScriptExecutionContext& contex MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) : RefCounted() , ActiveDOMObject(&context) - , m_private(privateTrack) , m_eventDispatchScheduled(false) + , m_private(privateTrack) , m_isMuted(m_private->muted()) , m_isEnded(m_private->ended()) { @@ -123,6 +123,25 @@ const AtomicString& MediaStreamTrack::readyState() const return ended() ? endedState : liveState; } +RefPtr MediaStreamTrack::clone() +{ + return MediaStreamTrack::create(*scriptExecutionContext(), *m_private->clone()); +} + +void MediaStreamTrack::stopProducingData() +{ + // NOTE: this method is called when the "stop" method is called from JS, using + // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires + // a "stop" method. + + if (remote()) + return; + + m_isEnded = true; + + m_private->detachSource(); +} + RefPtr MediaStreamTrack::getConstraints() const { // FIXME: https://bugs.webkit.org/show_bug.cgi?id=122428 @@ -159,25 +178,6 @@ void MediaStreamTrack::applyConstraints(const MediaConstraints&) // https://bugs.webkit.org/show_bug.cgi?id=122428 } -RefPtr MediaStreamTrack::clone() -{ - return MediaStreamTrack::create(*scriptExecutionContext(), *m_private->clone()); -} - -void MediaStreamTrack::stopProducingData() -{ - // NOTE: this method is called when the "stop" method is called from JS, using - // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires - // a "stop" method. - - if (remote()) - return; - - m_isEnded = true; - - m_private->detachSource(); -} - bool MediaStreamTrack::ended() const { return m_isEnded; diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 51a13679df768..62ca4766930ea 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -72,15 +72,15 @@ class MediaStreamTrack final : public RefCounted, public Scrip const AtomicString& readyState() const; + RefPtr clone(); + void stopProducingData(); + RefPtr getConstraints() const; RefPtr states() const; RefPtr getCapabilities() const; void applyConstraints(const Dictionary&); void applyConstraints(const MediaConstraints&); - RefPtr clone(); - void stopProducingData(); - RealtimeMediaSource* source() const { return m_private->source(); } MediaStreamTrackPrivate& privateTrack() { return m_private.get(); } @@ -117,14 +117,13 @@ class MediaStreamTrack final : public RefCounted, public Scrip void trackMutedChanged(); Vector> m_scheduledEvents; - - RefPtr m_constraints; + bool m_eventDispatchScheduled; Mutex m_mutex; Vector m_observers; - Ref m_private; - bool m_eventDispatchScheduled; + + RefPtr m_constraints; bool m_isMuted; bool m_isEnded; diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl b/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl index b93538da8db3f..dfb2df1d1f5e3 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.idl @@ -43,17 +43,15 @@ enum MediaStreamTrackState { "new", "live", "ended" }; readonly attribute MediaStreamTrackState readyState; attribute EventHandler onended; - MediaTrackConstraints getConstraints(); + MediaStreamTrack clone(); + [ImplementedAs=stopProducingData] void stop(); + MediaTrackConstraints getConstraints(); MediaSourceStates states(); - MediaStreamCapabilities getCapabilities(); // returns either AllVideoCapabilities or AllAudioCapabilities - void applyConstraints(Dictionary constraints); attribute EventHandler onoverconstrained; - MediaStreamTrack clone(); - [ImplementedAs=stopProducingData] void stop(); // EventTarget interface void addEventListener(DOMString type, EventListener listener, optional boolean useCapture); From bf284dcd35d38007cf89c3afe4e38806ed790f5e Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 8 Apr 2015 15:40:32 +0200 Subject: [PATCH 036/155] MediaStreamTrackPrivate: Remove left-over log --- Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index 4cff67731a18a..fa24faf0166c7 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -107,8 +107,6 @@ void MediaStreamTrackPrivate::detachSource() // The source will stop itself when out of consumers (observers in this case). m_source->removeObserver(this); m_source = nullptr; - - printf("source evals to: %d\n", !!m_source); } RefPtr MediaStreamTrackPrivate::clone() From 96b123d563d2df27278af7b343a24eb3f6630606 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 9 Apr 2015 10:12:41 +0200 Subject: [PATCH 037/155] RTCRtpSender/Receiver: Introduce common base class --- Source/WebCore/CMakeLists.txt | 3 + Source/WebCore/DerivedSources.make | 2 + .../Modules/mediastream/RTCRtpReceiver.cpp | 54 +++++++++++++++++ .../Modules/mediastream/RTCRtpReceiver.h | 53 ++++++++++++++++ .../Modules/mediastream/RTCRtpReceiver.idl | 35 +++++++++++ .../Modules/mediastream/RTCRtpSender.cpp | 9 +-- .../Modules/mediastream/RTCRtpSender.h | 12 +--- .../mediastream/RTCRtpSenderReceiverBase.cpp | 56 +++++++++++++++++ .../mediastream/RTCRtpSenderReceiverBase.h | 60 +++++++++++++++++++ 9 files changed, 266 insertions(+), 18 deletions(-) create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpReceiver.h create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpReceiver.idl create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.cpp create mode 100644 Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index df2bbac4a9197..59a828ce4e630 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -250,6 +250,7 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/RTCIceCandidateEvent.idl Modules/mediastream/RTCIceServer.idl Modules/mediastream/RTCPeerConnection.idl + Modules/mediastream/RTCRtpReceiver.idl Modules/mediastream/RTCRtpSender.idl Modules/mediastream/RTCSessionDescription.idl Modules/mediastream/RTCSessionDescriptionCallback.idl @@ -897,7 +898,9 @@ set(WebCore_SOURCES Modules/mediastream/RTCIceCandidateEvent.cpp Modules/mediastream/RTCOfferAnswerOptions.cpp Modules/mediastream/RTCPeerConnection.cpp + Modules/mediastream/RTCRtpReceiver.cpp Modules/mediastream/RTCRtpSender.cpp + Modules/mediastream/RTCRtpSenderReceiverBase.cpp Modules/mediastream/RTCSessionDescription.cpp # Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp Modules/mediastream/RTCStatsReport.cpp diff --git a/Source/WebCore/DerivedSources.make b/Source/WebCore/DerivedSources.make index 0e41319493532..11813321cd49b 100644 --- a/Source/WebCore/DerivedSources.make +++ b/Source/WebCore/DerivedSources.make @@ -144,6 +144,8 @@ NON_SVG_BINDING_IDLS = \ $(WebCore)/Modules/mediastream/RTCIceServer.idl \ $(WebCore)/Modules/mediastream/RTCPeerConnection.idl \ $(WebCore)/Modules/mediastream/RTCPeerConnectionErrorCallback.idl \ + $(WebCore)/Modules/mediastream/RTCRtpReceiver.idl \ + $(WebCore)/Modules/mediastream/RTCRtpSender.idl \ $(WebCore)/Modules/mediastream/RTCSessionDescription.idl \ $(WebCore)/Modules/mediastream/RTCSessionDescriptionCallback.idl \ $(WebCore)/Modules/mediastream/RTCStatsCallback.idl \ diff --git a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp new file mode 100644 index 0000000000000..12bd342d70787 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "RTCRtpReceiver.h" + +#if ENABLE(MEDIA_STREAM) + +namespace WebCore { + +RefPtr RTCRtpReceiver::create(RefPtr&& track) +{ + return adoptRef(new RTCRtpReceiver(WTF::move(track))); +} + +RTCRtpReceiver::RTCRtpReceiver(RefPtr&& track) + : RTCRtpSenderReceiverBase(WTF::move(track)) +{ +} + +RTCRtpReceiver::~RTCRtpReceiver() +{ +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h new file mode 100644 index 0000000000000..83120a40a018c --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef RTCRtpReceiver_h +#define RTCRtpReceiver_h + +#if ENABLE(MEDIA_STREAM) + +#include "RTCRtpSenderReceiverBase.h" + +namespace WebCore { + +class RTCRtpReceiver : public RTCRtpSenderReceiverBase { +public: + static RefPtr create(RefPtr&&); + virtual ~RTCRtpReceiver(); + +private: + RTCRtpReceiver(RefPtr&&); +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // RTCRtpReceiver_h diff --git a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.idl b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.idl new file mode 100644 index 0000000000000..bd97c6993d48e --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.idl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +[ + Conditional=MEDIA_STREAM +] interface RTCRtpReceiver { + readonly attribute MediaStreamTrack track; +}; diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp index e7983048d9287..063e1e825b7bc 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp @@ -33,8 +33,6 @@ #if ENABLE(MEDIA_STREAM) -#include "MediaStreamTrack.h" - namespace WebCore { RefPtr RTCRtpSender::create(RefPtr&& track) @@ -43,7 +41,7 @@ RefPtr RTCRtpSender::create(RefPtr&& track) } RTCRtpSender::RTCRtpSender(RefPtr&& track) - : m_track(track) + : RTCRtpSenderReceiverBase(WTF::move(track)) { } @@ -51,11 +49,6 @@ RTCRtpSender::~RTCRtpSender() { } -MediaStreamTrack* RTCRtpSender::track() const -{ - return m_track.get(); -} - } // namespace WebCore #endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.h b/Source/WebCore/Modules/mediastream/RTCRtpSender.h index ba8509e166c73..32c0e4d0782ef 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpSender.h +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.h @@ -33,25 +33,17 @@ #if ENABLE(MEDIA_STREAM) -#include "ScriptWrappable.h" -#include -#include +#include "RTCRtpSenderReceiverBase.h" namespace WebCore { -class MediaStreamTrack; - -class RTCRtpSender : public RefCounted, public ScriptWrappable { +class RTCRtpSender : public RTCRtpSenderReceiverBase { public: static RefPtr create(RefPtr&&); virtual ~RTCRtpSender(); - MediaStreamTrack* track() const; - private: RTCRtpSender(RefPtr&&); - - RefPtr m_track; }; } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.cpp b/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.cpp new file mode 100644 index 0000000000000..90a2f19ae57ab --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "RTCRtpSenderReceiverBase.h" + +#if ENABLE(MEDIA_STREAM) + +#include "MediaStreamTrack.h" + +namespace WebCore { + +RTCRtpSenderReceiverBase::RTCRtpSenderReceiverBase(RefPtr&& track) + : m_track(track) +{ +} + +RTCRtpSenderReceiverBase::~RTCRtpSenderReceiverBase() +{ +} + +MediaStreamTrack* RTCRtpSenderReceiverBase::track() const +{ + return m_track.get(); +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h b/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h new file mode 100644 index 0000000000000..e52da1157ddc8 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCRtpSenderReceiverBase.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef RTCRtpSenderReceiverBase_h +#define RTCRtpSenderReceiverBase_h + +#if ENABLE(MEDIA_STREAM) + +#include "ScriptWrappable.h" +#include +#include + +namespace WebCore { + +class MediaStreamTrack; + +class RTCRtpSenderReceiverBase : public RefCounted, public ScriptWrappable { +public: + virtual ~RTCRtpSenderReceiverBase(); + + MediaStreamTrack* track() const; + +protected: + RTCRtpSenderReceiverBase(RefPtr&&); + + RefPtr m_track; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // RTCRtpSenderReceiverBase_h From b1ea12a717cbd21b80c2d9a9dbba3fedd3ab25b2 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 10 Apr 2015 11:03:38 +0200 Subject: [PATCH 038/155] RTCPeerConnection: Implement removeTrack() --- .../Modules/mediastream/RTCPeerConnection.cpp | 13 +++++++++++++ .../WebCore/Modules/mediastream/RTCPeerConnection.h | 1 + .../Modules/mediastream/RTCPeerConnection.idl | 1 + 3 files changed, 15 insertions(+) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 7f79e3fb932fe..9a2a6cf1e386e 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -215,6 +215,19 @@ RefPtr RTCPeerConnection::addTrack(RefPtr&& trac return sender; } +void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec) +{ + if (m_signalingState == SignalingStateClosed) { + ec = INVALID_STATE_ERR; + return; + } + + if (!m_senders.removeFirst(sender)) + return; + + // FIXME: Mark connection as needing negotiation. +} + void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 5249da4cf6f4f..e90d34dafee27 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -67,6 +67,7 @@ class RTCPeerConnection final : public RefCounted, public Scr Vector> getSenders() const; RefPtr addTrack(RefPtr&&, ExceptionCode&); + void removeTrack(RTCRtpSender*, ExceptionCode&); void createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback, RejectCallback, ExceptionCode&); void createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback, RejectCallback, ExceptionCode&); diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl index 18dc8353c2adf..08bd01ded05ab 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl @@ -46,6 +46,7 @@ sequence getSenders(); [StrictTypeChecking, RaisesException] RTCRtpSender addTrack(MediaStreamTrack track); + [StrictTypeChecking, RaisesException] void removeTrack(RTCRtpSender sender); [Custom, RaisesException] Promise setLocalDescription(RTCSessionDescription description); readonly attribute RTCSessionDescription localDescription; From ec14da4312f85d3bc74c58c2bd238bdfd51a4265 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 13 Apr 2015 12:50:16 +0200 Subject: [PATCH 039/155] RTCPeerConnection: Use HashMap for RTCRtpSender member set (and fix addTrack()) --- .../Modules/mediastream/RTCPeerConnection.cpp | 18 ++++++++++++++---- .../Modules/mediastream/RTCPeerConnection.h | 3 ++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 9a2a6cf1e386e..6cd39b000aa54 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -199,7 +199,11 @@ RTCPeerConnection::~RTCPeerConnection() Vector> RTCPeerConnection::getSenders() const { - return m_senders; + Vector> senders; + for (auto& sender : m_senderSet.values()) + senders.append(sender); + + return senders; } RefPtr RTCPeerConnection::addTrack(RefPtr&& track, ExceptionCode& ec) @@ -209,8 +213,14 @@ RefPtr RTCPeerConnection::addTrack(RefPtr&& trac return nullptr; } + if (m_senderSet.contains(track->id())) { + // FIXME: Spec says InvalidParameter + ec = INVALID_MODIFICATION_ERR; + return nullptr; + } + RefPtr sender = RTCRtpSender::create(WTF::move(track)); - m_senders.append(sender); + m_senderSet.add(track->id(), sender); return sender; } @@ -222,7 +232,7 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec) return; } - if (!m_senders.removeFirst(sender)) + if (!m_senderSet.remove(sender->track()->id())) return; // FIXME: Mark connection as needing negotiation. @@ -248,7 +258,7 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); Vector localTracks; - for (auto sender : m_senders) + for (auto sender : m_senderSet.values()) localTracks.append(sender->track()); // FIXME: update existing media descriptions with tracks diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index e90d34dafee27..f1ab6fbf8140b 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -41,6 +41,7 @@ #include "MediaEndpoint.h" #include "ScriptWrappable.h" #include "Timer.h" +#include #include namespace WebCore { @@ -172,7 +173,7 @@ class RTCPeerConnection final : public RefCounted, public Scr IceGatheringState m_iceGatheringState; IceConnectionState m_iceConnectionState; - Vector> m_senders; + HashMap> m_senderSet; // TODO m_receivers RefPtr m_localConfiguration; From 97d7e570695376257de3481d9ac7f472a23e4b99 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 13 Apr 2015 14:17:02 +0200 Subject: [PATCH 040/155] RTCPeerConnection: Add getReceivers() function --- .../WebCore/Modules/mediastream/RTCPeerConnection.cpp | 10 ++++++++++ Source/WebCore/Modules/mediastream/RTCPeerConnection.h | 4 +++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 6cd39b000aa54..f4462859f09a0 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -51,6 +51,7 @@ #include "RTCIceCandidate.h" #include "RTCIceCandidateEvent.h" #include "RTCOfferAnswerOptions.h" +#include "RTCRtpReceiver.h" #include "RTCRtpSender.h" #include "RTCSessionDescription.h" #include @@ -206,6 +207,15 @@ Vector> RTCPeerConnection::getSenders() const return senders; } +Vector> RTCPeerConnection::getReceivers() const +{ + Vector> receivers; + for (auto& receiver : m_receiverSet.values()) + receivers.append(receiver); + + return receivers; +} + RefPtr RTCPeerConnection::addTrack(RefPtr&& track, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index f1ab6fbf8140b..3d8df3bc3cda2 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -52,6 +52,7 @@ class RTCConfiguration; class RTCDataChannel; class RTCIceCandidate; class RTCPeerConnectionErrorCallback; +class RTCRtpReceiver; class RTCRtpSender; class RTCSessionDescription; class RTCStatsCallback; @@ -66,6 +67,7 @@ class RTCPeerConnection final : public RefCounted, public Scr typedef std::function)> RejectCallback; Vector> getSenders() const; + Vector> getReceivers() const; RefPtr addTrack(RefPtr&&, ExceptionCode&); void removeTrack(RTCRtpSender*, ExceptionCode&); @@ -174,7 +176,7 @@ class RTCPeerConnection final : public RefCounted, public Scr IceConnectionState m_iceConnectionState; HashMap> m_senderSet; - // TODO m_receivers + HashMap> m_receiverSet; RefPtr m_localConfiguration; RefPtr m_remoteConfiguration; From 93ff28c9b28f99394e19d16e889888b9f8457fc7 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 13 Apr 2015 19:43:51 +0200 Subject: [PATCH 041/155] RTCOfferAnswerOptions: Remove private, align with spec (PR) and remove PassRefPtr --- .../mediastream/RTCOfferAnswerOptions.cpp | 74 ++++++------ .../mediastream/RTCOfferAnswerOptions.h | 45 +++++--- .../Modules/mediastream/RTCPeerConnection.cpp | 2 +- .../RTCOfferAnswerOptionsPrivate.h | 108 ------------------ 4 files changed, 69 insertions(+), 160 deletions(-) delete mode 100644 Source/WebCore/platform/mediastream/RTCOfferAnswerOptionsPrivate.h diff --git a/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp index 1855b80c5747e..a188ccea19bb4 100644 --- a/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp +++ b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,34 +33,21 @@ namespace WebCore { -PassRefPtr RTCOfferAnswerOptions::create(const Dictionary& options, ExceptionCode& ec) +RTCOfferAnswerOptions::RTCOfferAnswerOptions() + : m_voiceActivityDetection(true) { - RefPtr offerAnswerOptions = adoptRef(new RTCOfferAnswerOptions()); - String requestIdentity; - if (!offerAnswerOptions->initialize(options)) { - // FIXME: https://webkit.org/b/129800 - // According to the spec, the error is going to be defined yet, so let's use TYPE_MISMATCH_ERR for now. - ec = TYPE_MISMATCH_ERR; - return nullptr; - } - - return offerAnswerOptions.release(); } bool RTCOfferAnswerOptions::initialize(const Dictionary& options) { - if (!m_private) - m_private = RTCOfferAnswerOptionsPrivate::create(); - - String requestIdentity; - if (!options.isUndefinedOrNull() && (!options.get("requestIdentity", requestIdentity) || requestIdentity.isEmpty())) - return false; + bool voiceActivityDetection; + if (options.get("voiceActivityDetection", voiceActivityDetection)) + m_voiceActivityDetection = voiceActivityDetection; - m_private->setRequestIdentity(requestIdentity); return true; } -PassRefPtr RTCOfferOptions::create(const Dictionary& options, ExceptionCode& ec) +RefPtr RTCOfferOptions::create(const Dictionary& options, ExceptionCode& ec) { RefPtr offerOptions = adoptRef(new RTCOfferOptions()); if (!offerOptions->initialize(options)) { @@ -69,20 +57,21 @@ PassRefPtr RTCOfferOptions::create(const Dictionary& options, E return nullptr; } - return offerOptions.release(); + return offerOptions; } -bool RTCOfferOptions::initialize(const Dictionary& options) +RTCOfferOptions::RTCOfferOptions() + : m_offerToReceiveVideo(0) + , m_offerToReceiveAudio(0) + , m_iceRestart(false) { - RefPtr optionsPrivate = RTCOfferOptionsPrivate::create(); - m_private = optionsPrivate; +} +bool RTCOfferOptions::initialize(const Dictionary& options) +{ if (options.isUndefinedOrNull()) return true; - if (!RTCOfferAnswerOptions::initialize(options)) - return false; - String offerToReceiveVideoStr; bool numberConversionSuccess; if (!options.get("offerToReceiveVideo", offerToReceiveVideoStr)) @@ -92,7 +81,7 @@ bool RTCOfferOptions::initialize(const Dictionary& options) if (!numberConversionSuccess) return false; - optionsPrivate->setOfferToReceiveVideo(intConversionResult); + m_offerToReceiveVideo = intConversionResult; String offerToReceiveAudioStr; if (!options.get("offerToReceiveAudio", offerToReceiveAudioStr)) @@ -102,17 +91,34 @@ bool RTCOfferOptions::initialize(const Dictionary& options) if (!numberConversionSuccess) return false; - optionsPrivate->setOfferToReceiveAudio(intConversionResult); - - bool voiceActivityDetection; - if (options.get("voiceActivityDetection", voiceActivityDetection)) - optionsPrivate->setVoiceActivityDetection(voiceActivityDetection); + m_offerToReceiveAudio = intConversionResult; bool iceRestart; if (options.get("iceRestart", iceRestart)) - optionsPrivate->setIceRestart(iceRestart); + m_iceRestart = iceRestart; - return true; + return RTCOfferAnswerOptions::initialize(options); +} + +RefPtr RTCAnswerOptions::create(const Dictionary& options, ExceptionCode& ec) +{ + RefPtr offerOptions = adoptRef(new RTCAnswerOptions()); + if (!offerOptions->initialize(options)) { + // FIXME: https://webkit.org/b/129800 + // According to the spec, the error is going to be defined yet, so let's use TYPE_MISMATCH_ERR for now. + ec = TYPE_MISMATCH_ERR; + return nullptr; + } + + return offerOptions; +} + +bool RTCAnswerOptions::initialize(const Dictionary& options) +{ + if (options.isUndefinedOrNull()) + return true; + + return RTCOfferAnswerOptions::initialize(options); } } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.h b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.h index ad58248bd001c..91bf571d1ed04 100644 --- a/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.h +++ b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,45 +31,55 @@ #include "Dictionary.h" #include "ExceptionCode.h" -#include "RTCOfferAnswerOptionsPrivate.h" -#include +#include #include namespace WebCore { class Dictionary; +// FIXME: The WebRTC spec (as of 2015-04-13) only has a RTCOfferOptions, but a pending pull request +// reintroduces RTCOfferAnswerOptions as a common base for RTCOfferOptions and RTCAnswerOptions. +// This feature needs to be updated accordingly when that discussion is resolved. class RTCOfferAnswerOptions : public RefCounted { public: - static PassRefPtr create(const Dictionary&, ExceptionCode&); - - const String& requestIdentity() const { return m_private->requestIdentity(); } - RTCOfferAnswerOptionsPrivate* privateOfferAnswerOptions() const { return m_private.get(); } - virtual ~RTCOfferAnswerOptions() { } + bool voiceActivityDetection() const { return m_voiceActivityDetection; } + protected: virtual bool initialize(const Dictionary&); - RTCOfferAnswerOptions() { } + RTCOfferAnswerOptions(); - RefPtr m_private; + bool m_voiceActivityDetection; }; class RTCOfferOptions : public RTCOfferAnswerOptions { public: - static PassRefPtr create(const Dictionary&, ExceptionCode&); + static RefPtr create(const Dictionary&, ExceptionCode&); + virtual ~RTCOfferOptions() { } - int64_t offerToReceiveVideo() const { return privateOfferOptions()->offerToReceiveVideo(); } - int64_t offerToReceiveAudio() const { return privateOfferOptions()->offerToReceiveAudio(); } - bool voiceActivityDetection() const { return privateOfferOptions()->voiceActivityDetection(); } - bool iceRestart() const { return privateOfferOptions()->iceRestart(); } - RTCOfferOptionsPrivate* privateOfferOptions() const { return static_cast(m_private.get()); } + int64_t offerToReceiveVideo() const { return m_offerToReceiveVideo; } + int64_t offerToReceiveAudio() const { return m_offerToReceiveAudio; } + bool iceRestart() const { return m_iceRestart; } - virtual ~RTCOfferOptions() { } +private: + virtual bool initialize(const Dictionary&) override; + RTCOfferOptions(); + + int64_t m_offerToReceiveVideo; + int64_t m_offerToReceiveAudio; + bool m_iceRestart; +}; + +class RTCAnswerOptions : public RTCOfferAnswerOptions { +public: + static RefPtr create(const Dictionary&, ExceptionCode&); + virtual ~RTCAnswerOptions() { } private: virtual bool initialize(const Dictionary&) override; - RTCOfferOptions() { } + RTCAnswerOptions() { } }; } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index f4462859f09a0..4e838b5162d46 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -297,7 +297,7 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe return; } - RefPtr options = RTCOfferAnswerOptions::create(answerOptions, ec); + RefPtr options = RTCAnswerOptions::create(answerOptions, ec); if (ec) { callOnMainThread([rejectCallback] { RefPtr error = DOMError::create("Invalid createAnswer argument."); diff --git a/Source/WebCore/platform/mediastream/RTCOfferAnswerOptionsPrivate.h b/Source/WebCore/platform/mediastream/RTCOfferAnswerOptionsPrivate.h deleted file mode 100644 index 21e283e282bad..0000000000000 --- a/Source/WebCore/platform/mediastream/RTCOfferAnswerOptionsPrivate.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2014 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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. - */ - -#ifndef RTCOfferAnswerOptionsPrivate_h -#define RTCOfferAnswerOptionsPrivate_h - -#if ENABLE(MEDIA_STREAM) - -#include -#include -#include - -namespace WebCore { - -static bool validateRequestIdentity(const String& value) -{ - return value == "yes" || value == "no" || value == "ifconfigured"; -} - -class RTCOfferAnswerOptionsPrivate : public RefCounted { -public: - static PassRefPtr create() - { - return adoptRef(new RTCOfferAnswerOptionsPrivate()); - } - - const String& requestIdentity() const { return m_requestIdentity; } - void setRequestIdentity(const String& requestIdentity) - { - if (!validateRequestIdentity(requestIdentity)) - return; - - m_requestIdentity = requestIdentity; - } - - virtual ~RTCOfferAnswerOptionsPrivate() { } - -protected: - RTCOfferAnswerOptionsPrivate() - : m_requestIdentity("ifconfigured") - { - } - -private: - String m_requestIdentity; -}; - -class RTCOfferOptionsPrivate : public RTCOfferAnswerOptionsPrivate { -public: - static PassRefPtr create() - { - return adoptRef(new RTCOfferOptionsPrivate()); - } - - int64_t offerToReceiveVideo() const { return m_offerToReceiveVideo; } - void setOfferToReceiveVideo(int64_t offerToReceiveVideo) { m_offerToReceiveVideo = offerToReceiveVideo; } - int64_t offerToReceiveAudio() const { return m_offerToReceiveAudio; } - void setOfferToReceiveAudio(int64_t offerToReceiveAudio) { m_offerToReceiveAudio = offerToReceiveAudio; } - bool voiceActivityDetection() const { return m_voiceActivityDetection; } - void setVoiceActivityDetection(bool voiceActivityDetection) { m_voiceActivityDetection = voiceActivityDetection; } - bool iceRestart() const { return m_iceRestart; } - void setIceRestart(bool iceRestart) { m_iceRestart = iceRestart; } - - virtual ~RTCOfferOptionsPrivate() { } - -private: - RTCOfferOptionsPrivate() - : RTCOfferAnswerOptionsPrivate() - , m_offerToReceiveVideo(0) - , m_offerToReceiveAudio(0) - , m_voiceActivityDetection(true) - , m_iceRestart(false) - { - } - - int64_t m_offerToReceiveVideo; - int64_t m_offerToReceiveAudio; - bool m_voiceActivityDetection; - bool m_iceRestart; -}; - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) - -#endif // RTCOfferAnswerOptionsPrivate_h From a800ce9bb6984bbec0d95319ff8cbd3f67623b1f Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 14 Apr 2015 08:12:15 +0200 Subject: [PATCH 042/155] RTCConfiguration: Use a cpp file --- Source/WebCore/CMakeLists.txt | 1 + .../Modules/mediastream/RTCConfiguration.cpp | 78 +++++++++++++++++++ .../Modules/mediastream/RTCConfiguration.h | 29 ++----- 3 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 Source/WebCore/Modules/mediastream/RTCConfiguration.cpp diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 59a828ce4e630..5cbc62e1ee3fb 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -890,6 +890,7 @@ set(WebCore_SOURCES Modules/mediastream/NavigatorMediaDevices.cpp Modules/mediastream/NavigatorUserMedia.cpp Modules/mediastream/NavigatorUserMediaError.cpp + Modules/mediastream/RTCConfiguration.cpp Modules/mediastream/RTCDTMFSender.cpp Modules/mediastream/RTCDTMFToneChangeEvent.cpp Modules/mediastream/RTCDataChannel.cpp diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp new file mode 100644 index 0000000000000..7460b2e04f9ca --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "RTCConfiguration.h" + +#if ENABLE(MEDIA_STREAM) + +// #include "Dictionary.h" +// #include "ExceptionCode.h" + +namespace WebCore { + +PassRefPtr RTCConfiguration::create() +{ + return adoptRef(new RTCConfiguration()); +} + +RTCConfiguration::RTCConfiguration() + : m_private(RTCConfigurationPrivate::create()) +{ +} + +void RTCConfiguration::appendServer(PassRefPtr server) +{ + m_private->appendServer(server->privateServer()); +} + +PassRefPtr RTCConfiguration::server(size_t index) +{ + RTCIceServerPrivate* server = m_private->server(index); + if (!server) + return nullptr; + + return RTCIceServer::create(server); +} + +Vector> RTCConfiguration::iceServers() const +{ + Vector> servers; + Vector> privateServers = m_private->iceServers(); + + for (auto iter = privateServers.begin(); iter != privateServers.end(); ++iter) + servers.append(RTCIceServer::create(*iter)); + + return servers; +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.h b/Source/WebCore/Modules/mediastream/RTCConfiguration.h index 41051a93496d6..3c6321d2536b1 100644 --- a/Source/WebCore/Modules/mediastream/RTCConfiguration.h +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.h @@ -44,19 +44,12 @@ namespace WebCore { class RTCConfiguration : public RefCounted { public: - static PassRefPtr create() { return adoptRef(new RTCConfiguration()); } + static PassRefPtr create(); virtual ~RTCConfiguration() { } - void appendServer(PassRefPtr server) { m_private->appendServer(server->privateServer()); } + void appendServer(PassRefPtr); size_t numberOfServers() { return m_private->numberOfServers(); } - PassRefPtr server(size_t index) - { - RTCIceServerPrivate* server = m_private->server(index); - if (!server) - return nullptr; - - return RTCIceServer::create(server); - } + PassRefPtr server(size_t index); const String& iceTransports() const { return m_private->iceTransports(); } void setIceTransports(const String& iceTransports) { m_private->setIceTransports(iceTransports); } @@ -64,24 +57,12 @@ class RTCConfiguration : public RefCounted { const String& requestIdentity() const { return m_private->requestIdentity(); } void setRequestIdentity(const String& requestIdentity) { m_private->setRequestIdentity(requestIdentity); } - Vector> iceServers() const - { - Vector> servers; - Vector> privateServers = m_private->iceServers(); - - for (auto iter = privateServers.begin(); iter != privateServers.end(); ++iter) - servers.append(RTCIceServer::create(*iter)); - - return servers; - } + Vector> iceServers() const; RTCConfigurationPrivate* privateConfiguration() { return m_private.get(); } private: - RTCConfiguration() - : m_private(RTCConfigurationPrivate::create()) - { - } + RTCConfiguration(); RefPtr m_private; }; From 2df65bfb43893a81a885bcb30ebead4989c237a2 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 14 Apr 2015 09:13:33 +0200 Subject: [PATCH 043/155] RTCConfiguration: Move configuration parsing from RTCPeerConnection to RTCConfiguration --- .../Modules/mediastream/RTCConfiguration.cpp | 96 ++++++++++++++++++- .../Modules/mediastream/RTCConfiguration.h | 6 +- .../Modules/mediastream/RTCPeerConnection.cpp | 94 +----------------- .../Modules/mediastream/RTCPeerConnection.h | 1 - 4 files changed, 99 insertions(+), 98 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp index 7460b2e04f9ca..b0f69850b79b9 100644 --- a/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp @@ -1,4 +1,6 @@ /* + * Copyright (C) 2012 Google Inc. All rights reserved. + * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,14 +35,100 @@ #if ENABLE(MEDIA_STREAM) -// #include "Dictionary.h" -// #include "ExceptionCode.h" +#include "ArrayValue.h" +#include "Dictionary.h" +#include "ExceptionCode.h" +#include "URL.h" namespace WebCore { -PassRefPtr RTCConfiguration::create() +static bool validateIceServerURL(const String& iceURL) { - return adoptRef(new RTCConfiguration()); + URL url(URL(), iceURL); + if (url.isEmpty() || !url.isValid() || !(url.protocolIs("turn") || url.protocolIs("stun"))) + return false; + + return true; +} + +static ExceptionCode processIceServer(const Dictionary& iceServer, RTCConfiguration* rtcConfiguration) +{ + String credential, username; + iceServer.get("credential", credential); + iceServer.get("username", username); + + // Spec says that "urls" can be either a string or a sequence, so we must check for both. + Vector urlsList; + String urlString; + iceServer.get("urls", urlString); + // This is the only way to check if "urls" is a sequence or a string. If we try to convert + // to a sequence and it fails (in case it is a string), an exception will be set and the + // RTCPeerConnection will fail. + // So we convert to a string always, which converts a sequence to a string in the format: "foo, bar, ..", + // then checking for a comma in the string assures that a string was a sequence and then we convert + // it to a sequence safely. + if (urlString.isEmpty()) + return INVALID_ACCESS_ERR; + + if (urlString.find(',') != notFound && iceServer.get("urls", urlsList) && urlsList.size()) { + for (auto iter = urlsList.begin(); iter != urlsList.end(); ++iter) { + if (!validateIceServerURL(*iter)) + return INVALID_ACCESS_ERR; + } + } else { + if (!validateIceServerURL(urlString)) + return INVALID_ACCESS_ERR; + + urlsList.append(urlString); + } + + rtcConfiguration->appendServer(RTCIceServer::create(urlsList, credential, username)); + return 0; +} + +PassRefPtr RTCConfiguration::create(const Dictionary& configuration, ExceptionCode& ec) +{ + if (configuration.isUndefinedOrNull()) + return nullptr; + + ArrayValue iceServers; + bool ok = configuration.get("iceServers", iceServers); + if (!ok || iceServers.isUndefinedOrNull()) { + ec = TYPE_MISMATCH_ERR; + return nullptr; + } + + size_t numberOfServers; + ok = iceServers.length(numberOfServers); + if (!ok || !numberOfServers) { + ec = !ok ? TYPE_MISMATCH_ERR : INVALID_ACCESS_ERR; + return nullptr; + } + + String iceTransports; + String requestIdentity; + configuration.get("iceTransports", iceTransports); + configuration.get("requestIdentity", requestIdentity); + + RefPtr rtcConfiguration = adoptRef(new RTCConfiguration()); + + rtcConfiguration->setIceTransports(iceTransports); + rtcConfiguration->setRequestIdentity(requestIdentity); + + for (size_t i = 0; i < numberOfServers; ++i) { + Dictionary iceServer; + ok = iceServers.get(i, iceServer); + if (!ok) { + ec = TYPE_MISMATCH_ERR; + return nullptr; + } + + ec = processIceServer(iceServer, rtcConfiguration.get()); + if (ec) + return nullptr; + } + + return rtcConfiguration.release(); } RTCConfiguration::RTCConfiguration() diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.h b/Source/WebCore/Modules/mediastream/RTCConfiguration.h index 3c6321d2536b1..94e6715fefe21 100644 --- a/Source/WebCore/Modules/mediastream/RTCConfiguration.h +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.h @@ -42,9 +42,13 @@ namespace WebCore { +class Dictionary; + +typedef int ExceptionCode; + class RTCConfiguration : public RefCounted { public: - static PassRefPtr create(); + static PassRefPtr create(const Dictionary& configuration, ExceptionCode&); virtual ~RTCConfiguration() { } void appendServer(PassRefPtr); diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 4e838b5162d46..f4038f8c18ac8 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -36,7 +36,6 @@ #include "RTCPeerConnection.h" -#include "ArrayValue.h" #include "DOMError.h" #include "Document.h" #include "Event.h" @@ -58,100 +57,11 @@ namespace WebCore { -static bool validateIceServerURL(const String& iceURL) -{ - URL url(URL(), iceURL); - if (url.isEmpty() || !url.isValid() || !(url.protocolIs("turn") || url.protocolIs("stun"))) - return false; - - return true; -} - -static ExceptionCode processIceServer(const Dictionary& iceServer, RTCConfiguration* rtcConfiguration) -{ - String credential, username; - iceServer.get("credential", credential); - iceServer.get("username", username); - - // Spec says that "urls" can be either a string or a sequence, so we must check for both. - Vector urlsList; - String urlString; - iceServer.get("urls", urlString); - // This is the only way to check if "urls" is a sequence or a string. If we try to convert - // to a sequence and it fails (in case it is a string), an exception will be set and the - // RTCPeerConnection will fail. - // So we convert to a string always, which converts a sequence to a string in the format: "foo, bar, ..", - // then checking for a comma in the string assures that a string was a sequence and then we convert - // it to a sequence safely. - if (urlString.isEmpty()) - return INVALID_ACCESS_ERR; - - if (urlString.find(',') != notFound && iceServer.get("urls", urlsList) && urlsList.size()) { - for (auto iter = urlsList.begin(); iter != urlsList.end(); ++iter) { - if (!validateIceServerURL(*iter)) - return INVALID_ACCESS_ERR; - } - } else { - if (!validateIceServerURL(urlString)) - return INVALID_ACCESS_ERR; - - urlsList.append(urlString); - } - - rtcConfiguration->appendServer(RTCIceServer::create(urlsList, credential, username)); - return 0; -} - -PassRefPtr RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionCode& ec) -{ - if (configuration.isUndefinedOrNull()) - return nullptr; - - ArrayValue iceServers; - bool ok = configuration.get("iceServers", iceServers); - if (!ok || iceServers.isUndefinedOrNull()) { - ec = TYPE_MISMATCH_ERR; - return nullptr; - } - - size_t numberOfServers; - ok = iceServers.length(numberOfServers); - if (!ok || !numberOfServers) { - ec = !ok ? TYPE_MISMATCH_ERR : INVALID_ACCESS_ERR; - return nullptr; - } - - String iceTransports; - String requestIdentity; - configuration.get("iceTransports", iceTransports); - configuration.get("requestIdentity", requestIdentity); - - RefPtr rtcConfiguration = RTCConfiguration::create(); - - rtcConfiguration->setIceTransports(iceTransports); - rtcConfiguration->setRequestIdentity(requestIdentity); - - for (size_t i = 0; i < numberOfServers; ++i) { - Dictionary iceServer; - ok = iceServers.get(i, iceServer); - if (!ok) { - ec = TYPE_MISMATCH_ERR; - return nullptr; - } - - ec = processIceServer(iceServer, rtcConfiguration.get()); - if (ec) - return nullptr; - } - - return rtcConfiguration.release(); -} - PassRefPtr RTCPeerConnection::create(ScriptExecutionContext& context, const Dictionary& rtcConfiguration, ExceptionCode& ec) { printf("-> RTCConfiguration::create\n"); - RefPtr configuration = parseConfiguration(rtcConfiguration, ec); + RefPtr configuration = RTCConfiguration::create(rtcConfiguration, ec); if (ec) return nullptr; @@ -382,7 +292,7 @@ void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionC return; } - m_configuration = parseConfiguration(rtcConfiguration, ec); + m_configuration = RTCConfiguration::create(rtcConfiguration, ec); if (ec) return; diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 3d8df3bc3cda2..78e2a9faaa637 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -151,7 +151,6 @@ class RTCPeerConnection final : public RefCounted, public Scr RTCPeerConnection(ScriptExecutionContext&, PassRefPtr, ExceptionCode&); - static PassRefPtr parseConfiguration(const Dictionary& configuration, ExceptionCode&); SignalingState targetSignalingState(SetterType, DescriptionType) const; DescriptionType parseDescriptionType(const String& typeName) const; From f0f724808a8da942dc293ff32c7ea6cca180a5e4 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 15 Apr 2015 10:54:30 +0200 Subject: [PATCH 044/155] RTCConfiguration: Remove platform connection (privates). Introduced MediaEndpointInit (needs more work) --- Source/WebCore/CMakeLists.txt | 1 + .../Modules/mediastream/RTCConfiguration.cpp | 107 ++++++++---------- .../Modules/mediastream/RTCConfiguration.h | 27 ++--- .../Modules/mediastream/RTCConfiguration.idl | 8 +- .../Modules/mediastream/RTCIceServer.h | 30 ++--- .../Modules/mediastream/RTCPeerConnection.cpp | 16 ++- .../platform/mediastream/MediaEndpoint.h | 6 +- .../mediastream/MediaEndpointInit.cpp | 62 ++++++++++ .../platform/mediastream/MediaEndpointInit.h | 102 +++++++++++++++++ .../mediastream/RTCConfigurationPrivate.h | 80 ------------- .../mediastream/RTCIceServerPrivate.h | 67 ----------- .../openwebrtc/MediaEndpointOwr.cpp | 6 +- .../mediastream/openwebrtc/MediaEndpointOwr.h | 4 +- 13 files changed, 260 insertions(+), 256 deletions(-) create mode 100644 Source/WebCore/platform/mediastream/MediaEndpointInit.cpp create mode 100644 Source/WebCore/platform/mediastream/MediaEndpointInit.h delete mode 100644 Source/WebCore/platform/mediastream/RTCConfigurationPrivate.h delete mode 100644 Source/WebCore/platform/mediastream/RTCIceServerPrivate.h diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 5cbc62e1ee3fb..bff186ea8babd 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -2195,6 +2195,7 @@ set(WebCore_SOURCES platform/graphics/transforms/TranslateTransformOperation.cpp platform/mediastream/MediaEndpointConfigurationConversions.cpp + platform/mediastream/MediaEndpointInit.cpp platform/mediastream/MediaStreamPrivate.cpp platform/mediastream/MediaStreamTrackPrivate.cpp platform/mediastream/RealtimeMediaSource.cpp diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp index b0f69850b79b9..b3cc46fc54f6a 100644 --- a/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp @@ -51,7 +51,7 @@ static bool validateIceServerURL(const String& iceURL) return true; } -static ExceptionCode processIceServer(const Dictionary& iceServer, RTCConfiguration* rtcConfiguration) +static RefPtr parseIceServer(const Dictionary& iceServer, ExceptionCode& ec) { String credential, username; iceServer.get("credential", credential); @@ -67,98 +67,89 @@ static ExceptionCode processIceServer(const Dictionary& iceServer, RTCConfigurat // So we convert to a string always, which converts a sequence to a string in the format: "foo, bar, ..", // then checking for a comma in the string assures that a string was a sequence and then we convert // it to a sequence safely. - if (urlString.isEmpty()) - return INVALID_ACCESS_ERR; + if (urlString.isEmpty()) { + ec = INVALID_ACCESS_ERR; + return nullptr; + } if (urlString.find(',') != notFound && iceServer.get("urls", urlsList) && urlsList.size()) { for (auto iter = urlsList.begin(); iter != urlsList.end(); ++iter) { - if (!validateIceServerURL(*iter)) - return INVALID_ACCESS_ERR; + if (!validateIceServerURL(*iter)) { + ec = INVALID_ACCESS_ERR; + return nullptr; + } } } else { - if (!validateIceServerURL(urlString)) - return INVALID_ACCESS_ERR; + if (!validateIceServerURL(urlString)) { + ec = INVALID_ACCESS_ERR; + return nullptr; + } urlsList.append(urlString); } - rtcConfiguration->appendServer(RTCIceServer::create(urlsList, credential, username)); - return 0; + return RTCIceServer::create(urlsList, credential, username); } -PassRefPtr RTCConfiguration::create(const Dictionary& configuration, ExceptionCode& ec) +RefPtr RTCConfiguration::create(const Dictionary& configuration, ExceptionCode& ec) { if (configuration.isUndefinedOrNull()) return nullptr; + RefPtr rtcConfiguration = adoptRef(new RTCConfiguration()); + rtcConfiguration->initialize(configuration, ec); + if (ec) + return nullptr; + + return rtcConfiguration; +} + +RTCConfiguration::RTCConfiguration() + : m_iceTransportPolicy("all") + , m_bundlePolicy("balanced") +{ +} + +void RTCConfiguration::initialize(const Dictionary& configuration, ExceptionCode& ec) +{ ArrayValue iceServers; bool ok = configuration.get("iceServers", iceServers); if (!ok || iceServers.isUndefinedOrNull()) { ec = TYPE_MISMATCH_ERR; - return nullptr; + return; } size_t numberOfServers; ok = iceServers.length(numberOfServers); if (!ok || !numberOfServers) { ec = !ok ? TYPE_MISMATCH_ERR : INVALID_ACCESS_ERR; - return nullptr; + return; } - String iceTransports; - String requestIdentity; - configuration.get("iceTransports", iceTransports); - configuration.get("requestIdentity", requestIdentity); - - RefPtr rtcConfiguration = adoptRef(new RTCConfiguration()); - - rtcConfiguration->setIceTransports(iceTransports); - rtcConfiguration->setRequestIdentity(requestIdentity); - for (size_t i = 0; i < numberOfServers; ++i) { - Dictionary iceServer; - ok = iceServers.get(i, iceServer); + Dictionary iceServerDict; + ok = iceServers.get(i, iceServerDict); if (!ok) { ec = TYPE_MISMATCH_ERR; - return nullptr; + return; } - ec = processIceServer(iceServer, rtcConfiguration.get()); - if (ec) - return nullptr; - } - - return rtcConfiguration.release(); -} - -RTCConfiguration::RTCConfiguration() - : m_private(RTCConfigurationPrivate::create()) -{ -} + RefPtr iceServer = parseIceServer(iceServerDict, ec); + if (!iceServer) + return; -void RTCConfiguration::appendServer(PassRefPtr server) -{ - m_private->appendServer(server->privateServer()); -} - -PassRefPtr RTCConfiguration::server(size_t index) -{ - RTCIceServerPrivate* server = m_private->server(index); - if (!server) - return nullptr; - - return RTCIceServer::create(server); -} - -Vector> RTCConfiguration::iceServers() const -{ - Vector> servers; - Vector> privateServers = m_private->iceServers(); + m_iceServers.append(WTF::move(iceServer)); + } - for (auto iter = privateServers.begin(); iter != privateServers.end(); ++iter) - servers.append(RTCIceServer::create(*iter)); + String iceTransportPolicy; + configuration.get("iceTransportPolicy", iceTransportPolicy); + if (iceTransportPolicy == "none" || iceTransportPolicy == "relay" || iceTransportPolicy == "all") + m_iceTransportPolicy = iceTransportPolicy; - return servers; + String bundlePolicy; + configuration.get("bundlePolicy", bundlePolicy); + if (bundlePolicy == "balanced" || bundlePolicy == "max-compat" || bundlePolicy == "max-bundle") + m_bundlePolicy = bundlePolicy; } } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.h b/Source/WebCore/Modules/mediastream/RTCConfiguration.h index 94e6715fefe21..004963d2d5482 100644 --- a/Source/WebCore/Modules/mediastream/RTCConfiguration.h +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.h @@ -33,10 +33,9 @@ #if ENABLE(MEDIA_STREAM) -#include "RTCConfigurationPrivate.h" #include "RTCIceServer.h" -#include #include +#include #include #include @@ -48,27 +47,21 @@ typedef int ExceptionCode; class RTCConfiguration : public RefCounted { public: - static PassRefPtr create(const Dictionary& configuration, ExceptionCode&); + static RefPtr create(const Dictionary& configuration, ExceptionCode&); virtual ~RTCConfiguration() { } - void appendServer(PassRefPtr); - size_t numberOfServers() { return m_private->numberOfServers(); } - PassRefPtr server(size_t index); - - const String& iceTransports() const { return m_private->iceTransports(); } - void setIceTransports(const String& iceTransports) { m_private->setIceTransports(iceTransports); } - - const String& requestIdentity() const { return m_private->requestIdentity(); } - void setRequestIdentity(const String& requestIdentity) { m_private->setRequestIdentity(requestIdentity); } - - Vector> iceServers() const; - - RTCConfigurationPrivate* privateConfiguration() { return m_private.get(); } + const String& iceTransportPolicy() const { return m_iceTransportPolicy; } + const String& bundlePolicy() const { return m_bundlePolicy; } + Vector> iceServers() const { return m_iceServers; } private: RTCConfiguration(); - RefPtr m_private; + void initialize(const Dictionary& configuration, ExceptionCode&); + + Vector> m_iceServers; + String m_iceTransportPolicy; + String m_bundlePolicy; }; } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.idl b/Source/WebCore/Modules/mediastream/RTCConfiguration.idl index 046830b0cf5a7..a2776d8466a30 100644 --- a/Source/WebCore/Modules/mediastream/RTCConfiguration.idl +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.idl @@ -23,14 +23,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -enum RTCIceTransportsEnum { "none", "relay", "all" }; -enum RTCIdentityOptionEnum { "yes", "no", "ifconfigured" }; +enum RTCIceTransportPolicyEnum { "none", "relay", "all" }; +enum RTCBundlePolicyEnum { "balanced", "max-compat", "max-bundle" }; [ Conditional=MEDIA_STREAM, NoInterfaceObject, ] interface RTCConfiguration { readonly attribute RTCIceServer[] iceServers; - readonly attribute RTCIceTransportsEnum iceTransports; - readonly attribute RTCIdentityOptionEnum requestIdentity; + readonly attribute RTCIceTransportPolicyEnum iceTransportPolicy; + readonly attribute RTCBundlePolicyEnum bundlePolicy; }; diff --git a/Source/WebCore/Modules/mediastream/RTCIceServer.h b/Source/WebCore/Modules/mediastream/RTCIceServer.h index eca258fb46272..07057590ce675 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceServer.h +++ b/Source/WebCore/Modules/mediastream/RTCIceServer.h @@ -28,7 +28,6 @@ #if ENABLE(MEDIA_STREAM) -#include "RTCIceServerPrivate.h" #include #include #include @@ -42,31 +41,22 @@ class RTCIceServer : public RefCounted { { return adoptRef(new RTCIceServer(urls, credential, username)); } - - static PassRefPtr create(PassRefPtr server) - { - return adoptRef(new RTCIceServer(server)); - } - virtual ~RTCIceServer() { } - const Vector& urls() { return m_private->urls(); } - const String& credential() { return m_private->credential(); } - const String& username() { return m_private->username(); } - RTCIceServerPrivate* privateServer() { return m_private.get(); } + const Vector& urls() const { return m_urls; } + const String& credential() const { return m_credential; } + const String& username() const { return m_username; } private: RTCIceServer(const Vector& urls, const String& credential, const String& username) - : m_private(RTCIceServerPrivate::create(urls, credential, username)) - { - } - - RTCIceServer(PassRefPtr server) - : m_private(server) - { - } + : m_urls(urls) + , m_credential(credential) + , m_username(username) + { } - RefPtr m_private; + Vector m_urls; + String m_credential; + String m_username; }; } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index f4038f8c18ac8..1c40ddf280d11 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -43,6 +43,7 @@ #include "Frame.h" #include "MediaEndpointConfiguration.h" #include "MediaEndpointConfigurationConversions.h" +#include "MediaEndpointInit.h" #include "MediaStreamTrack.h" #include "PeerMediaDescription.h" #include "RTCConfiguration.h" @@ -57,6 +58,15 @@ namespace WebCore { +static RefPtr createMediaEndpointInit(RTCConfiguration& rtcConfig) +{ + Vector> iceServers; + for (auto& server : rtcConfig.iceServers()) + iceServers.append(IceServerInfo::create(server->urls(), server->credential(), server->username())); + + return MediaEndpointInit::create(iceServers, rtcConfig.iceTransportPolicy(), rtcConfig.bundlePolicy()); +} + PassRefPtr RTCPeerConnection::create(ScriptExecutionContext& context, const Dictionary& rtcConfiguration, ExceptionCode& ec) { printf("-> RTCConfiguration::create\n"); @@ -100,7 +110,7 @@ RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr return; } - m_mediaEndpoint->setConfiguration(m_configuration->privateConfiguration()); + m_mediaEndpoint->setConfiguration(createMediaEndpointInit(*m_configuration)); } RTCPeerConnection::~RTCPeerConnection() @@ -296,7 +306,9 @@ void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionC if (ec) return; - // FIXME: use configuration + // FIXME: updateIce() might be renamed to setConfiguration(). It's also possible + // that its current behavior with update deltas will change. + m_mediaEndpoint->setConfiguration(createMediaEndpointInit(*m_configuration)); } void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index b29f0be07851e..4488e726fe5b5 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -33,7 +33,8 @@ #if ENABLE(MEDIA_STREAM) -#include "RTCConfigurationPrivate.h" +// #include "RTCConfigurationPrivate.h" +#include "MediaEndpointInit.h" #include namespace WebCore { @@ -61,7 +62,8 @@ class MediaEndpoint { WEBCORE_EXPORT static CreateMediaEndpoint create; virtual ~MediaEndpoint() { } - virtual void setConfiguration(RefPtr&&) = 0; + // FIMXE: look over naming + virtual void setConfiguration(RefPtr&&) = 0; virtual void prepareToReceive(MediaEndpointConfiguration*, bool isInitiator) = 0; virtual void prepareToSend(MediaEndpointConfiguration*, bool isInitiator) = 0; diff --git a/Source/WebCore/platform/mediastream/MediaEndpointInit.cpp b/Source/WebCore/platform/mediastream/MediaEndpointInit.cpp new file mode 100644 index 0000000000000..37a30d3d05fdd --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaEndpointInit.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "MediaEndpointInit.h" + +#if ENABLE(MEDIA_STREAM) + +namespace WebCore { + +MediaEndpointInit::MediaEndpointInit(Vector>& iceServers, const String& iceTransportPolicy, const String& bundlePolicy) + : m_iceServers(iceServers) +{ + if (iceTransportPolicy == "none") + m_iceTransportPolicy = IceTransportPolicyNone; + else if (iceTransportPolicy == "relay") + m_iceTransportPolicy = IceTransportPolicyRelay; + else if (iceTransportPolicy == "all") + m_iceTransportPolicy = IceTransportPolicyAll; + else + ASSERT_NOT_REACHED(); + + if (bundlePolicy == "balanced") + m_bundlePolicy = BundlePolicyBalanced; + else if (bundlePolicy == "max-compat") + m_bundlePolicy = BundlePolicyMaxCompat; + else if (bundlePolicy == "max-bundle") + m_bundlePolicy = BundlePolicyMaxBundle; + else + ASSERT_NOT_REACHED(); +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointInit.h b/Source/WebCore/platform/mediastream/MediaEndpointInit.h new file mode 100644 index 0000000000000..6c1ddbdeeaf1e --- /dev/null +++ b/Source/WebCore/platform/mediastream/MediaEndpointInit.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef MediaEndpointInit_h +#define MediaEndpointInit_h + +#if ENABLE(MEDIA_STREAM) + +#include +#include +#include +#include + +namespace WebCore { + +class IceServerInfo : public RefCounted { +public: + static RefPtr create(const Vector& urls, const String& credential, const String& username) + { + return adoptRef(new IceServerInfo(urls, credential, username)); + } + virtual ~IceServerInfo() { } + + const Vector& urls() const { return m_urls; } + const String& credential() const { return m_credential; } + const String& username() const { return m_username; } + +private: + IceServerInfo(const Vector& urls, const String& credential, const String& username) + : m_urls(urls) + , m_credential(credential) + , m_username(username) + { } + + Vector m_urls; + String m_credential; + String m_username; +}; + +class MediaEndpointInit : public RefCounted { +public: + static RefPtr create(Vector>& iceServers, const String& iceTransportPolicy, const String& bundlePolicy) + { + return adoptRef(new MediaEndpointInit(iceServers, iceTransportPolicy, bundlePolicy)); + } + + enum IceTransportPolicy { + IceTransportPolicyNone, + IceTransportPolicyRelay, + IceTransportPolicyAll + }; + + enum BundlePolicy { + BundlePolicyBalanced, + BundlePolicyMaxCompat, + BundlePolicyMaxBundle + }; + + const Vector>& iceServers() const { return m_iceServers; } + IceTransportPolicy iceTransportPolicy() const { return m_iceTransportPolicy; } + BundlePolicy bundlePolicy() const { return m_bundlePolicy; } + +private: + MediaEndpointInit(Vector>&, const String& iceTransportPolicy, const String& bundlePolicy); + + Vector> m_iceServers; + IceTransportPolicy m_iceTransportPolicy; + BundlePolicy m_bundlePolicy; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // MediaEndpointInit_h diff --git a/Source/WebCore/platform/mediastream/RTCConfigurationPrivate.h b/Source/WebCore/platform/mediastream/RTCConfigurationPrivate.h deleted file mode 100644 index 8a1354c843a6e..0000000000000 --- a/Source/WebCore/platform/mediastream/RTCConfigurationPrivate.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2014 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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. - */ - -#ifndef RTCConfigurationPrivate_h -#define RTCConfigurationPrivate_h - -#if ENABLE(MEDIA_STREAM) - -#include "RTCIceServerPrivate.h" -#include -#include -#include -#include - -namespace WebCore { - -class RTCConfigurationPrivate : public RefCounted { -public: - static PassRefPtr create() { return adoptRef(new RTCConfigurationPrivate()); } - virtual ~RTCConfigurationPrivate() { } - - void appendServer(PassRefPtr server) { m_privateServers.append(server); } - size_t numberOfServers() { return m_privateServers.size(); } - RTCIceServerPrivate* server(size_t index) { return m_privateServers[index].get(); } - - const String& iceTransports() const { return m_iceTransports; } - void setIceTransports(const String& iceTransports) - { - if (iceTransports == "none" || iceTransports == "relay" || iceTransports == "all") - m_iceTransports = iceTransports; - } - - const String& requestIdentity() const { return m_requestIdentity; } - void setRequestIdentity(const String& requestIdentity) - { - if (requestIdentity == "yes" || requestIdentity == "no" || requestIdentity == "ifconfigured") - m_requestIdentity = requestIdentity; - } - - Vector> iceServers() const { return m_privateServers; } - -private: - RTCConfigurationPrivate() - : m_iceTransports("all") - , m_requestIdentity("ifconfigured") - { - } - - Vector> m_privateServers; - String m_iceTransports; - String m_requestIdentity; -}; - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) - -#endif // RTCConfigurationPrivate_h diff --git a/Source/WebCore/platform/mediastream/RTCIceServerPrivate.h b/Source/WebCore/platform/mediastream/RTCIceServerPrivate.h deleted file mode 100644 index 9bd8019b09cb8..0000000000000 --- a/Source/WebCore/platform/mediastream/RTCIceServerPrivate.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2014 Apple Inc. All rights reserved. - * - * 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. ``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 - * 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. - */ - -#ifndef RTCIceServerPrivate_h -#define RTCIceServerPrivate_h - -#if ENABLE(MEDIA_STREAM) - -#include -#include -#include -#include - -namespace WebCore { - -class RTCIceServerPrivate : public RefCounted { -public: - static PassRefPtr create(const Vector& urls, const String& credential, const String& username) - { - return adoptRef(new RTCIceServerPrivate(urls, credential, username)); - } - virtual ~RTCIceServerPrivate() { } - - const Vector& urls() { return m_urls; } - const String& credential() { return m_credential; } - const String& username() { return m_username; } - -private: - RTCIceServerPrivate(const Vector& urls, const String& credential, const String& username) - : m_urls(urls) - , m_credential(credential) - , m_username(username) - { - } - - Vector m_urls; - String m_credential; - String m_username; -}; - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) - -#endif // RTCIceServerPrivate_h diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index a4e57a09a0771..b536ad5fbecc7 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -67,7 +67,7 @@ MediaEndpointOwr::~MediaEndpointOwr() g_object_unref(m_transportAgent); } -void MediaEndpointOwr::setConfiguration(RefPtr&& configuration) +void MediaEndpointOwr::setConfiguration(RefPtr&& configuration) { m_configuration = configuration; } @@ -144,9 +144,7 @@ void MediaEndpointOwr::ensureTransportAgentAndMediaSessions(bool isInitiator, co if (!m_transportAgent) { m_transportAgent = owr_transport_agent_new(false); - for (unsigned i = 0; i < m_configuration->numberOfServers(); ++i) { - RTCIceServerPrivate* server = m_configuration->server(i); - + for (auto& server : m_configuration->iceServers()) { // FIXME: parse url type and port owr_transport_agent_add_helper_server(m_transportAgent, OWR_HELPER_SERVER_TYPE_STUN, server->urls()[0].ascii().data(), 3478, nullptr, nullptr); diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index 0ace34849cbf0..e03c1527c446b 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -47,7 +47,7 @@ class MediaEndpointOwr : public MediaEndpoint { MediaEndpointOwr(MediaEndpointClient*); ~MediaEndpointOwr(); - virtual void setConfiguration(RefPtr&&) override; + virtual void setConfiguration(RefPtr&&) override; virtual void prepareToReceive(MediaEndpointConfiguration*, bool isInitiator) override; virtual void prepareToSend(MediaEndpointConfiguration*, bool isInitiator) override; @@ -65,7 +65,7 @@ class MediaEndpointOwr : public MediaEndpoint { void prepareMediaSession(unsigned mdescIndex, OwrMediaSession*, PeerMediaDescription*); void ensureTransportAgentAndMediaSessions(bool isInitiator, const Vector& newMediaSessionDtlsRoles); - RefPtr m_configuration; + RefPtr m_configuration; OwrTransportAgent* m_transportAgent; Vector m_mediaSessions; From e3ebcef2c92922177bf3127ada6ed66702c89308 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 16 Apr 2015 10:57:30 +0200 Subject: [PATCH 045/155] RTCOfferAnswerOptions: Don't fail on missing (non-required) members --- .../mediastream/RTCOfferAnswerOptions.cpp | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp index a188ccea19bb4..5432ef085fe86 100644 --- a/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp +++ b/Source/WebCore/Modules/mediastream/RTCOfferAnswerOptions.cpp @@ -72,26 +72,25 @@ bool RTCOfferOptions::initialize(const Dictionary& options) if (options.isUndefinedOrNull()) return true; - String offerToReceiveVideoStr; + String stringValue; + int64_t intConversionResult; bool numberConversionSuccess; - if (!options.get("offerToReceiveVideo", offerToReceiveVideoStr)) - return false; - int64_t intConversionResult = offerToReceiveVideoStr.toInt64Strict(&numberConversionSuccess); - if (!numberConversionSuccess) - return false; + if (options.get("offerToReceiveVideo", stringValue)) { + intConversionResult = stringValue.toInt64Strict(&numberConversionSuccess); + if (!numberConversionSuccess) + return false; - m_offerToReceiveVideo = intConversionResult; - - String offerToReceiveAudioStr; - if (!options.get("offerToReceiveAudio", offerToReceiveAudioStr)) - return false; + m_offerToReceiveVideo = intConversionResult; + } - intConversionResult = offerToReceiveAudioStr.toInt64Strict(&numberConversionSuccess); - if (!numberConversionSuccess) - return false; + if (options.get("offerToReceiveAudio", stringValue)) { + intConversionResult = stringValue.toInt64Strict(&numberConversionSuccess); + if (!numberConversionSuccess) + return false; - m_offerToReceiveAudio = intConversionResult; + m_offerToReceiveAudio = intConversionResult; + } bool iceRestart; if (options.get("iceRestart", iceRestart)) From cb17da822ccdf01c35e980683edaabff6af2ebf8 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 16 Apr 2015 11:20:18 +0200 Subject: [PATCH 046/155] MediaEndpointConfiguration: Add mode --- .../mediastream/MediaEndpointConfigurationConversions.cpp | 4 ++++ Source/WebCore/platform/mediastream/PeerMediaDescription.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index 5218cd3303095..9d2494bcad7ae 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -117,6 +117,9 @@ RefPtr fromJSON(const String& json) if (mdescObject->getInteger(ASCIILiteral("port"), intValue)) mdesc->setPort(intValue); + if (mdescObject->getString(ASCIILiteral("mode"), stringValue)) + mdesc->setMode(stringValue); + RefPtr payloadsArray = InspectorArray::create(); mdescObject->getArray(ASCIILiteral("payloads"), payloadsArray); @@ -206,6 +209,7 @@ String toJSON(MediaEndpointConfiguration* configuration) mdescObject->setString(ASCIILiteral("type"), mdesc->type()); mdescObject->setInteger(ASCIILiteral("port"), mdesc->port()); + mdescObject->setString(ASCIILiteral("mode"), mdesc->mode()); RefPtr payloadsArray = InspectorArray::create(); diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index b88bdb14b43c8..0866b153d66eb 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -54,6 +54,9 @@ class PeerMediaDescription : public RefCounted { unsigned short port() const { return m_port; } void setPort(unsigned short port) { m_port = port; } + const String& mode() const { return m_mode; } + void setMode(const String& mode) { m_mode = mode; } + const Vector>& payloads() const { return m_payloads; } void addPayload(RefPtr&& payload) { m_payloads.append(WTF::move(payload)); } @@ -83,6 +86,7 @@ class PeerMediaDescription : public RefCounted { String m_type; unsigned short m_port; + String m_mode; Vector> m_payloads; From d3f1bac361d288ce08a99e0800c806ddfdedb0ab Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 16 Apr 2015 11:44:53 +0200 Subject: [PATCH 047/155] RTCPeerConnection: Use RTCOfferOptions to add extra media descriptions --- .../Modules/mediastream/RTCPeerConnection.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 1c40ddf280d11..50c1e5dcd0a50 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -199,6 +199,21 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR mediaDescription->setMediaStreamId("fix me"); mediaDescription->setMediaStreamTrackId(track->id()); mediaDescription->setType(track->kind()); + mediaDescription->setMode("sendrcv"); + // FIXME: payloads + mediaDescription->setRtcpMux(true); + mediaDescription->setDtlsSetup("actpass"); + + configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); + } + + int extraMediaDescriptionCount = options->offerToReceiveAudio() + options->offerToReceiveVideo(); + for (int i = 0; i < extraMediaDescriptionCount; ++i) { + bool audioType = i < options->offerToReceiveAudio(); + RefPtr mediaDescription = PeerMediaDescription::create(); + + mediaDescription->setType(audioType ? "audio" : "video"); + mediaDescription->setMode("recvonly"); // FIXME: payloads mediaDescription->setRtcpMux(true); mediaDescription->setDtlsSetup("actpass"); From b60c4eb854efa93202b0b4881721199f681a6e74 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 16 Apr 2015 14:40:10 +0200 Subject: [PATCH 048/155] RTCConfiguration: Make iceTransportPolicy and bundlePolicy behave like enum dictionary members --- .../Modules/mediastream/RTCConfiguration.cpp | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp index b3cc46fc54f6a..c16bb3fcc4a70 100644 --- a/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp +++ b/Source/WebCore/Modules/mediastream/RTCConfiguration.cpp @@ -142,14 +142,22 @@ void RTCConfiguration::initialize(const Dictionary& configuration, ExceptionCode } String iceTransportPolicy; - configuration.get("iceTransportPolicy", iceTransportPolicy); - if (iceTransportPolicy == "none" || iceTransportPolicy == "relay" || iceTransportPolicy == "all") - m_iceTransportPolicy = iceTransportPolicy; + if (configuration.get("iceTransportPolicy", iceTransportPolicy)) { + if (iceTransportPolicy == "none" || iceTransportPolicy == "relay" || iceTransportPolicy == "all") + m_iceTransportPolicy = iceTransportPolicy; + else { + ec = TypeError; + return; + } + } String bundlePolicy; - configuration.get("bundlePolicy", bundlePolicy); - if (bundlePolicy == "balanced" || bundlePolicy == "max-compat" || bundlePolicy == "max-bundle") - m_bundlePolicy = bundlePolicy; + if (configuration.get("bundlePolicy", bundlePolicy)) { + if (bundlePolicy == "balanced" || bundlePolicy == "max-compat" || bundlePolicy == "max-bundle") + m_bundlePolicy = bundlePolicy; + else + ec = TypeError; + } } } // namespace WebCore From bcadcf8a50a3ae485084d841bb3af315b0593d15 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 17 Apr 2015 16:02:23 +0200 Subject: [PATCH 049/155] RTCPeerConnection: Improve description type check on setLocal/RemoteDescription() --- .../Modules/mediastream/RTCPeerConnection.cpp | 39 +++++++++++++------ .../Modules/mediastream/RTCPeerConnection.h | 4 +- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 50c1e5dcd0a50..568278a69c83f 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -244,7 +244,7 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe // TODO } -void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback, ExceptionCode& ec) +void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; @@ -252,14 +252,14 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, } DescriptionType descriptionType = parseDescriptionType(description->type()); - if (descriptionType == DescriptionTypeInvalid) { - // FIXME: rejectCallback - return; - } SignalingState targetState = targetSignalingState(SetterTypeLocal, descriptionType); if (targetState == SignalingStateInvalid) { - // FIXME: rejectCallback + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError"); + rejectCallback(error.get()); + }); return; } @@ -292,14 +292,30 @@ RefPtr RTCPeerConnection::localDescription() const return RTCSessionDescription::create(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get()), m_localConfigurationType); } -void RTCPeerConnection::setRemoteDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback, ExceptionCode& ec) +void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; return; } - // TODO + DescriptionType descriptionType = parseDescriptionType(description->type()); + + SignalingState targetState = targetSignalingState(SetterTypeRemote, descriptionType); + if (targetState == SignalingStateInvalid) { + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError"); + rejectCallback(error.get()); + }); + return; + } + + RefPtr protectedThis(this); + m_completeSetLocalDescription = [targetState, resolveCallback, protectedThis]() mutable { + protectedThis->m_signalingState = targetState; + resolveCallback(); + }; } RefPtr RTCPeerConnection::remoteDescription() const @@ -513,10 +529,11 @@ RTCPeerConnection::DescriptionType RTCPeerConnection::parseDescriptionType(const { if (typeName == "offer") return DescriptionTypeOffer; - if (typeName == "answer") - return DescriptionTypeAnswer; + if (typeName == "pranswer") + return DescriptionTypePranswer; - return DescriptionTypeInvalid; + ASSERT(typeName == "answer"); + return DescriptionTypeAnswer; } const char* RTCPeerConnection::activeDOMObjectName() const diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 78e2a9faaa637..924a78ede3c2c 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -119,8 +119,8 @@ class RTCPeerConnection final : public RefCounted, public Scr enum DescriptionType { DescriptionTypeOffer = 1, - DescriptionTypeAnswer = 2, - DescriptionTypeInvalid = 3 + DescriptionTypePranswer = 2, + DescriptionTypeAnswer = 3 }; enum SignalingState { From 1754312e14c66f27263a37fa7b34957ef1a2f506 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 17 Apr 2015 17:30:01 +0200 Subject: [PATCH 050/155] RTCPeerConnection: Fix typo (s/sendrcv/sendrecv/) --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 568278a69c83f..03d156e400a33 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -199,7 +199,7 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR mediaDescription->setMediaStreamId("fix me"); mediaDescription->setMediaStreamTrackId(track->id()); mediaDescription->setType(track->kind()); - mediaDescription->setMode("sendrcv"); + mediaDescription->setMode("sendrecv"); // FIXME: payloads mediaDescription->setRtcpMux(true); mediaDescription->setDtlsSetup("actpass"); From 5a88018c4e5673dee17de2d8dfa1f768dd4e2771 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 17 Apr 2015 19:57:43 +0200 Subject: [PATCH 051/155] RTCPeerConnection: Add temporary solution for resolving setLocal/RemoteDescription() --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 03d156e400a33..96e8ab12ecf41 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -282,6 +282,9 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, if (m_remoteConfiguration) m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); + + // FIXME: Temporary solution + callOnMainThread(m_completeSetLocalDescription); } RefPtr RTCPeerConnection::localDescription() const @@ -312,10 +315,10 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, } RefPtr protectedThis(this); - m_completeSetLocalDescription = [targetState, resolveCallback, protectedThis]() mutable { + callOnMainThread([targetState, resolveCallback, protectedThis]() mutable { protectedThis->m_signalingState = targetState; resolveCallback(); - }; + }); } RefPtr RTCPeerConnection::remoteDescription() const From aa5b9f53b48937c92f129366de92508cb436e7b1 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 17 Apr 2015 19:58:55 +0200 Subject: [PATCH 052/155] RTCPeerConnection: Update existing media descriptions with new tracks in createOffer() --- .../Modules/mediastream/RTCPeerConnection.cpp | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 96e8ab12ecf41..84e92485cb765 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -168,6 +168,45 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec) // FIXME: Mark connection as needing negotiation. } +static void updateMediaDescriptionsWithTracks(const Vector>& mediaDescriptions, Vector& tracks) +{ + // Remove any track elements from tracks that are already represented by a media description + // and mark media descriptions that don't have a track (anymore) as "available". + for (auto& mdesc : mediaDescriptions) { + const String& mdescTrackId = mdesc->mediaStreamTrackId(); + bool foundTrack = tracks.removeFirstMatching([mdescTrackId](const MediaStreamTrack* track) -> bool { + return track->id() == mdescTrackId; + }); + if (!foundTrack) { + mdesc->setMediaStreamId(emptyString()); + mdesc->setMediaStreamTrackId(emptyString()); + } + } + + // Remove any track elements from tracks that can be matched (by type) to an available media + // description. Media descriptions that don't get a local (sending) track is marked receive only. + for (auto& mdesc : mediaDescriptions) { + if (mdesc->mediaStreamTrackId() != emptyString()) + continue; + + MediaStreamTrack* track = nullptr; + for (auto t : tracks) { + if (t->kind() == mdesc->type()) { + track = t; + break; + } + } + + if (track) { + mdesc->setMediaStreamId("fix me"); + mdesc->setMediaStreamTrackId(track->id()); + mdesc->setMode("sendrecv"); + tracks.removeFirst(track); + } else + mdesc->setMode("recvonly"); + } +} + void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { @@ -191,8 +230,9 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR for (auto sender : m_senderSet.values()) localTracks.append(sender->track()); - // FIXME: update existing media descriptions with tracks + updateMediaDescriptionsWithTracks(configurationSnapshot->mediaDescriptions(), localTracks); + // Add media descriptions for remaining tracks. for (auto track : localTracks) { RefPtr mediaDescription = PeerMediaDescription::create(); From 7e6751556009d0e1f2535b7d1b4b87c50a3a0772 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 18 Apr 2015 13:13:52 +0200 Subject: [PATCH 053/155] RTCPeerConnection: Add stream argument to addTrack() and save the id on the RTCRtpSender --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 5 +++-- Source/WebCore/Modules/mediastream/RTCPeerConnection.h | 3 ++- Source/WebCore/Modules/mediastream/RTCPeerConnection.idl | 2 +- Source/WebCore/Modules/mediastream/RTCRtpSender.cpp | 7 ++++--- Source/WebCore/Modules/mediastream/RTCRtpSender.h | 9 +++++++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 84e92485cb765..44fbee73213b0 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -44,6 +44,7 @@ #include "MediaEndpointConfiguration.h" #include "MediaEndpointConfigurationConversions.h" #include "MediaEndpointInit.h" +#include "MediaStream.h" #include "MediaStreamTrack.h" #include "PeerMediaDescription.h" #include "RTCConfiguration.h" @@ -136,7 +137,7 @@ Vector> RTCPeerConnection::getReceivers() const return receivers; } -RefPtr RTCPeerConnection::addTrack(RefPtr&& track, ExceptionCode& ec) +RefPtr RTCPeerConnection::addTrack(RefPtr&& track, const MediaStream* stream, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; @@ -149,7 +150,7 @@ RefPtr RTCPeerConnection::addTrack(RefPtr&& trac return nullptr; } - RefPtr sender = RTCRtpSender::create(WTF::move(track)); + RefPtr sender = RTCRtpSender::create(WTF::move(track), stream->id()); m_senderSet.add(track->id(), sender); return sender; diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 924a78ede3c2c..caae221f44394 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -47,6 +47,7 @@ namespace WebCore { class MediaEndpointConfiguration; +class MediaStream; class MediaStreamTrack; class RTCConfiguration; class RTCDataChannel; @@ -69,7 +70,7 @@ class RTCPeerConnection final : public RefCounted, public Scr Vector> getSenders() const; Vector> getReceivers() const; - RefPtr addTrack(RefPtr&&, ExceptionCode&); + RefPtr addTrack(RefPtr&&, const MediaStream* stream, ExceptionCode&); void removeTrack(RTCRtpSender*, ExceptionCode&); void createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback, RejectCallback, ExceptionCode&); diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl index 08bd01ded05ab..562b5942927c4 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl @@ -45,7 +45,7 @@ sequence getSenders(); - [StrictTypeChecking, RaisesException] RTCRtpSender addTrack(MediaStreamTrack track); + [StrictTypeChecking, RaisesException] RTCRtpSender addTrack(MediaStreamTrack track, MediaStream stream); [StrictTypeChecking, RaisesException] void removeTrack(RTCRtpSender sender); [Custom, RaisesException] Promise setLocalDescription(RTCSessionDescription description); diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp index 063e1e825b7bc..3d957d374be26 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp @@ -35,13 +35,14 @@ namespace WebCore { -RefPtr RTCRtpSender::create(RefPtr&& track) +RefPtr RTCRtpSender::create(RefPtr&& track, const String& mediaStreamId) { - return adoptRef(new RTCRtpSender(WTF::move(track))); + return adoptRef(new RTCRtpSender(WTF::move(track), mediaStreamId)); } -RTCRtpSender::RTCRtpSender(RefPtr&& track) +RTCRtpSender::RTCRtpSender(RefPtr&& track, const String& mediaStreamId) : RTCRtpSenderReceiverBase(WTF::move(track)) + , m_mediaStreamId(mediaStreamId) { } diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.h b/Source/WebCore/Modules/mediastream/RTCRtpSender.h index 32c0e4d0782ef..fc19cdd8e4a3c 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpSender.h +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.h @@ -34,16 +34,21 @@ #if ENABLE(MEDIA_STREAM) #include "RTCRtpSenderReceiverBase.h" +#include namespace WebCore { class RTCRtpSender : public RTCRtpSenderReceiverBase { public: - static RefPtr create(RefPtr&&); + static RefPtr create(RefPtr&&, const String& mediaStreamId); virtual ~RTCRtpSender(); + const String& mediaStreamId() const { return m_mediaStreamId; } + private: - RTCRtpSender(RefPtr&&); + RTCRtpSender(RefPtr&&, const String& mediaStreamId); + + String m_mediaStreamId; }; } // namespace WebCore From 9bc5e38d18a7e85dccb5dfcf116aba89ef56c54d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 18 Apr 2015 13:16:47 +0200 Subject: [PATCH 054/155] RTCPeerConnection: Use mediaStreamId from RTCRtpSeder when creating media descriptions --- .../Modules/mediastream/RTCPeerConnection.cpp | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 44fbee73213b0..afb1284e49cef 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -169,40 +169,40 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec) // FIXME: Mark connection as needing negotiation. } -static void updateMediaDescriptionsWithTracks(const Vector>& mediaDescriptions, Vector& tracks) +static void updateMediaDescriptionsWithSenders(const Vector>& mediaDescriptions, Vector& senders) { - // Remove any track elements from tracks that are already represented by a media description - // and mark media descriptions that don't have a track (anymore) as "available". + // Remove any sender(s) from the senders list that already have their tracks represented by a media + // description. Mark media descriptions that don't have a sender/track (anymore) as "available". for (auto& mdesc : mediaDescriptions) { const String& mdescTrackId = mdesc->mediaStreamTrackId(); - bool foundTrack = tracks.removeFirstMatching([mdescTrackId](const MediaStreamTrack* track) -> bool { - return track->id() == mdescTrackId; + bool foundSender = senders.removeFirstMatching([mdescTrackId](const RTCRtpSender* sender) -> bool { + return sender->track()->id() == mdescTrackId; }); - if (!foundTrack) { + if (!foundSender) { mdesc->setMediaStreamId(emptyString()); mdesc->setMediaStreamTrackId(emptyString()); } } - // Remove any track elements from tracks that can be matched (by type) to an available media - // description. Media descriptions that don't get a local (sending) track is marked receive only. + // Remove any sender(s) from the senders list that can be matched (by track type) to an "available" + // media description. Mark media descriptions that don't get matched with a sender as receive only. for (auto& mdesc : mediaDescriptions) { if (mdesc->mediaStreamTrackId() != emptyString()) continue; - MediaStreamTrack* track = nullptr; - for (auto t : tracks) { - if (t->kind() == mdesc->type()) { - track = t; + RTCRtpSender* sender = nullptr; + for (auto s : senders) { + if (s->track()->kind() == mdesc->type()) { + sender = s; break; } } - if (track) { - mdesc->setMediaStreamId("fix me"); - mdesc->setMediaStreamTrackId(track->id()); + if (sender) { + mdesc->setMediaStreamId(sender->mediaStreamId()); + mdesc->setMediaStreamTrackId(sender->track()->id()); mdesc->setMode("sendrecv"); - tracks.removeFirst(track); + senders.removeFirst(sender); } else mdesc->setMode("recvonly"); } @@ -227,17 +227,18 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR RefPtr configurationSnapshot = m_localConfiguration ? MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); - Vector localTracks; - for (auto sender : m_senderSet.values()) - localTracks.append(sender->track()); + Vector senders; + for (auto& sender : m_senderSet.values()) + senders.append(sender.get()); - updateMediaDescriptionsWithTracks(configurationSnapshot->mediaDescriptions(), localTracks); + updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); - // Add media descriptions for remaining tracks. - for (auto track : localTracks) { + // Add media descriptions for remaining senders. + for (auto sender : senders) { RefPtr mediaDescription = PeerMediaDescription::create(); + MediaStreamTrack* track = sender->track(); - mediaDescription->setMediaStreamId("fix me"); + mediaDescription->setMediaStreamId(sender->mediaStreamId()); mediaDescription->setMediaStreamTrackId(track->id()); mediaDescription->setType(track->kind()); mediaDescription->setMode("sendrecv"); From d719d0ce35116b836003b0c794cde1d4e6923020 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 19 Apr 2015 14:19:50 +0200 Subject: [PATCH 055/155] MediaEndpointOwr: Use the more general OwrSession instead of OwrMediaSession when possible (prepare for future OwrDataSession) --- .../openwebrtc/MediaEndpointOwr.cpp | 67 +++++++++++-------- .../mediastream/openwebrtc/MediaEndpointOwr.h | 25 ++++--- 2 files changed, 55 insertions(+), 37 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index b536ad5fbecc7..02aca9ccf7078 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -40,8 +40,8 @@ namespace WebCore { -static void gotCandidate(OwrMediaSession*, OwrCandidate*, MediaEndpointOwr*); -static void candidateGatheringDone(OwrMediaSession*, MediaEndpointOwr*); +static void gotCandidate(OwrSession*, OwrCandidate*, MediaEndpointOwr*); +static void candidateGatheringDone(OwrSession*, MediaEndpointOwr*); static char* iceCandidateTypes[] = { "host", "srflx", "relay", nullptr }; @@ -55,8 +55,8 @@ CreateMediaEndpoint MediaEndpoint::create = createMediaEndpointOwr; MediaEndpointOwr::MediaEndpointOwr(MediaEndpointClient* client) : m_transportAgent(nullptr) , m_client(client) - , m_numberOfReceivePreparedMediaSessions(0) - , m_numberOfSendPreparedMediaSessions(0) + , m_numberOfReceivePreparedSessions(0) + , m_numberOfSendPreparedSessions(0) { initializeOpenWebRTC(); } @@ -74,17 +74,23 @@ void MediaEndpointOwr::setConfiguration(RefPtr&& configuratio void MediaEndpointOwr::prepareToReceive(MediaEndpointConfiguration* configuration, bool isInitiator) { - Vector dtlsRoles; - for (unsigned i = m_mediaSessions.size(); i < configuration->mediaDescriptions().size(); ++i) - dtlsRoles.append(configuration->mediaDescriptions()[i]->dtlsSetup()); + Vector sessionConfigs; + for (unsigned i = m_sessions.size(); i < configuration->mediaDescriptions().size(); ++i) { + SessionConfig config; + config.type = SessionTypeMedia; + config.isDtlsClient = configuration->mediaDescriptions()[i]->dtlsSetup() == "active"; + sessionConfigs.append(WTF::move(config)); + } - ensureTransportAgentAndMediaSessions(isInitiator, dtlsRoles); + ensureTransportAgentAndSessions(isInitiator, sessionConfigs); - // prepare the new media sessions - for (unsigned i = m_numberOfReceivePreparedMediaSessions; i < m_mediaSessions.size(); ++i) - prepareMediaSession(i, m_mediaSessions[i], configuration->mediaDescriptions()[i].get()); + // Prepare the new sessions. + for (unsigned i = m_numberOfReceivePreparedSessions; i < m_sessions.size(); ++i) { + prepareMediaSession(OWR_MEDIA_SESSION(m_sessions[i]), configuration->mediaDescriptions()[i].get()); + owr_transport_agent_add_session(m_transportAgent, m_sessions[i]); + } - m_numberOfReceivePreparedMediaSessions = m_mediaSessions.size(); + m_numberOfReceivePreparedSessions = m_sessions.size(); } void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration* configuration, bool isInitiator) @@ -114,32 +120,35 @@ void MediaEndpointOwr::stop() printf("MediaEndpointOwr::stop\n"); } -unsigned MediaEndpointOwr::mediaSessionIndex(OwrMediaSession* mediaSession) const +unsigned MediaEndpointOwr::sessionIndex(OwrSession* session) const { - unsigned index = m_mediaSessions.find(mediaSession); + unsigned index = m_sessions.find(session); ASSERT(index != notFound); return index; } -void MediaEndpointOwr::dispatchNewIceCandidate(unsigned mediaSessionIndex, RefPtr&& iceCandidate) +void MediaEndpointOwr::dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&& iceCandidate) { - m_client->gotIceCandidate(mediaSessionIndex, WTF::move(iceCandidate)); + m_client->gotIceCandidate(sessionIndex, WTF::move(iceCandidate)); } -void MediaEndpointOwr::dispatchGatheringDone(unsigned mediaSessionIndex) +void MediaEndpointOwr::dispatchGatheringDone(unsigned sessionIndex) { - m_client->doneGatheringCandidates(mediaSessionIndex); + m_client->doneGatheringCandidates(sessionIndex); } -void MediaEndpointOwr::prepareMediaSession(unsigned mdescIndex, OwrMediaSession* mediaSession, PeerMediaDescription*) +void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription*) { - g_signal_connect(mediaSession, "on-new-candidate", G_CALLBACK(gotCandidate), this); - g_signal_connect(mediaSession, "on-candidate-gathering-done", G_CALLBACK(candidateGatheringDone), this); + g_signal_connect(session, "on-new-candidate", G_CALLBACK(gotCandidate), this); + g_signal_connect(session, "on-candidate-gathering-done", G_CALLBACK(candidateGatheringDone), this); +} - owr_transport_agent_add_session(m_transportAgent, OWR_SESSION(mediaSession)); +void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMediaDescription* mediaDescription) +{ + prepareSession(OWR_SESSION(mediaSession), mediaDescription); } -void MediaEndpointOwr::ensureTransportAgentAndMediaSessions(bool isInitiator, const Vector& newMediaSessionDtlsRoles) +void MediaEndpointOwr::ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs) { if (!m_transportAgent) { m_transportAgent = owr_transport_agent_new(false); @@ -153,11 +162,11 @@ void MediaEndpointOwr::ensureTransportAgentAndMediaSessions(bool isInitiator, co g_object_set(m_transportAgent, "ice-controlling-mode", isInitiator, nullptr); - for (auto role : newMediaSessionDtlsRoles) - m_mediaSessions.append(owr_media_session_new(role == "active")); + for (auto& config : sessionConfigs) + m_sessions.append(OWR_SESSION(owr_media_session_new(config.isDtlsClient))); } -static void gotCandidate(OwrMediaSession* mediaSession, OwrCandidate* candidate, MediaEndpointOwr* mediaEndpoint) +static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndpointOwr* mediaEndpoint) { OwrCandidateType candidateType; OwrComponentType componentType; @@ -185,12 +194,12 @@ static void gotCandidate(OwrMediaSession* mediaSession, OwrCandidate* candidate, iceCandidate->setTransport(transportType == OWR_TRANSPORT_TYPE_UDP ? "UDP" : "TCP"); // FIXME: set the rest - mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->mediaSessionIndex(mediaSession), WTF::move(iceCandidate)); + mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->sessionIndex(session), WTF::move(iceCandidate)); } -static void candidateGatheringDone(OwrMediaSession* mediaSession, MediaEndpointOwr* mediaEndpoint) +static void candidateGatheringDone(OwrSession* session, MediaEndpointOwr* mediaEndpoint) { - mediaEndpoint->dispatchGatheringDone(mediaEndpoint->mediaSessionIndex(mediaSession)); + mediaEndpoint->dispatchGatheringDone(mediaEndpoint->sessionIndex(session)); } } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index e03c1527c446b..d539345262883 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -56,24 +56,33 @@ class MediaEndpointOwr : public MediaEndpoint { virtual void stop() override; - unsigned mediaSessionIndex(OwrMediaSession*) const; + unsigned sessionIndex(OwrSession*) const; - void dispatchNewIceCandidate(unsigned mediaSessionIndex, RefPtr&&); - void dispatchGatheringDone(unsigned mediaSessionIndex); + void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&); + void dispatchGatheringDone(unsigned sessionIndex); private: - void prepareMediaSession(unsigned mdescIndex, OwrMediaSession*, PeerMediaDescription*); - void ensureTransportAgentAndMediaSessions(bool isInitiator, const Vector& newMediaSessionDtlsRoles); + enum SessionType { SessionTypeMedia }; + + struct SessionConfig { + SessionType type; + bool isDtlsClient; + }; + + void prepareSession(OwrSession*, PeerMediaDescription*); + void prepareMediaSession(OwrMediaSession*, PeerMediaDescription*); + + void ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs); RefPtr m_configuration; OwrTransportAgent* m_transportAgent; - Vector m_mediaSessions; + Vector m_sessions; MediaEndpointClient* m_client; - unsigned m_numberOfReceivePreparedMediaSessions; - unsigned m_numberOfSendPreparedMediaSessions; + unsigned m_numberOfReceivePreparedSessions; + unsigned m_numberOfSendPreparedSessions; }; } // namespace WebCore From 2b25be5d918225c7c83dcd700d7a060cd5bb05f4 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 19 Apr 2015 17:00:01 +0200 Subject: [PATCH 056/155] OpenWebRTCUtilities: Add init guard --- .../platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp index a99195f123f59..a752f26d7afc3 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp @@ -44,7 +44,12 @@ namespace WebCore { void initializeOpenWebRTC() { + static bool isInitialized = false; + if (isInitialized) + return; + owr_init_with_main_context(g_main_context_default()); + isInitialized = true; } } From 3bcfbfbefe92f5a4e74a2e9212b590e9b36c8eef Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 19 Apr 2015 17:01:19 +0200 Subject: [PATCH 057/155] MediaEndpointOwr: Add dtls cert signal handler stub (prints pem) --- .../openwebrtc/MediaEndpointOwr.cpp | 21 +++++++++++++++++++ .../mediastream/openwebrtc/MediaEndpointOwr.h | 1 + 2 files changed, 22 insertions(+) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 02aca9ccf7078..73536dce221aa 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -42,6 +42,7 @@ namespace WebCore { static void gotCandidate(OwrSession*, OwrCandidate*, MediaEndpointOwr*); static void candidateGatheringDone(OwrSession*, MediaEndpointOwr*); +static void gotDtlsCertificate(OwrSession*, GParamSpec*, MediaEndpointOwr*); static char* iceCandidateTypes[] = { "host", "srflx", "relay", nullptr }; @@ -137,10 +138,16 @@ void MediaEndpointOwr::dispatchGatheringDone(unsigned sessionIndex) m_client->doneGatheringCandidates(sessionIndex); } +void MediaEndpointOwr::dispatchDtlsFingerprint(unsigned sessionIndex, const String& fingerprint, const String& hashFunction) +{ + m_client->gotDtlsFingerprint(sessionIndex, fingerprint, hashFunction); +} + void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription*) { g_signal_connect(session, "on-new-candidate", G_CALLBACK(gotCandidate), this); g_signal_connect(session, "on-candidate-gathering-done", G_CALLBACK(candidateGatheringDone), this); + g_signal_connect(session, "notify::dtls-certificate", G_CALLBACK(gotDtlsCertificate), this); } void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMediaDescription* mediaDescription) @@ -202,6 +209,20 @@ static void candidateGatheringDone(OwrSession* session, MediaEndpointOwr* mediaE mediaEndpoint->dispatchGatheringDone(mediaEndpoint->sessionIndex(session)); } +static void gotDtlsCertificate(OwrSession* session, GParamSpec*, MediaEndpointOwr* mediaEndpoint) +{ + String fingerprint; + String hashFunction; + + gchar* pem; + + g_object_get(session, "dtls-certificate", &pem, nullptr); + + printf("pem: %s\n", pem); + + mediaEndpoint->dispatchDtlsFingerprint(mediaEndpoint->sessionIndex(session), fingerprint, hashFunction); +} + } // namespace WebCore #endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index d539345262883..343959f260cd4 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -60,6 +60,7 @@ class MediaEndpointOwr : public MediaEndpoint { void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&); void dispatchGatheringDone(unsigned sessionIndex); + void dispatchDtlsFingerprint(unsigned sessionIndex, const String& fingerprint, const String& hashFunction); private: enum SessionType { SessionTypeMedia }; From e463327f747b7e5d7ca855b80f885245df943143 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 19 Apr 2015 17:23:53 +0200 Subject: [PATCH 058/155] MediaEndpointOwr: Fix some warnings --- .../platform/mediastream/openwebrtc/MediaEndpointOwr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 73536dce221aa..0a375bdecb0b2 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -44,7 +44,7 @@ static void gotCandidate(OwrSession*, OwrCandidate*, MediaEndpointOwr*); static void candidateGatheringDone(OwrSession*, MediaEndpointOwr*); static void gotDtlsCertificate(OwrSession*, GParamSpec*, MediaEndpointOwr*); -static char* iceCandidateTypes[] = { "host", "srflx", "relay", nullptr }; +static const char* iceCandidateTypes[] = { "host", "srflx", "relay", nullptr }; static std::unique_ptr createMediaEndpointOwr(MediaEndpointClient* client) { @@ -94,7 +94,7 @@ void MediaEndpointOwr::prepareToReceive(MediaEndpointConfiguration* configuratio m_numberOfReceivePreparedSessions = m_sessions.size(); } -void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration* configuration, bool isInitiator) +void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration*, bool) { printf("-> MediaEndpointOwr::prepareToSend\n"); } From 969cb2b90742af4f0319426643abf540f41f778c Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 19 Apr 2015 17:44:35 +0200 Subject: [PATCH 059/155] MediaEndpointOwr: Config rtcp mux in prepareMediaSession --- .../platform/mediastream/openwebrtc/MediaEndpointOwr.cpp | 7 +++++-- .../platform/mediastream/openwebrtc/MediaEndpointOwr.h | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 0a375bdecb0b2..b9a6064ffb4ce 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -87,7 +87,7 @@ void MediaEndpointOwr::prepareToReceive(MediaEndpointConfiguration* configuratio // Prepare the new sessions. for (unsigned i = m_numberOfReceivePreparedSessions; i < m_sessions.size(); ++i) { - prepareMediaSession(OWR_MEDIA_SESSION(m_sessions[i]), configuration->mediaDescriptions()[i].get()); + prepareMediaSession(OWR_MEDIA_SESSION(m_sessions[i]), configuration->mediaDescriptions()[i].get(), isInitiator); owr_transport_agent_add_session(m_transportAgent, m_sessions[i]); } @@ -150,9 +150,12 @@ void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription* g_signal_connect(session, "notify::dtls-certificate", G_CALLBACK(gotDtlsCertificate), this); } -void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMediaDescription* mediaDescription) +void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMediaDescription* mediaDescription, bool isInitiator) { prepareSession(OWR_SESSION(mediaSession), mediaDescription); + + bool useRtpMux = !isInitiator && mediaDescription->rtcpMux(); + g_object_set(mediaSession, "rtcp-mux", useRtpMux, nullptr); } void MediaEndpointOwr::ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index 343959f260cd4..e609f72b8cdf4 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -71,7 +71,7 @@ class MediaEndpointOwr : public MediaEndpoint { }; void prepareSession(OwrSession*, PeerMediaDescription*); - void prepareMediaSession(OwrMediaSession*, PeerMediaDescription*); + void prepareMediaSession(OwrMediaSession*, PeerMediaDescription*, bool isInitiator); void ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs); From d211376e99b89ffe663ae8962a9e561d2ac1e688 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 19 Apr 2015 17:45:41 +0200 Subject: [PATCH 060/155] MediaEndpointOwr: Add OwrMediaSession specific signal handler stubs --- .../mediastream/openwebrtc/MediaEndpointOwr.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index b9a6064ffb4ce..110992c1b83ac 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -43,6 +43,8 @@ namespace WebCore { static void gotCandidate(OwrSession*, OwrCandidate*, MediaEndpointOwr*); static void candidateGatheringDone(OwrSession*, MediaEndpointOwr*); static void gotDtlsCertificate(OwrSession*, GParamSpec*, MediaEndpointOwr*); +static void gotSendSsrc(OwrMediaSession*, GParamSpec*, MediaEndpointOwr*); +static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*); static const char* iceCandidateTypes[] = { "host", "srflx", "relay", nullptr }; @@ -156,6 +158,9 @@ void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMe bool useRtpMux = !isInitiator && mediaDescription->rtcpMux(); g_object_set(mediaSession, "rtcp-mux", useRtpMux, nullptr); + + g_signal_connect(mediaSession, "notify::send-ssrc", G_CALLBACK(gotSendSsrc), this); + g_signal_connect(mediaSession, "on-incoming-source", G_CALLBACK(gotIncomingSource), this); } void MediaEndpointOwr::ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs) @@ -226,6 +231,16 @@ static void gotDtlsCertificate(OwrSession* session, GParamSpec*, MediaEndpointOw mediaEndpoint->dispatchDtlsFingerprint(mediaEndpoint->sessionIndex(session), fingerprint, hashFunction); } +static void gotSendSsrc(OwrMediaSession* mediaSession, GParamSpec*, MediaEndpointOwr*) +{ + printf("-> gotSendSsrc\n"); +} + +static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*) +{ + printf("-> gotIncomingSource\n"); +} + } // namespace WebCore #endif // ENABLE(MEDIA_STREAM) From 80a28487b7e3890e580249f696b61643035ca1b6 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 21 Apr 2015 09:23:22 +0200 Subject: [PATCH 061/155] OpenWebRTCUtilities: Update initialize function --- .../platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp index a752f26d7afc3..e4cfb59df501d 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp @@ -48,7 +48,7 @@ void initializeOpenWebRTC() if (isInitialized) return; - owr_init_with_main_context(g_main_context_default()); + owr_init(g_main_context_default()); isInitialized = true; } From 143afeb52563d4d133656f341dd96b31160b4906 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 21 Apr 2015 10:41:07 +0200 Subject: [PATCH 062/155] jhbuild: Move to gstreamer git (gstreamer, plugins-base -good -bad, libav) --- Tools/gtk/jhbuild.modules | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index 52646b35d387e..c51089086ea85 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -276,10 +276,7 @@ - + - - + + @@ -300,33 +294,23 @@ - - + - - - + + - + + From 40b6fcb52cb34f85cb34c1cd47e8144d9a49a18b Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 21 Apr 2015 10:52:14 +0200 Subject: [PATCH 063/155] jhbuild: Add libsrtp to the build and enable more 'bad' plugins --- Tools/gtk/jhbuild.modules | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index c51089086ea85..bef32a0b89ad5 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -23,6 +23,7 @@ + @@ -60,6 +61,8 @@ href="http://download.savannah.gnu.org/releases/"/> + + + + + + @@ -297,9 +309,10 @@ - + + From aa33dd2ecf72d55f2d3d05c5d715b1b602be030d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 23 Apr 2015 07:57:26 +0200 Subject: [PATCH 064/155] MediaEndpoint: Send entire dtls cert to client (instead of fingerprint and function name) --- .../Modules/mediastream/RTCPeerConnection.cpp | 2 +- .../WebCore/Modules/mediastream/RTCPeerConnection.h | 2 +- Source/WebCore/platform/mediastream/MediaEndpoint.h | 2 +- .../mediastream/openwebrtc/MediaEndpointOwr.cpp | 13 +++++-------- .../mediastream/openwebrtc/MediaEndpointOwr.h | 2 +- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 63fdb3751539d..7c8fa93218d80 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -502,7 +502,7 @@ void RTCPeerConnection::gotSendSSRC(unsigned, const String&, const String&) { } -void RTCPeerConnection::gotDtlsFingerprint(unsigned, const String&, const String&) +void RTCPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& certificate) { } diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 95f04927d8022..c7a82c40215e5 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -100,7 +100,7 @@ class RTCPeerConnection final : public RefCounted, public Scr // MediaEndpointClient virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) override; - virtual void gotDtlsFingerprint(unsigned mdescIndex, const String& fingerprint, const String& hashFunction) override; + virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) override; virtual void doneGatheringCandidates(unsigned mdescIndex) override; virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index 4488e726fe5b5..bf295b6e1fa2a 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -47,7 +47,7 @@ class RealTimeMediaSource; // not implemented class MediaEndpointClient { public: virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) = 0; - virtual void gotDtlsFingerprint(unsigned mdescIndex, const String& fingerprint, const String& hashFunction) = 0; + virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) = 0; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) = 0; virtual void doneGatheringCandidates(unsigned mdescIndex) = 0; virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) = 0; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 110992c1b83ac..e4e43f0f8c09f 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -140,9 +140,9 @@ void MediaEndpointOwr::dispatchGatheringDone(unsigned sessionIndex) m_client->doneGatheringCandidates(sessionIndex); } -void MediaEndpointOwr::dispatchDtlsFingerprint(unsigned sessionIndex, const String& fingerprint, const String& hashFunction) +void MediaEndpointOwr::dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate) { - m_client->gotDtlsFingerprint(sessionIndex, fingerprint, hashFunction); + m_client->gotDtlsCertificate(sessionIndex, certificate); } void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription*) @@ -219,16 +219,13 @@ static void candidateGatheringDone(OwrSession* session, MediaEndpointOwr* mediaE static void gotDtlsCertificate(OwrSession* session, GParamSpec*, MediaEndpointOwr* mediaEndpoint) { - String fingerprint; - String hashFunction; - gchar* pem; - g_object_get(session, "dtls-certificate", &pem, nullptr); - printf("pem: %s\n", pem); + String certificate(pem); + g_free(pem); - mediaEndpoint->dispatchDtlsFingerprint(mediaEndpoint->sessionIndex(session), fingerprint, hashFunction); + mediaEndpoint->dispatchDtlsCertificate(mediaEndpoint->sessionIndex(session), certificate); } static void gotSendSsrc(OwrMediaSession* mediaSession, GParamSpec*, MediaEndpointOwr*) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index e609f72b8cdf4..90d90bad20ad8 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -60,7 +60,7 @@ class MediaEndpointOwr : public MediaEndpoint { void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&); void dispatchGatheringDone(unsigned sessionIndex); - void dispatchDtlsFingerprint(unsigned sessionIndex, const String& fingerprint, const String& hashFunction); + void dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate); private: enum SessionType { SessionTypeMedia }; From 072a77b26744e6f4af07de9c17676eab07dd4fe9 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 23 Apr 2015 08:45:47 +0200 Subject: [PATCH 065/155] MediaEndpointConfiguration: Add dtls fingerprint and fingerprint hash function (with conversion) --- .../mediastream/MediaEndpointConfigurationConversions.cpp | 8 ++++++++ .../WebCore/platform/mediastream/PeerMediaDescription.h | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index 9d2494bcad7ae..1bd396ed1f313 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -154,6 +154,12 @@ RefPtr fromJSON(const String& json) if (mdescObject->getObject(ASCIILiteral("dtls"), dtlsObject)) { if (dtlsObject->getString(ASCIILiteral("setup"), stringValue)) mdesc->setDtlsSetup(stringValue); + + if (dtlsObject->getString(ASCIILiteral("fingerprintHashFunction"), stringValue)) + mdesc->setDtlsFingerprintHashFunction(stringValue); + + if (dtlsObject->getString(ASCIILiteral("fingerprint"), stringValue)) + mdesc->setDtlsFingerprint(stringValue); } RefPtr iceObject = InspectorObject::create(); @@ -232,6 +238,8 @@ String toJSON(MediaEndpointConfiguration* configuration) RefPtr dtlsObject = InspectorObject::create(); dtlsObject->setString(ASCIILiteral("setup"), mdesc->dtlsSetup()); + dtlsObject->setString(ASCIILiteral("fingerprintHashFunction"), mdesc->dtlsFingerprintHashFunction()); + dtlsObject->setString(ASCIILiteral("fingerprint"), mdesc->dtlsFingerprint()); mdescObject->setObject(ASCIILiteral("dtls"), dtlsObject); RefPtr iceObject = InspectorObject::create(); diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index 0866b153d66eb..e4aed188ef35d 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -72,6 +72,12 @@ class PeerMediaDescription : public RefCounted { const String& dtlsSetup() const { return m_dtlsSetup; } void setDtlsSetup(const String& dtlsSetup) { m_dtlsSetup = dtlsSetup; } + const String& dtlsFingerprintHashFunction() const { return m_dtlsFingerprintHashFunction; } + void setDtlsFingerprintHashFunction(const String& dtlsFingerprintHashFunction) { m_dtlsFingerprintHashFunction = dtlsFingerprintHashFunction; } + + const String& dtlsFingerprint() const { return m_dtlsFingerprint; } + void setDtlsFingerprint(const String& dtlsFingerprint) { m_dtlsFingerprint = dtlsFingerprint; } + const String& iceUfrag() const { return m_iceUfrag; } void setIceUfrag(const String& iceUfrag) { m_iceUfrag = iceUfrag; } @@ -96,6 +102,8 @@ class PeerMediaDescription : public RefCounted { String m_mediaStreamTrackId; String m_dtlsSetup; + String m_dtlsFingerprintHashFunction; + String m_dtlsFingerprint; String m_iceUfrag; String m_icePassword; From c85288ad14b29c439b2b85a0e19457d83b4ff161 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 23 Apr 2015 08:47:56 +0200 Subject: [PATCH 066/155] RTCPeerConnection: Fix mixup between type and sdp arguments in local/remoteDescription getters --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 7c8fa93218d80..ce15a944a3fcc 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -334,7 +334,7 @@ RefPtr RTCPeerConnection::localDescription() const if (!m_localConfiguration) return nullptr; - return RTCSessionDescription::create(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get()), m_localConfigurationType); + return RTCSessionDescription::create(m_localConfigurationType, MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())); } void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) @@ -368,7 +368,7 @@ RefPtr RTCPeerConnection::remoteDescription() const if (!m_remoteConfiguration) return nullptr; - return RTCSessionDescription::create(MediaEndpointConfigurationConversions::toJSON(m_remoteConfiguration.get()), m_remoteConfigurationType); + return RTCSessionDescription::create(m_remoteConfigurationType, MediaEndpointConfigurationConversions::toJSON(m_remoteConfiguration.get())); } void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionCode& ec) From 01c3eb32d2b546bee02a08c90c7b6c0efa9c7137 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 23 Apr 2015 08:49:03 +0200 Subject: [PATCH 067/155] RTCPeerConnection: Add fingerprint info to local MediaEndpointConfiguration --- .../Modules/mediastream/RTCPeerConnection.cpp | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index ce15a944a3fcc..ce74ce07b103a 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -36,6 +36,7 @@ #include "RTCPeerConnection.h" +#include "CryptoDigest.h" #include "DOMError.h" #include "Document.h" #include "Event.h" @@ -56,6 +57,7 @@ #include "RTCRtpSender.h" #include "RTCSessionDescription.h" #include +#include namespace WebCore { @@ -324,9 +326,6 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, if (m_remoteConfiguration) m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); - - // FIXME: Temporary solution - callOnMainThread(m_completeSetLocalDescription); } RefPtr RTCPeerConnection::localDescription() const @@ -504,6 +503,42 @@ void RTCPeerConnection::gotSendSSRC(unsigned, const String&, const String&) void RTCPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& certificate) { + Vector certificateRows; + Vector der; + + der.reserveCapacity(certificate.length() * 3/4 + 2); + certificate.split("\n", certificateRows); + + for (auto& row : certificateRows) { + if (row.startsWith("-----")) + continue; + + Vector decodedRow; + if (!base64Decode(row, decodedRow, Base64FailOnInvalidCharacterOrExcessPadding)) { + ASSERT_NOT_REACHED(); + return; + } + der.appendVector(decodedRow); + } + + std::unique_ptr digest = CryptoDigest::create(CryptoAlgorithmIdentifier::SHA_256); + if (!digest) { + ASSERT_NOT_REACHED(); + return; + } + + digest->addBytes(der.data(), der.size()); + Vector fingerprintVector = digest->computeHash(); + + StringBuilder fingerprint; + for (unsigned i = 0; i < fingerprintVector.size(); ++i) + fingerprint.append(String::format(i ? ":%02X" : "%02X", fingerprintVector[i])); + + m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprintHashFunction("sha256"); + m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprint(fingerprint.toString()); + + // FIXME: Temporary solution + m_completeSetLocalDescription(); } void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate) From 21ec1b05af7e117f49e84d11df630479665cfc50 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Thu, 23 Apr 2015 17:30:18 +0200 Subject: [PATCH 068/155] Switch to owr-gst for audio/video rendering --- .../graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp | 8 ++++---- .../graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h | 8 ++++---- Source/cmake/FindOpenWebRTC.cmake | 2 +- Tools/gtk/jhbuild.modules | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp index efd14018c38c8..8178bc1800b0e 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp @@ -32,8 +32,8 @@ #include "URL.h" #include #include -#include -#include +#include +#include #include GST_DEBUG_CATEGORY(webkit_openwebrtc_debug); @@ -276,7 +276,7 @@ void MediaPlayerPrivateGStreamerOwr::createGSTAudioSinkBin() m_audioSink = adoptGRef(GST_ELEMENT(gst_child_proxy_get_child_by_index(childProxy, 0))); gst_element_set_state(sink.get(), GST_STATE_NULL); - m_audioRenderer = owr_audio_renderer_new(G_OBJECT(m_audioSink.get())); + m_audioRenderer = owr_gst_audio_renderer_new(m_audioSink.get()); } void MediaPlayerPrivateGStreamerOwr::sourceReadyStateChanged() @@ -315,7 +315,7 @@ bool MediaPlayerPrivateGStreamerOwr::observerIsEnabled() GstElement* MediaPlayerPrivateGStreamerOwr::createVideoSink() { GstElement* sink = MediaPlayerPrivateGStreamerBase::createVideoSink(); - m_videoRenderer = owr_video_renderer_new(0, G_OBJECT(sink)); + m_videoRenderer = owr_gst_video_renderer_new(sink); return nullptr; } diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h index 8961e2e211454..9aa4072e47326 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h @@ -25,8 +25,8 @@ #include "MediaPlayerPrivateGStreamerBase.h" #include "RealtimeMediaSource.h" -typedef struct _OwrVideoRenderer OwrVideoRenderer; -typedef struct _OwrAudioRenderer OwrAudioRenderer; +typedef struct _OwrGstVideoRenderer OwrGstVideoRenderer; +typedef struct _OwrGstAudioRenderer OwrGstAudioRenderer; namespace WebCore { @@ -107,8 +107,8 @@ class MediaPlayerPrivateGStreamerOwr : public MediaPlayerPrivateGStreamerBase, p RefPtr m_audioSource; GRefPtr m_audioSink; RefPtr m_streamPrivate; - OwrVideoRenderer* m_videoRenderer; - OwrAudioRenderer* m_audioRenderer; + OwrGstVideoRenderer* m_videoRenderer; + OwrGstAudioRenderer* m_audioRenderer; }; } // namespace WebCore diff --git a/Source/cmake/FindOpenWebRTC.cmake b/Source/cmake/FindOpenWebRTC.cmake index 9605326f5e806..2fface0b660a5 100644 --- a/Source/cmake/FindOpenWebRTC.cmake +++ b/Source/cmake/FindOpenWebRTC.cmake @@ -30,7 +30,7 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. find_package(PkgConfig) -pkg_check_modules(OPENWEBRTC openwebrtc-0.1) +pkg_check_modules(OPENWEBRTC openwebrtc-0.1 openwebrtc-gst-0.1) set(VERSION_OK TRUE) if (OPENWEBRTC_VERSION) diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index bef32a0b89ad5..edd528531b523 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -378,12 +378,12 @@ - + - + From f20d85ef3b4b7096077d1c3eaca07e193408d3fc Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 25 Apr 2015 16:58:51 +0200 Subject: [PATCH 069/155] MediaEndpointConfiguration: Add ssrcs list and cname (with JSON conversion) --- .../MediaEndpointConfigurationConversions.cpp | 20 +++++++++++++++++++ .../mediastream/PeerMediaDescription.h | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index 1bd396ed1f313..660b6273da0a1 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -162,6 +162,17 @@ RefPtr fromJSON(const String& json) mdesc->setDtlsFingerprint(stringValue); } + RefPtr ssrcsArray = InspectorArray::create(); + mdescObject->getArray(ASCIILiteral("ssrcs"), ssrcsArray); + + for (unsigned j = 0; j < ssrcsArray->length(); ++j) { + ssrcsArray->get(j)->asString(stringValue); + mdesc->addSsrc(stringValue); + } + + if (mdescObject->getString(ASCIILiteral("cname"), stringValue)) + mdesc->setCname(stringValue); + RefPtr iceObject = InspectorObject::create(); if (mdescObject->getObject(ASCIILiteral("ice"), iceObject)) { if (iceObject->getString(ASCIILiteral("ufrag"), stringValue)) @@ -242,6 +253,15 @@ String toJSON(MediaEndpointConfiguration* configuration) dtlsObject->setString(ASCIILiteral("fingerprint"), mdesc->dtlsFingerprint()); mdescObject->setObject(ASCIILiteral("dtls"), dtlsObject); + RefPtr ssrcsArray = InspectorArray::create(); + + for (const auto& ssrc : mdesc->ssrcs()) { + ssrcsArray->pushString(ssrc); + } + mdescObject->setArray(ASCIILiteral("ssrcs"), ssrcsArray); + + mdescObject->setString(ASCIILiteral("cname"), mdesc->cname()); + RefPtr iceObject = InspectorObject::create(); iceObject->setString(ASCIILiteral("ufrag"), mdesc->iceUfrag()); iceObject->setString(ASCIILiteral("password"), mdesc->icePassword()); diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index e4aed188ef35d..a952459c3b4c7 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -78,6 +78,12 @@ class PeerMediaDescription : public RefCounted { const String& dtlsFingerprint() const { return m_dtlsFingerprint; } void setDtlsFingerprint(const String& dtlsFingerprint) { m_dtlsFingerprint = dtlsFingerprint; } + const String& cname() const { return m_cname; } + void setCname(const String& cname) { m_cname = cname; } + + const Vector& ssrcs() const { return m_ssrcs; } + void addSsrc(const String& ssrc) { m_ssrcs.append(ssrc); } + const String& iceUfrag() const { return m_iceUfrag; } void setIceUfrag(const String& iceUfrag) { m_iceUfrag = iceUfrag; } @@ -105,6 +111,9 @@ class PeerMediaDescription : public RefCounted { String m_dtlsFingerprintHashFunction; String m_dtlsFingerprint; + Vector m_ssrcs; + String m_cname; + String m_iceUfrag; String m_icePassword; Vector> m_iceCandidates; From 3dffc65d4359be5fdad0453bf935d87833c9c4c6 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 25 Apr 2015 17:00:29 +0200 Subject: [PATCH 070/155] RTCPeerConnection: Initial (incomplete) implementation of setLocalDescription() resolving --- .../Modules/mediastream/RTCPeerConnection.cpp | 53 ++++++++++++++++--- .../Modules/mediastream/RTCPeerConnection.h | 12 ++++- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index ce74ce07b103a..95e014c3bb9ca 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -94,6 +94,7 @@ RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr , m_signalingState(SignalingStateStable) , m_iceGatheringState(IceGatheringStateNew) , m_iceConnectionState(IceConnectionStateNew) + , m_resolveSetLocalDescription(nullptr) , m_scheduledEventTimer(*this, &RTCPeerConnection::scheduledEventTimerFired) , m_configuration(configuration) , m_stopped(false) @@ -316,7 +317,7 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, bool isInitiator = descriptionType == DescriptionTypeOffer; RefPtr protectedThis(this); - m_completeSetLocalDescription = [targetState, resolveCallback, protectedThis]() mutable { + m_resolveSetLocalDescription = [targetState, resolveCallback, protectedThis]() mutable { protectedThis->m_signalingState = targetState; resolveCallback(); }; @@ -499,6 +500,9 @@ void RTCPeerConnection::close() void RTCPeerConnection::gotSendSSRC(unsigned, const String&, const String&) { + printf("-> gotSendSSRC()\n"); + + maybeResolveSetLocalDescription(); } void RTCPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& certificate) @@ -537,8 +541,8 @@ void RTCPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& ce m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprintHashFunction("sha256"); m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprint(fingerprint.toString()); - // FIXME: Temporary solution - m_completeSetLocalDescription(); + if (maybeResolveSetLocalDescription() == SetLocalDescriptionResolvedSuccessfully) + maybeDispatchGatheringDone(); } void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate) @@ -548,9 +552,14 @@ void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtrisContextThread()); - String candidateString = MediaEndpointConfigurationConversions::iceCandidateToJSON(candidate.get()); - RefPtr iceCandidate = RTCIceCandidate::create(candidateString, "", mdescIndex); - scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, WTF::move(iceCandidate))); + ResolveSetLocalDescriptionResult result = maybeResolveSetLocalDescription(); + if (result == SetLocalDescriptionResolvedSuccessfully) + maybeDispatchGatheringDone(); + else if (result == SetLocalDescriptionAlreadyResolved) { + String candidateString = MediaEndpointConfigurationConversions::iceCandidateToJSON(candidate.get()); + RefPtr iceCandidate = RTCIceCandidate::create(candidateString, "", mdescIndex); + scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, WTF::move(iceCandidate))); + } } void RTCPeerConnection::doneGatheringCandidates(unsigned) @@ -616,6 +625,38 @@ RTCPeerConnection::DescriptionType RTCPeerConnection::parseDescriptionType(const return DescriptionTypeAnswer; } +bool RTCPeerConnection::isLocalConfigurationComplete() const +{ + for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { + // FIXME: add more tests + if (mdesc->dtlsFingerprint().isEmpty()) + return false; + } + + return true; +} + +RTCPeerConnection::ResolveSetLocalDescriptionResult RTCPeerConnection::maybeResolveSetLocalDescription() +{ + if (!m_resolveSetLocalDescription) { + ASSERT(isLocalConfigurationComplete()); + return SetLocalDescriptionAlreadyResolved; + } + + if (isLocalConfigurationComplete()) { + m_resolveSetLocalDescription(); + m_resolveSetLocalDescription = nullptr; + return SetLocalDescriptionResolvedSuccessfully; + } + + return LocalConfigurationIncomplete; +} + +void RTCPeerConnection::maybeDispatchGatheringDone() const +{ + // FIXME: implement +} + const char* RTCPeerConnection::activeDOMObjectName() const { return "RTCPeerConnection"; diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index c7a82c40215e5..1057886674028 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -155,6 +155,16 @@ class RTCPeerConnection final : public RefCounted, public Scr SignalingState targetSignalingState(SetterType, DescriptionType) const; DescriptionType parseDescriptionType(const String& typeName) const; + enum ResolveSetLocalDescriptionResult { + LocalConfigurationIncomplete, + SetLocalDescriptionResolvedSuccessfully, + SetLocalDescriptionAlreadyResolved + }; + + bool isLocalConfigurationComplete() const; + ResolveSetLocalDescriptionResult maybeResolveSetLocalDescription(); + void maybeDispatchGatheringDone() const; + void scheduleDispatchEvent(PassRefPtr); void scheduledEventTimerFired(); @@ -184,7 +194,7 @@ class RTCPeerConnection final : public RefCounted, public Scr String m_localConfigurationType; String m_remoteConfigurationType; - std::function m_completeSetLocalDescription; + std::function m_resolveSetLocalDescription; Vector> m_dataChannels; From 159d22e56f54649c97fa9abab152adf9c8949b93 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 25 Apr 2015 17:19:47 +0200 Subject: [PATCH 071/155] MediaEndpointConfiguration: Add ice candidate gathering done 'flag' --- .../WebCore/platform/mediastream/PeerMediaDescription.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index a952459c3b4c7..45e2c0c9a0cfa 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -93,8 +93,13 @@ class PeerMediaDescription : public RefCounted { const Vector>& iceCandidates() const { return m_iceCandidates; } void addIceCandidate(RefPtr&& candidate) { m_iceCandidates.append(WTF::move(candidate)); } + bool iceCandidateGatheringDone() const { return m_iceCandidateGatheringDone; } + void setIceCandidateGatheringDone(bool iceCandidateGatheringDone) { m_iceCandidateGatheringDone = iceCandidateGatheringDone; } + private: - PeerMediaDescription() { } + PeerMediaDescription() + : m_iceCandidateGatheringDone(false) + { } String m_type; unsigned short m_port; @@ -117,6 +122,7 @@ class PeerMediaDescription : public RefCounted { String m_iceUfrag; String m_icePassword; Vector> m_iceCandidates; + bool m_iceCandidateGatheringDone; }; } // namespace WebCore From bc4019596c5fa91c9accfbb66ae1b4a4f673aa66 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 25 Apr 2015 17:25:40 +0200 Subject: [PATCH 072/155] MediaEndpointConfiguration: Initialize bools and ints in constructor --- Source/WebCore/platform/mediastream/IceCandidate.h | 4 +++- .../platform/mediastream/MediaEndpointConfiguration.h | 4 +++- Source/WebCore/platform/mediastream/MediaPayload.h | 5 ++++- Source/WebCore/platform/mediastream/PeerMediaDescription.h | 4 +++- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Source/WebCore/platform/mediastream/IceCandidate.h b/Source/WebCore/platform/mediastream/IceCandidate.h index b904f9a9965b1..03329a33e9320 100644 --- a/Source/WebCore/platform/mediastream/IceCandidate.h +++ b/Source/WebCore/platform/mediastream/IceCandidate.h @@ -60,7 +60,9 @@ class IceCandidate : public RefCounted { void setTransport(const String& transport) { m_transport = transport; } private: - IceCandidate() { } + IceCandidate() + : m_componentId(0) + { } String m_type; String m_foundation; diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h index 32f3341ee595f..02d7b3d099def 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h @@ -52,7 +52,9 @@ class MediaEndpointConfiguration : public RefCounted void addMediaDescription(RefPtr&& description) { m_mediaDescriptions.append(WTF::move(description)); } private: - MediaEndpointConfiguration() { } + MediaEndpointConfiguration() + : m_sessionId(0) + { } unsigned long m_sessionId; diff --git a/Source/WebCore/platform/mediastream/MediaPayload.h b/Source/WebCore/platform/mediastream/MediaPayload.h index 64d62098d381f..55e8c263ccbe0 100644 --- a/Source/WebCore/platform/mediastream/MediaPayload.h +++ b/Source/WebCore/platform/mediastream/MediaPayload.h @@ -55,7 +55,10 @@ class MediaPayload : public RefCounted { unsigned clockRate() const { return m_clockRate; } private: - MediaPayload() { } + MediaPayload() + : m_type(0) + , m_clockRate(0) + { } unsigned m_type; String m_encodingName; diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index 45e2c0c9a0cfa..1b005a46bc45c 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -98,7 +98,9 @@ class PeerMediaDescription : public RefCounted { private: PeerMediaDescription() - : m_iceCandidateGatheringDone(false) + : m_port(0) + , m_rtcpMux(false) + , m_iceCandidateGatheringDone(false) { } String m_type; From e2e57334794a143621b06f52950731201e968bc6 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 25 Apr 2015 17:41:21 +0200 Subject: [PATCH 073/155] RTCPeerConnection: Implement maybeDispatchGatheringDone() --- .../Modules/mediastream/RTCPeerConnection.cpp | 17 +++++++++++++---- .../Modules/mediastream/RTCPeerConnection.h | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 95e014c3bb9ca..235032a1990a3 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -562,14 +562,15 @@ void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr RTCPeerConnection::doneGatheringCandidates\n"); printf("is context thread: %d\n", scriptExecutionContext()->isContextThread()); ASSERT(scriptExecutionContext()->isContextThread()); - scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, 0)); + m_localConfiguration->mediaDescriptions()[mdescIndex]->setIceCandidateGatheringDone(true); + maybeDispatchGatheringDone(); } void RTCPeerConnection::gotRemoteSource(unsigned, RefPtr&&) @@ -652,9 +653,17 @@ RTCPeerConnection::ResolveSetLocalDescriptionResult RTCPeerConnection::maybeReso return LocalConfigurationIncomplete; } -void RTCPeerConnection::maybeDispatchGatheringDone() const +void RTCPeerConnection::maybeDispatchGatheringDone() { - // FIXME: implement + if (!isLocalConfigurationComplete()) + return; + + for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { + if (!mdesc->iceCandidateGatheringDone()) + return; + } + + scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, nullptr)); } const char* RTCPeerConnection::activeDOMObjectName() const diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 1057886674028..7318deb2cb15a 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -163,7 +163,7 @@ class RTCPeerConnection final : public RefCounted, public Scr bool isLocalConfigurationComplete() const; ResolveSetLocalDescriptionResult maybeResolveSetLocalDescription(); - void maybeDispatchGatheringDone() const; + void maybeDispatchGatheringDone(); void scheduleDispatchEvent(PassRefPtr); void scheduledEventTimerFired(); From f5b0da0ad566334e75ead1d6240b71266604c636 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 09:32:46 +0200 Subject: [PATCH 074/155] MediaEndpointConfiguration: Make IceCandidate complete (with JSON conversions) --- .../platform/mediastream/IceCandidate.h | 27 +++++++++++++++++++ .../MediaEndpointConfigurationConversions.cpp | 24 +++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/Source/WebCore/platform/mediastream/IceCandidate.h b/Source/WebCore/platform/mediastream/IceCandidate.h index 03329a33e9320..0a7f99b7f9e95 100644 --- a/Source/WebCore/platform/mediastream/IceCandidate.h +++ b/Source/WebCore/platform/mediastream/IceCandidate.h @@ -59,15 +59,42 @@ class IceCandidate : public RefCounted { const String& transport() const { return m_transport; } void setTransport(const String& transport) { m_transport = transport; } + int priority() const { return m_priority; } + void setPriority(int priority) { m_priority = priority; } + + const String& address() const { return m_address; } + void setAddress(const String& address) { m_address = address; } + + unsigned port() const { return m_port; } + void setPort(unsigned port) { m_port = port; } + + const String& tcpType() const { return m_tcpType; } + void setTcpType(const String& tcpType) { m_tcpType = tcpType; } + + const String& relatedAddress() const { return m_relatedAddress; } + void setRelatedAddress(const String& relatedAddress) { m_relatedAddress = relatedAddress; } + + unsigned relatedPort() const { return m_relatedPort; } + void setRelatedPort(unsigned relatedPort) { m_relatedPort = relatedPort; } + private: IceCandidate() : m_componentId(0) + , m_priority(0) + , m_port(0) + , m_relatedPort(0) { } String m_type; String m_foundation; unsigned m_componentId; String m_transport; + int m_priority; + String m_address; + unsigned m_port; + String m_tcpType; + String m_relatedAddress; + unsigned m_relatedPort; }; } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index 660b6273da0a1..af9a321081e44 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -54,6 +54,12 @@ static RefPtr createCandidateObject(IceCandidate* candidate) candidateObject->setString(ASCIILiteral("foundation"), candidate->foundation()); candidateObject->setInteger(ASCIILiteral("componentId"), candidate->componentId()); candidateObject->setString(ASCIILiteral("transport"), candidate->transport()); + candidateObject->setInteger(ASCIILiteral("priority"), candidate->priority()); + candidateObject->setString(ASCIILiteral("address"), candidate->address()); + candidateObject->setInteger(ASCIILiteral("port"), candidate->port()); + candidateObject->setString(ASCIILiteral("tcpType"), candidate->tcpType()); + candidateObject->setString(ASCIILiteral("relatedAddress"), candidate->relatedAddress()); + candidateObject->setInteger(ASCIILiteral("relatedPort"), candidate->relatedPort()); return candidateObject; } @@ -76,6 +82,24 @@ static RefPtr createCandidate(InspectorObject* candidateObject) if (candidateObject->getString(ASCIILiteral("transport"), stringValue)) candidate->setTransport(stringValue); + if (candidateObject->getInteger(ASCIILiteral("priority"), intValue)) + candidate->setPriority(intValue); + + if (candidateObject->getString(ASCIILiteral("address"), stringValue)) + candidate->setAddress(stringValue); + + if (candidateObject->getInteger(ASCIILiteral("port"), intValue)) + candidate->setPort(intValue); + + if (candidateObject->getString(ASCIILiteral("tcpType"), stringValue)) + candidate->setTcpType(stringValue); + + if (candidateObject->getString(ASCIILiteral("relatedAddress"), stringValue)) + candidate->setRelatedAddress(stringValue); + + if (candidateObject->getInteger(ASCIILiteral("relatedPort"), intValue)) + candidate->setRelatedPort(intValue); + return candidate; } From 22036c78b814e1aa6b00d5c883816893ebd1e9f6 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 09:38:58 +0200 Subject: [PATCH 075/155] RTCPeerConnection: Add generated candidates to local configuration (update local config completeness check) --- .../Modules/mediastream/RTCPeerConnection.cpp | 20 +++++-- .../Modules/mediastream/RTCPeerConnection.h | 2 +- .../platform/mediastream/MediaEndpoint.h | 2 +- .../openwebrtc/MediaEndpointOwr.cpp | 55 ++++++++++++++----- .../mediastream/openwebrtc/MediaEndpointOwr.h | 2 +- 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 235032a1990a3..72490ad0dbee8 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -545,13 +545,22 @@ void RTCPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& ce maybeDispatchGatheringDone(); } -void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate) +void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate, const String& ufrag, const String& password) { - printf("-> RTCPeerConnection::gotIceCandidate\n"); - printf("is context thread: %d\n", scriptExecutionContext()->isContextThread()); + printf("-> gotIceCandidate()\n"); ASSERT(scriptExecutionContext()->isContextThread()); + PeerMediaDescription& mdesc = *m_localConfiguration->mediaDescriptions()[mdescIndex]; + if (mdesc.iceUfrag().isEmpty()) { + mdesc.setIceUfrag(ufrag); + mdesc.setIcePassword(password); + } + + mdesc.addIceCandidate(candidate.copyRef()); + + // FIXME: update mdesc address (ideally with active candidate) + ResolveSetLocalDescriptionResult result = maybeResolveSetLocalDescription(); if (result == SetLocalDescriptionResolvedSuccessfully) maybeDispatchGatheringDone(); @@ -564,8 +573,7 @@ void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr RTCPeerConnection::doneGatheringCandidates\n"); - printf("is context thread: %d\n", scriptExecutionContext()->isContextThread()); + printf("-> doneGatheringCandidates()\n"); ASSERT(scriptExecutionContext()->isContextThread()); @@ -630,7 +638,7 @@ bool RTCPeerConnection::isLocalConfigurationComplete() const { for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { // FIXME: add more tests - if (mdesc->dtlsFingerprint().isEmpty()) + if (mdesc->dtlsFingerprint().isEmpty() || mdesc->iceUfrag().isEmpty()) return false; } diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 7318deb2cb15a..bb017a256a099 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -101,7 +101,7 @@ class RTCPeerConnection final : public RefCounted, public Scr // MediaEndpointClient virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) override; virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; - virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) override; + virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) override; virtual void doneGatheringCandidates(unsigned mdescIndex) override; virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index bf295b6e1fa2a..4bcb0cb79c78c 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -48,7 +48,7 @@ class MediaEndpointClient { public: virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) = 0; virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) = 0; - virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) = 0; + virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) = 0; virtual void doneGatheringCandidates(unsigned mdescIndex) = 0; virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) = 0; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index e4e43f0f8c09f..5a619e0a81281 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -46,7 +46,8 @@ static void gotDtlsCertificate(OwrSession*, GParamSpec*, MediaEndpointOwr*); static void gotSendSsrc(OwrMediaSession*, GParamSpec*, MediaEndpointOwr*); static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*); -static const char* iceCandidateTypes[] = { "host", "srflx", "relay", nullptr }; +static const char* iceCandidateTypes[] = { "host", "srflx", "relay" }; +static const char* iceCandidateTcpTypes[] = { "", "active", "passive", "so" }; static std::unique_ptr createMediaEndpointOwr(MediaEndpointClient* client) { @@ -130,9 +131,9 @@ unsigned MediaEndpointOwr::sessionIndex(OwrSession* session) const return index; } -void MediaEndpointOwr::dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&& iceCandidate) +void MediaEndpointOwr::dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&& iceCandidate, const String& ufrag, const String& password) { - m_client->gotIceCandidate(sessionIndex, WTF::move(iceCandidate)); + m_client->gotIceCandidate(sessionIndex, WTF::move(iceCandidate), ufrag, password); } void MediaEndpointOwr::dispatchGatheringDone(unsigned sessionIndex) @@ -184,32 +185,60 @@ void MediaEndpointOwr::ensureTransportAgentAndSessions(bool isInitiator, const V static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndpointOwr* mediaEndpoint) { OwrCandidateType candidateType; - OwrComponentType componentType; - OwrTransportType transportType; gchar* foundation; + OwrComponentType componentId; + OwrTransportType transportType; + gint priority; gchar* address; + guint port; gchar* relatedAddress; - gint port, priority, relatedPort; + guint relatedPort; + gchar* ufrag; + gchar* password; g_object_get(candidate, "type", &candidateType, - "component-type", &componentType, "foundation", &foundation, + "component-type", &componentId, "transport-type", &transportType, + "priority", &priority, "address", &address, "port", &port, - "priority", &priority, "base-address", &relatedAddress, - "base-port", &relatedPort, nullptr); + "base-port", &relatedPort, + "ufrag", &ufrag, + "password", &password, + nullptr); - printf("candidateType: %d, foundation: %s, address: %s, port %d\n", candidateType, foundation, address, port); + ASSERT(candidateType >= 0 && candidateType <= 2); + ASSERT(transportType >= 0 && transportType <= 3); RefPtr iceCandidate = IceCandidate::create(); iceCandidate->setType(iceCandidateTypes[candidateType]); iceCandidate->setFoundation(foundation); - iceCandidate->setTransport(transportType == OWR_TRANSPORT_TYPE_UDP ? "UDP" : "TCP"); - // FIXME: set the rest + iceCandidate->setComponentId(componentId); + iceCandidate->setPriority(priority); + iceCandidate->setAddress(address); + iceCandidate->setPort(port); + + if (transportType == OWR_TRANSPORT_TYPE_UDP) + iceCandidate->setTransport("UDP"); + else { + iceCandidate->setTransport("TCP"); + iceCandidate->setTcpType(iceCandidateTcpTypes[transportType]); + } + + if (candidateType == OWR_CANDIDATE_TYPE_HOST) { + iceCandidate->setRelatedAddress(relatedAddress); + iceCandidate->setRelatedPort(relatedPort); + } + + mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->sessionIndex(session), WTF::move(iceCandidate), String(ufrag), String(password)); - mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->sessionIndex(session), WTF::move(iceCandidate)); + g_free(foundation); + g_free(address); + g_free(relatedAddress); + g_free(ufrag); + g_free(password); } static void candidateGatheringDone(OwrSession* session, MediaEndpointOwr* mediaEndpoint) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index 90d90bad20ad8..a6562cebfdaad 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -58,7 +58,7 @@ class MediaEndpointOwr : public MediaEndpoint { unsigned sessionIndex(OwrSession*) const; - void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&); + void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&, const String& ufrag, const String& password); void dispatchGatheringDone(unsigned sessionIndex); void dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate); From 1efd8958b8fe45971e664c76d914c22c9cc3ec44 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 10:36:55 +0200 Subject: [PATCH 076/155] RTCPeerConnection: Handle cname and send SSRCs (not complete) --- .../Modules/mediastream/RTCPeerConnection.cpp | 10 ++++++++-- .../mediastream/openwebrtc/MediaEndpointOwr.cpp | 15 +++++++++++++-- .../mediastream/openwebrtc/MediaEndpointOwr.h | 1 + 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 72490ad0dbee8..4678ce8277b9b 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -498,10 +498,13 @@ void RTCPeerConnection::close() m_signalingState = SignalingStateClosed; } -void RTCPeerConnection::gotSendSSRC(unsigned, const String&, const String&) +void RTCPeerConnection::gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) { printf("-> gotSendSSRC()\n"); + m_localConfiguration->mediaDescriptions()[mdescIndex]->addSsrc(ssrc); + m_localConfiguration->mediaDescriptions()[mdescIndex]->setCname(cname); + maybeResolveSetLocalDescription(); } @@ -637,9 +640,12 @@ RTCPeerConnection::DescriptionType RTCPeerConnection::parseDescriptionType(const bool RTCPeerConnection::isLocalConfigurationComplete() const { for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { - // FIXME: add more tests if (mdesc->dtlsFingerprint().isEmpty() || mdesc->iceUfrag().isEmpty()) return false; + if (mdesc->type() == "audio" || mdesc->type() == "video") { + if (!mdesc->ssrcs().size() || mdesc->cname().isEmpty()) + return false; + } } return true; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 5a619e0a81281..c2cea73441905 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -146,6 +146,11 @@ void MediaEndpointOwr::dispatchDtlsCertificate(unsigned sessionIndex, const Stri m_client->gotDtlsCertificate(sessionIndex, certificate); } +void MediaEndpointOwr::dispatchSendSSRC(unsigned sessionIndex, const String& ssrc, const String& cname) +{ + m_client->gotSendSSRC(sessionIndex, ssrc, cname); +} + void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription*) { g_signal_connect(session, "on-new-candidate", G_CALLBACK(gotCandidate), this); @@ -257,9 +262,15 @@ static void gotDtlsCertificate(OwrSession* session, GParamSpec*, MediaEndpointOw mediaEndpoint->dispatchDtlsCertificate(mediaEndpoint->sessionIndex(session), certificate); } -static void gotSendSsrc(OwrMediaSession* mediaSession, GParamSpec*, MediaEndpointOwr*) +static void gotSendSsrc(OwrMediaSession* mediaSession, GParamSpec*, MediaEndpointOwr* mediaEndpoint) { - printf("-> gotSendSsrc\n"); + gchar* cname; + g_object_get(mediaSession, "cname", &cname, nullptr); + + // FIXME: fix send-ssrc + mediaEndpoint->dispatchSendSSRC(mediaEndpoint->sessionIndex(OWR_SESSION(mediaSession)), "fix me", String(cname)); + + g_free(cname); } static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index a6562cebfdaad..fc21cc8f57d75 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -61,6 +61,7 @@ class MediaEndpointOwr : public MediaEndpoint { void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&, const String& ufrag, const String& password); void dispatchGatheringDone(unsigned sessionIndex); void dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate); + void dispatchSendSSRC(unsigned sessionIndex, const String& ssrc, const String& cname); private: enum SessionType { SessionTypeMedia }; From dfcf2257482c80ff5c35291f337a6b814015bdf8 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 16:04:50 +0200 Subject: [PATCH 077/155] MediaEndpointOwr: Use Vector for string to index (and reverse) translate lists --- .../mediastream/openwebrtc/MediaEndpointOwr.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index c2cea73441905..f07738a19ec81 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -46,8 +46,8 @@ static void gotDtlsCertificate(OwrSession*, GParamSpec*, MediaEndpointOwr*); static void gotSendSsrc(OwrMediaSession*, GParamSpec*, MediaEndpointOwr*); static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*); -static const char* iceCandidateTypes[] = { "host", "srflx", "relay" }; -static const char* iceCandidateTcpTypes[] = { "", "active", "passive", "so" }; +static const Vector candidateTypes = { "host", "srflx", "prflx", "relay" }; +static const Vector candidateTcpTypes = { "", "active", "passive", "so" }; static std::unique_ptr createMediaEndpointOwr(MediaEndpointClient* client) { @@ -214,11 +214,11 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp "password", &password, nullptr); - ASSERT(candidateType >= 0 && candidateType <= 2); - ASSERT(transportType >= 0 && transportType <= 3); + ASSERT(candidateType >= 0 && candidateType < candidateTypes.size()); + ASSERT(transportType >= 0 && transportType < candidateTcpTypes.size()); RefPtr iceCandidate = IceCandidate::create(); - iceCandidate->setType(iceCandidateTypes[candidateType]); + iceCandidate->setType(candidateTypes[candidateType]); iceCandidate->setFoundation(foundation); iceCandidate->setComponentId(componentId); iceCandidate->setPriority(priority); @@ -229,7 +229,7 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp iceCandidate->setTransport("UDP"); else { iceCandidate->setTransport("TCP"); - iceCandidate->setTcpType(iceCandidateTcpTypes[transportType]); + iceCandidate->setTcpType(candidateTcpTypes[transportType]); } if (candidateType == OWR_CANDIDATE_TYPE_HOST) { From 537604bf6a41c3c21bc244c530616d17f7b5334f Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 16:05:39 +0200 Subject: [PATCH 078/155] MediaEndpointConfiguration: Add source to media description --- Source/WebCore/platform/mediastream/PeerMediaDescription.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index 1b005a46bc45c..8eb5f37f6f311 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -35,6 +35,7 @@ #include "IceCandidate.h" #include "MediaPayload.h" +#include "RealtimeMediaSource.h" #include #include @@ -96,11 +97,15 @@ class PeerMediaDescription : public RefCounted { bool iceCandidateGatheringDone() const { return m_iceCandidateGatheringDone; } void setIceCandidateGatheringDone(bool iceCandidateGatheringDone) { m_iceCandidateGatheringDone = iceCandidateGatheringDone; } + RealtimeMediaSource* source() const { return m_source.get(); } + void setSource(RefPtr&& source) { m_source = source; } + private: PeerMediaDescription() : m_port(0) , m_rtcpMux(false) , m_iceCandidateGatheringDone(false) + , m_source(nullptr) { } String m_type; @@ -125,6 +130,8 @@ class PeerMediaDescription : public RefCounted { String m_icePassword; Vector> m_iceCandidates; bool m_iceCandidateGatheringDone; + + RefPtr m_source; }; } // namespace WebCore From 4b1dcb1ec3c70fd0c86d83c5813d39be371e9f4e Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 16:10:08 +0200 Subject: [PATCH 079/155] MediaEndpointOwr: Add hard coded receive payload --- .../openwebrtc/MediaEndpointOwr.cpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index f07738a19ec81..37401c3ac9485 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -36,6 +36,8 @@ #include "MediaEndpointConfiguration.h" #include "OpenWebRTCUtilities.h" #include +#include +#include #include namespace WebCore { @@ -167,6 +169,29 @@ void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMe g_signal_connect(mediaSession, "notify::send-ssrc", G_CALLBACK(gotSendSsrc), this); g_signal_connect(mediaSession, "on-incoming-source", G_CALLBACK(gotIncomingSource), this); + + OwrPayload* receivePayload; + + if (mediaDescription->type() == "audio") { + // { "encodingName": "OPUS", "type": 111, "clockRate": 48000, "channels": 2 }, + OwrCodecType codecType = OWR_CODEC_TYPE_OPUS; + gint64 payloadType = 111; + gint64 clockRate = 48000; + gint64 channels = 2; + + receivePayload = owr_audio_payload_new(codecType, payloadType, clockRate, channels); + } else { + // { "encodingName": "VP8", "type": 100, "clockRate": 90000, "ccmfir": true, "nackpli": true, "nack": true } + OwrCodecType codecType = OWR_CODEC_TYPE_VP8; + gint64 payloadType = 100; + gint64 clockRate = 90000; + gboolean ccmfir = true; + gboolean nackpli = true; + + receivePayload = owr_video_payload_new(codecType, payloadType, clockRate, ccmfir, nackpli); + } + + owr_media_session_add_receive_payload(mediaSession, receivePayload); } void MediaEndpointOwr::ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs) From 1ce9b0df6b04290e683033c5b8526949b82480f5 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 16:12:08 +0200 Subject: [PATCH 080/155] MediaEndpointOwr: Initial version of prepareToReceive() and internalAddRemoteCandidate() --- .../openwebrtc/MediaEndpointOwr.cpp | 92 ++++++++++++++++++- .../mediastream/openwebrtc/MediaEndpointOwr.h | 1 + 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 37401c3ac9485..6d9bfa8c71285 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -35,6 +35,7 @@ #include "MediaEndpointConfiguration.h" #include "OpenWebRTCUtilities.h" +#include "RealtimeMediaSourceOwr.h" #include #include #include @@ -99,9 +100,66 @@ void MediaEndpointOwr::prepareToReceive(MediaEndpointConfiguration* configuratio m_numberOfReceivePreparedSessions = m_sessions.size(); } -void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration*, bool) +void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration* configuration, bool isInitiator) { - printf("-> MediaEndpointOwr::prepareToSend\n"); + Vector sessionConfigs; + for (unsigned i = m_sessions.size(); i < configuration->mediaDescriptions().size(); ++i) { + SessionConfig config; + config.type = SessionTypeMedia; + config.isDtlsClient = configuration->mediaDescriptions()[i]->dtlsSetup() != "active"; + sessionConfigs.append(WTF::move(config)); + } + + ensureTransportAgentAndSessions(isInitiator, sessionConfigs); + + for (unsigned i = 0; i < m_sessions.size(); ++i) { + if (i >= configuration->mediaDescriptions().size()) + printf("prepareToSend: BAD missing configuration element for %d\n", i); + + OwrSession* session = m_sessions[i]; + PeerMediaDescription& mdesc = *configuration->mediaDescriptions()[i]; + + if (mdesc.type() == "audio" || mdesc.type() == "video") + g_object_set(session, "rtcp-mux", mdesc.rtcpMux(), nullptr); + + if (mdesc.iceCandidates().size()) { + for (auto& candidate : mdesc.iceCandidates()) + internalAddRemoteCandidate(session, *candidate, mdesc.iceUfrag(), mdesc.icePassword()); + } + + if (i < m_numberOfSendPreparedSessions) + continue; + + if (!mdesc.source()) + continue; + + OwrPayload* sendPayload; + RealtimeMediaSourceOwr* source = static_cast(mdesc.source()); + + if (mdesc.type() == "audio") { + // { "encodingName": "OPUS", "type": 111, "clockRate": 48000, "channels": 2 }, + OwrCodecType codecType = OWR_CODEC_TYPE_OPUS; + gint64 payloadType = 111; + gint64 clockRate = 48000; + gint64 channels = 2; + + sendPayload = owr_audio_payload_new(codecType, payloadType, clockRate, channels); + } else { + // { "encodingName": "VP8", "type": 100, "clockRate": 90000, "ccmfir": true, "nackpli": true, "nack": true } + OwrCodecType codecType = OWR_CODEC_TYPE_VP8; + gint64 payloadType = 100; + gint64 clockRate = 90000; + gboolean ccmfir = true; + gboolean nackpli = true; + + sendPayload = owr_video_payload_new(codecType, payloadType, clockRate, ccmfir, nackpli); + } + + owr_media_session_set_send_payload(OWR_MEDIA_SESSION(session), sendPayload); + owr_media_session_set_send_source(OWR_MEDIA_SESSION(session), source->mediaSource()); + + m_numberOfSendPreparedSessions = i + 1; + } } void MediaEndpointOwr::addRemoteCandidate(IceCandidate* candidate) @@ -212,6 +270,36 @@ void MediaEndpointOwr::ensureTransportAgentAndSessions(bool isInitiator, const V m_sessions.append(OWR_SESSION(owr_media_session_new(config.isDtlsClient))); } +void MediaEndpointOwr::internalAddRemoteCandidate(OwrSession* session, IceCandidate& candidate, const String& ufrag, const String& password) +{ + gboolean rtcpMux; + g_object_get(session, "rtcp-mux", &rtcpMux, nullptr); + + if (rtcpMux && candidate.componentId() == OWR_COMPONENT_TYPE_RTCP) + return; + + ASSERT(candidateTypes.find(candidate.type()) != notFound); + ASSERT(candidateTcpTypes.find(candidate.tcpType()) != notFound); + + OwrCandidateType candidateType = static_cast(candidateTypes.find(candidate.type())); + OwrComponentType componentId = static_cast(candidate.componentId()); + OwrTransportType transportType = static_cast(candidateTcpTypes.find(candidate.tcpType())); + + OwrCandidate* owrCandidate = owr_candidate_new(candidateType, componentId); + g_object_set(owrCandidate, "transport-type", transportType, + "address", candidate.address().ascii().data(), + "port", candidate.port(), + "base-address", candidate.relatedAddress().ascii().data(), + "base-port", candidate.relatedPort(), + "priority", candidate.priority(), + "foundation", candidate.foundation().ascii().data(), + "ufrag", ufrag.ascii().data(), + "password", password.ascii().data(), + nullptr); + + owr_session_add_remote_candidate(session, owrCandidate); +} + static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndpointOwr* mediaEndpoint) { OwrCandidateType candidateType; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index fc21cc8f57d75..2e7e45c5c4261 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -75,6 +75,7 @@ class MediaEndpointOwr : public MediaEndpoint { void prepareMediaSession(OwrMediaSession*, PeerMediaDescription*, bool isInitiator); void ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs); + void internalAddRemoteCandidate(OwrSession*, IceCandidate&, const String& ufrag, const String& password); RefPtr m_configuration; From e89453ff825944276c531aaa583d5c8eb651bd10 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 16:13:57 +0200 Subject: [PATCH 081/155] MediaEndpoint: Fix style error --- Source/WebCore/platform/mediastream/MediaEndpoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index 4bcb0cb79c78c..33d5243f268d9 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -68,7 +68,7 @@ class MediaEndpoint { virtual void prepareToReceive(MediaEndpointConfiguration*, bool isInitiator) = 0; virtual void prepareToSend(MediaEndpointConfiguration*, bool isInitiator) = 0; - virtual void addRemoteCandidate(IceCandidate *) = 0; + virtual void addRemoteCandidate(IceCandidate*) = 0; virtual void stop() = 0; }; From bac2280b438698ba5cc13c762e93493aa11a8591 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 26 Apr 2015 21:48:39 +0200 Subject: [PATCH 082/155] RTCPeerConnection: First proper version of addIceCandidate() --- .../Modules/mediastream/RTCPeerConnection.cpp | 37 +++++++++++++++---- .../platform/mediastream/MediaEndpoint.h | 2 +- .../openwebrtc/MediaEndpointOwr.cpp | 16 +------- .../mediastream/openwebrtc/MediaEndpointOwr.h | 2 +- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 4678ce8277b9b..b0da70d49bb9f 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -387,25 +387,48 @@ void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionC m_mediaEndpoint->setConfiguration(createMediaEndpointInit(*m_configuration)); } -void RTCPeerConnection::addIceCandidate(RTCIceCandidate* iceCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) +void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; return; } - RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(iceCandidate->candidate()); + if (!m_remoteConfiguration) { + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidStateError (no remote description)"); + rejectCallback(error.get()); + }); + return; + } + + RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(rtcCandidate->candidate()); if (!candidate) { - rejectCallback(DOMError::create("FIXME: bad candidate")); + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); + rejectCallback(error.get()); + }); return; } - printf("RTCPeerConnection::addIceCandidate: candidate: type %s, foundation: %s, componentId: %d, transport: %s\n", - candidate->type().ascii().data(), candidate->foundation().ascii().data(), candidate->componentId(), candidate->transport().ascii().data()); + unsigned mdescIndex = rtcCandidate->sdpMLineIndex(); + if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSdpMlineIndex (sdpMLineIndex out of range"); + rejectCallback(error.get()); + }); + return; + } + + PeerMediaDescription& mdesc = *m_remoteConfiguration->mediaDescriptions()[mdescIndex]; + mdesc.addIceCandidate(candidate.copyRef()); - m_mediaEndpoint->addRemoteCandidate(candidate.get()); + m_mediaEndpoint->addRemoteCandidate(*candidate, mdescIndex, mdesc.iceUfrag(), mdesc.icePassword()); - resolveCallback(); + callOnMainThread(resolveCallback); } String RTCPeerConnection::signalingState() const diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index 33d5243f268d9..4a974e63788aa 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -68,7 +68,7 @@ class MediaEndpoint { virtual void prepareToReceive(MediaEndpointConfiguration*, bool isInitiator) = 0; virtual void prepareToSend(MediaEndpointConfiguration*, bool isInitiator) = 0; - virtual void addRemoteCandidate(IceCandidate*) = 0; + virtual void addRemoteCandidate(IceCandidate&, unsigned mdescIndex, const String& ufrag, const String& password) = 0; virtual void stop() = 0; }; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 6d9bfa8c71285..c0ee1be69ed7a 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -162,21 +162,9 @@ void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration* configuration, } } -void MediaEndpointOwr::addRemoteCandidate(IceCandidate* candidate) +void MediaEndpointOwr::addRemoteCandidate(IceCandidate& candidate, unsigned mdescIndex, const String& ufrag, const String& password) { - OwrCandidateType candidateType; - OwrComponentType componentType = (OwrComponentType) candidate->componentId(); - - if (candidate->type() == "host") - candidateType = OWR_CANDIDATE_TYPE_HOST; - else if (candidate->type() == "srflx") - candidateType = OWR_CANDIDATE_TYPE_SERVER_REFLEXIVE; - else - candidateType = OWR_CANDIDATE_TYPE_RELAY; - - OwrCandidate* remoteCandidate = owr_candidate_new(candidateType, componentType); - - printf("MediaEndpointOwr::addRemoteCandidate: created candidate: %p\n", remoteCandidate); + internalAddRemoteCandidate(m_sessions[mdescIndex], candidate, ufrag, password); } void MediaEndpointOwr::stop() diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index 2e7e45c5c4261..0e20a881bcec0 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -52,7 +52,7 @@ class MediaEndpointOwr : public MediaEndpoint { virtual void prepareToReceive(MediaEndpointConfiguration*, bool isInitiator) override; virtual void prepareToSend(MediaEndpointConfiguration*, bool isInitiator) override; - virtual void addRemoteCandidate(IceCandidate*) override; + virtual void addRemoteCandidate(IceCandidate&, unsigned mdescIndex, const String& ufrag, const String& password) override; virtual void stop() override; From 0d0aade9509eda27600573c8f042f3de5e66d3e0 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 17 May 2015 22:34:54 +0200 Subject: [PATCH 083/155] RTCIceCandidate: Make attributes writable (align with spec) --- .../Modules/mediastream/RTCIceCandidate.cpp | 16 ++++++++++++++++ .../Modules/mediastream/RTCIceCandidate.h | 5 +++++ .../Modules/mediastream/RTCIceCandidate.idl | 6 +++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp index 22afd132721e4..da36cb46c24b1 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp @@ -95,16 +95,32 @@ const String& RTCIceCandidate::candidate() const return m_candidate; } +void RTCIceCandidate::setCandidate(const String& candidate) +{ + m_candidate = candidate; +} + + const String& RTCIceCandidate::sdpMid() const { return m_sdpMid; } +void RTCIceCandidate::setSdpMid(const String& sdpMid) +{ + m_sdpMid = sdpMid; +} + unsigned short RTCIceCandidate::sdpMLineIndex() const { return m_sdpMLineIndex; } +void RTCIceCandidate::setSdpMLineIndex(unsigned short sdpMLineIndex) +{ + m_sdpMLineIndex = sdpMLineIndex; +} + } // namespace WebCore #endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h index 1cc8d91750352..cf4ca9d2957ea 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h @@ -51,8 +51,13 @@ class RTCIceCandidate : public RefCounted, public ScriptWrappab virtual ~RTCIceCandidate(); const String& candidate() const; + void setCandidate(const String&); + const String& sdpMid() const; + void setSdpMid(const String&); + unsigned short sdpMLineIndex() const; + void setSdpMLineIndex(unsigned short); private: explicit RTCIceCandidate(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex); diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl b/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl index 4fb49586d1520..8e6238def91e1 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.idl @@ -34,8 +34,8 @@ CustomConstructor(optional Dictionary dictionary), ConstructorRaisesException ] interface RTCIceCandidate { - readonly attribute DOMString candidate; - readonly attribute DOMString sdpMid; - readonly attribute unsigned short sdpMLineIndex; + attribute DOMString candidate; + attribute DOMString sdpMid; + attribute unsigned short sdpMLineIndex; }; From de26dcc953a3c96c9cc41c2b5307fd221da325f7 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 17 May 2015 22:39:31 +0200 Subject: [PATCH 084/155] MediaEndpoint: Fixed Realtime/RealTime mixed spellings --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 2 +- Source/WebCore/Modules/mediastream/RTCPeerConnection.h | 2 +- Source/WebCore/platform/mediastream/MediaEndpoint.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index b0da70d49bb9f..b306bc744d212 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -607,7 +607,7 @@ void RTCPeerConnection::doneGatheringCandidates(unsigned mdescIndex) maybeDispatchGatheringDone(); } -void RTCPeerConnection::gotRemoteSource(unsigned, RefPtr&&) +void RTCPeerConnection::gotRemoteSource(unsigned, RefPtr&&) { } diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index bb017a256a099..b2cff5376e899 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -103,7 +103,7 @@ class RTCPeerConnection final : public RefCounted, public Scr virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) override; virtual void doneGatheringCandidates(unsigned mdescIndex) override; - virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; + virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; // EventTarget virtual EventTargetInterface eventTargetInterface() const override { return RTCPeerConnectionEventTargetInterfaceType; } diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index 4a974e63788aa..903a3d42002b1 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -42,7 +42,7 @@ namespace WebCore { class IceCandidate; class MediaEndpoint; class MediaEndpointConfiguration; -class RealTimeMediaSource; // not implemented +class RealtimeMediaSource; class MediaEndpointClient { public: @@ -50,7 +50,7 @@ class MediaEndpointClient { virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) = 0; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) = 0; virtual void doneGatheringCandidates(unsigned mdescIndex) = 0; - virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) = 0; + virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) = 0; virtual ~MediaEndpointClient() { } }; From a664b3efbc989733b9c70e8497b9dc04c356b751 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sun, 17 May 2015 22:42:53 +0200 Subject: [PATCH 085/155] RTCPeerConnection: Add takeFirstSenderOfType() helper function --- .../Modules/mediastream/RTCPeerConnection.cpp | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index b306bc744d212..6b621ecb07a54 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -172,6 +172,18 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec) // FIXME: Mark connection as needing negotiation. } +static RTCRtpSender* takeFirstSenderOfType(Vector& senders, const String& type) +{ + for (unsigned i = 0; i < senders.size(); ++i) { + if (senders[i]->track()->kind() == type) { + RTCRtpSender* sender = senders[i]; + senders.remove(i); + return sender; + } + } + return nullptr; +} + static void updateMediaDescriptionsWithSenders(const Vector>& mediaDescriptions, Vector& senders) { // Remove any sender(s) from the senders list that already have their tracks represented by a media @@ -193,19 +205,11 @@ static void updateMediaDescriptionsWithSenders(const VectormediaStreamTrackId() != emptyString()) continue; - RTCRtpSender* sender = nullptr; - for (auto s : senders) { - if (s->track()->kind() == mdesc->type()) { - sender = s; - break; - } - } - + RTCRtpSender* sender = takeFirstSenderOfType(senders, mdesc->type()); if (sender) { mdesc->setMediaStreamId(sender->mediaStreamId()); mdesc->setMediaStreamTrackId(sender->track()->id()); mdesc->setMode("sendrecv"); - senders.removeFirst(sender); } else mdesc->setMode("recvonly"); } From e6f0ed89ca20f4003bf7b82d54ee440fd38445a7 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 19 May 2015 09:06:41 +0200 Subject: [PATCH 086/155] MediaEndpoint: ssrc should be an unsigned (instead of String) --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 2 +- Source/WebCore/Modules/mediastream/RTCPeerConnection.h | 2 +- Source/WebCore/platform/mediastream/MediaEndpoint.h | 2 +- .../MediaEndpointConfigurationConversions.cpp | 9 ++++----- .../WebCore/platform/mediastream/PeerMediaDescription.h | 6 +++--- .../platform/mediastream/openwebrtc/MediaEndpointOwr.cpp | 8 ++++---- .../platform/mediastream/openwebrtc/MediaEndpointOwr.h | 2 +- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 6b621ecb07a54..575b67f672705 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -525,7 +525,7 @@ void RTCPeerConnection::close() m_signalingState = SignalingStateClosed; } -void RTCPeerConnection::gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) +void RTCPeerConnection::gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) { printf("-> gotSendSSRC()\n"); diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index b2cff5376e899..9243da0c31922 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -99,7 +99,7 @@ class RTCPeerConnection final : public RefCounted, public Scr void close(); // MediaEndpointClient - virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) override; + virtual void gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) override; virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) override; virtual void doneGatheringCandidates(unsigned mdescIndex) override; diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index 903a3d42002b1..773177e70bf84 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -46,7 +46,7 @@ class RealtimeMediaSource; class MediaEndpointClient { public: - virtual void gotSendSSRC(unsigned mdescIndex, const String& ssrc, const String& cname) = 0; + virtual void gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) = 0; virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) = 0; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) = 0; virtual void doneGatheringCandidates(unsigned mdescIndex) = 0; diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index af9a321081e44..190f5b58f5578 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -190,8 +190,8 @@ RefPtr fromJSON(const String& json) mdescObject->getArray(ASCIILiteral("ssrcs"), ssrcsArray); for (unsigned j = 0; j < ssrcsArray->length(); ++j) { - ssrcsArray->get(j)->asString(stringValue); - mdesc->addSsrc(stringValue); + ssrcsArray->get(j)->asInteger(intValue); + mdesc->addSsrc(intValue); } if (mdescObject->getString(ASCIILiteral("cname"), stringValue)) @@ -279,9 +279,8 @@ String toJSON(MediaEndpointConfiguration* configuration) RefPtr ssrcsArray = InspectorArray::create(); - for (const auto& ssrc : mdesc->ssrcs()) { - ssrcsArray->pushString(ssrc); - } + for (auto ssrc : mdesc->ssrcs()) + ssrcsArray->pushDouble(ssrc); mdescObject->setArray(ASCIILiteral("ssrcs"), ssrcsArray); mdescObject->setString(ASCIILiteral("cname"), mdesc->cname()); diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index 8eb5f37f6f311..07525150ac41f 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -82,8 +82,8 @@ class PeerMediaDescription : public RefCounted { const String& cname() const { return m_cname; } void setCname(const String& cname) { m_cname = cname; } - const Vector& ssrcs() const { return m_ssrcs; } - void addSsrc(const String& ssrc) { m_ssrcs.append(ssrc); } + const Vector& ssrcs() const { return m_ssrcs; } + void addSsrc(unsigned ssrc) { m_ssrcs.append(ssrc); } const String& iceUfrag() const { return m_iceUfrag; } void setIceUfrag(const String& iceUfrag) { m_iceUfrag = iceUfrag; } @@ -123,7 +123,7 @@ class PeerMediaDescription : public RefCounted { String m_dtlsFingerprintHashFunction; String m_dtlsFingerprint; - Vector m_ssrcs; + Vector m_ssrcs; String m_cname; String m_iceUfrag; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index c0ee1be69ed7a..047845d212b8a 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -194,7 +194,7 @@ void MediaEndpointOwr::dispatchDtlsCertificate(unsigned sessionIndex, const Stri m_client->gotDtlsCertificate(sessionIndex, certificate); } -void MediaEndpointOwr::dispatchSendSSRC(unsigned sessionIndex, const String& ssrc, const String& cname) +void MediaEndpointOwr::dispatchSendSSRC(unsigned sessionIndex, unsigned ssrc, const String& cname) { m_client->gotSendSSRC(sessionIndex, ssrc, cname); } @@ -365,11 +365,11 @@ static void gotDtlsCertificate(OwrSession* session, GParamSpec*, MediaEndpointOw static void gotSendSsrc(OwrMediaSession* mediaSession, GParamSpec*, MediaEndpointOwr* mediaEndpoint) { + guint ssrc; gchar* cname; - g_object_get(mediaSession, "cname", &cname, nullptr); + g_object_get(mediaSession, "send-ssrc", &ssrc, "cname", &cname, nullptr); - // FIXME: fix send-ssrc - mediaEndpoint->dispatchSendSSRC(mediaEndpoint->sessionIndex(OWR_SESSION(mediaSession)), "fix me", String(cname)); + mediaEndpoint->dispatchSendSSRC(mediaEndpoint->sessionIndex(OWR_SESSION(mediaSession)), ssrc, String(cname)); g_free(cname); } diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index 0e20a881bcec0..81028e3e3faa2 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -61,7 +61,7 @@ class MediaEndpointOwr : public MediaEndpoint { void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&, const String& ufrag, const String& password); void dispatchGatheringDone(unsigned sessionIndex); void dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate); - void dispatchSendSSRC(unsigned sessionIndex, const String& ssrc, const String& cname); + void dispatchSendSSRC(unsigned sessionIndex, unsigned ssrc, const String& cname); private: enum SessionType { SessionTypeMedia }; From 6258a5eb5fad305d3f210bc8a0713114b054e5b4 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 19 May 2015 11:02:28 +0200 Subject: [PATCH 087/155] MediaEndpointConfiguration: Changed type of sessionId and added sessionVersion --- .../mediastream/MediaEndpointConfiguration.h | 14 ++++++++++---- .../MediaEndpointConfigurationConversions.cpp | 5 ++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h index 02d7b3d099def..f216c7042b660 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h @@ -34,6 +34,7 @@ #if ENABLE(MEDIA_STREAM) #include "PeerMediaDescription.h" +#include namespace WebCore { @@ -45,18 +46,23 @@ class MediaEndpointConfiguration : public RefCounted } virtual ~MediaEndpointConfiguration() { } - unsigned long sessionId() const { return m_sessionId; } - void setSessionId(unsigned long sessionId) { m_sessionId = sessionId; } + uint64_t sessionId() const { return m_sessionId; } + void setSessionId(uint64_t sessionId) { m_sessionId = sessionId; } + + unsigned sessionVersion() const { return m_sessionVersion; } + void setSessionVersion(unsigned sessionVersion) { m_sessionVersion = sessionVersion; } const Vector>& mediaDescriptions() const { return m_mediaDescriptions; } void addMediaDescription(RefPtr&& description) { m_mediaDescriptions.append(WTF::move(description)); } private: MediaEndpointConfiguration() - : m_sessionId(0) + : m_sessionId(cryptographicallyRandomNumber()) // FIXME: should be 64 bits + , m_sessionVersion(0) { } - unsigned long m_sessionId; + uint64_t m_sessionId; + unsigned m_sessionVersion; Vector> m_mediaDescriptions; }; diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index 190f5b58f5578..b3888d6eff987 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -124,6 +124,8 @@ RefPtr fromJSON(const String& json) if (object->getObject(ASCIILiteral("originator"), originatorObject)) { if (originatorObject->getInteger(ASCIILiteral("sessionId"), longValue)) configuration->setSessionId(longValue); + if (originatorObject->getInteger(ASCIILiteral("sessionVersion"), intValue)) + configuration->setSessionVersion(intValue); } RefPtr mediaDescriptionsArray = InspectorArray::create(); @@ -240,7 +242,8 @@ String toJSON(MediaEndpointConfiguration* configuration) RefPtr object = InspectorObject::create(); RefPtr originatorObject = InspectorObject::create(); - originatorObject->setInteger(ASCIILiteral("sessionId"), configuration->sessionId()); + originatorObject->setDouble(ASCIILiteral("sessionId"), configuration->sessionId()); + originatorObject->setInteger(ASCIILiteral("sessionVersion"), configuration->sessionVersion()); object->setObject(ASCIILiteral("originator"), originatorObject); RefPtr mediaDescriptionsArray = InspectorArray::create(); From 370307bd667dbf6a4de90ae3a09b9a82402bbde8 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 23 May 2015 11:18:43 +0200 Subject: [PATCH 088/155] MediaEndpointOwr: Fix bug where related address and port are added to host candidates --- .../platform/mediastream/openwebrtc/MediaEndpointOwr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 047845d212b8a..413d4e4026f61 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -333,7 +333,7 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp iceCandidate->setTcpType(candidateTcpTypes[transportType]); } - if (candidateType == OWR_CANDIDATE_TYPE_HOST) { + if (candidateType != OWR_CANDIDATE_TYPE_HOST) { iceCandidate->setRelatedAddress(relatedAddress); iceCandidate->setRelatedPort(relatedPort); } From cd73260074f88d8ee5bfb54b57c52c035dac09e0 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 23 May 2015 11:21:14 +0200 Subject: [PATCH 089/155] RTCPeerConnection: s/sha256/sha-256/ --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 575b67f672705..992d385a3bedc 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -568,7 +568,7 @@ void RTCPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& ce for (unsigned i = 0; i < fingerprintVector.size(); ++i) fingerprint.append(String::format(i ? ":%02X" : "%02X", fingerprintVector[i])); - m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprintHashFunction("sha256"); + m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprintHashFunction("sha-256"); m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprint(fingerprint.toString()); if (maybeResolveSetLocalDescription() == SetLocalDescriptionResolvedSuccessfully) From 1404b95f4ddc0979341c5689afc41642f061a972 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 23 May 2015 11:34:35 +0200 Subject: [PATCH 090/155] MECConversions: Select which candidate fields to serialize --- .../MediaEndpointConfigurationConversions.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index b3888d6eff987..6a9aa4b6a5458 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -57,9 +57,12 @@ static RefPtr createCandidateObject(IceCandidate* candidate) candidateObject->setInteger(ASCIILiteral("priority"), candidate->priority()); candidateObject->setString(ASCIILiteral("address"), candidate->address()); candidateObject->setInteger(ASCIILiteral("port"), candidate->port()); - candidateObject->setString(ASCIILiteral("tcpType"), candidate->tcpType()); - candidateObject->setString(ASCIILiteral("relatedAddress"), candidate->relatedAddress()); - candidateObject->setInteger(ASCIILiteral("relatedPort"), candidate->relatedPort()); + if (!candidate->tcpType().isEmpty()) + candidateObject->setString(ASCIILiteral("tcpType"), candidate->tcpType()); + if (candidate->type().upper() != "HOST") { + candidateObject->setString(ASCIILiteral("relatedAddress"), candidate->relatedAddress()); + candidateObject->setInteger(ASCIILiteral("relatedPort"), candidate->relatedPort()); + } return candidateObject; } From c2dbe2cbce1aff719d15445d345ed7860e782d39 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 23 May 2015 11:40:47 +0200 Subject: [PATCH 091/155] PeerMediaDescription: Add address, rtcpAddress and rtcpPort --- .../MediaEndpointConfigurationConversions.cpp | 12 ++++++++++++ .../platform/mediastream/PeerMediaDescription.h | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index 6a9aa4b6a5458..ecaab600ce53d 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -146,6 +146,9 @@ RefPtr fromJSON(const String& json) if (mdescObject->getInteger(ASCIILiteral("port"), intValue)) mdesc->setPort(intValue); + if (mdescObject->getString(ASCIILiteral("address"), stringValue)) + mdesc->setAddress(stringValue); + if (mdescObject->getString(ASCIILiteral("mode"), stringValue)) mdesc->setMode(stringValue); @@ -171,6 +174,12 @@ RefPtr fromJSON(const String& json) if (mdescObject->getObject(ASCIILiteral("rtcp"), rtcpObject)) { if (rtcpObject->getBoolean(ASCIILiteral("mux"), boolValue)) mdesc->setRtcpMux(boolValue); + + if (rtcpObject->getString(ASCIILiteral("rtcpAddress"), stringValue)) + mdesc->setRtcpAddress(stringValue); + + if (rtcpObject->getInteger(ASCIILiteral("rtcpPort"), intValue)) + mdesc->setRtcpPort(intValue); } if (mdescObject->getString(ASCIILiteral("mediaStreamId"), stringValue)) @@ -256,6 +265,7 @@ String toJSON(MediaEndpointConfiguration* configuration) mdescObject->setString(ASCIILiteral("type"), mdesc->type()); mdescObject->setInteger(ASCIILiteral("port"), mdesc->port()); + mdescObject->setString(ASCIILiteral("address"), mdesc->address()); mdescObject->setString(ASCIILiteral("mode"), mdesc->mode()); RefPtr payloadsArray = InspectorArray::create(); @@ -272,6 +282,8 @@ String toJSON(MediaEndpointConfiguration* configuration) RefPtr rtcpObject = InspectorObject::create(); rtcpObject->setBoolean(ASCIILiteral("mux"), mdesc->rtcpMux()); + rtcpObject->setString(ASCIILiteral("address"), mdesc->rtcpAddress()); + rtcpObject->setInteger(ASCIILiteral("port"), mdesc->rtcpPort()); mdescObject->setObject(ASCIILiteral("rtcp"), rtcpObject); mdescObject->setString(ASCIILiteral("mediaStreamId"), mdesc->mediaStreamId()); diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index 07525150ac41f..95c7e162d9af9 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -55,6 +55,9 @@ class PeerMediaDescription : public RefCounted { unsigned short port() const { return m_port; } void setPort(unsigned short port) { m_port = port; } + const String& address() const { return m_address; } + void setAddress(const String& address) { m_address = address; } + const String& mode() const { return m_mode; } void setMode(const String& mode) { m_mode = mode; } @@ -64,6 +67,12 @@ class PeerMediaDescription : public RefCounted { bool rtcpMux() const { return m_rtcpMux; } void setRtcpMux(bool rtcpMux) { m_rtcpMux = rtcpMux; } + const String& rtcpAddress() const { return m_rtcpAddress; } + void setRtcpAddress(const String& rtcpAddress) { m_rtcpAddress = rtcpAddress; } + + unsigned short rtcpPort() const { return m_rtcpPort; } + void setRtcpPort(unsigned short rtcpPort) { m_rtcpPort = rtcpPort; } + const String& mediaStreamId() const { return m_mediaStreamId; } void setMediaStreamId(const String& mediaStreamId) { m_mediaStreamId = mediaStreamId; } @@ -110,11 +119,14 @@ class PeerMediaDescription : public RefCounted { String m_type; unsigned short m_port; + String m_address; String m_mode; Vector> m_payloads; bool m_rtcpMux; + String m_rtcpAddress; + unsigned short m_rtcpPort; String m_mediaStreamId; String m_mediaStreamTrackId; From 1c79c09d80d9e2c7a099f2c046a61e6d760fa537 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 23 May 2015 11:45:06 +0200 Subject: [PATCH 092/155] RTCPeerConnection: Populate media description address info (rtp/rtcp) from ice candidates --- .../Modules/mediastream/RTCPeerConnection.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 992d385a3bedc..89abca08da1fd 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -589,7 +589,19 @@ void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtraddress().contains(':')) { // not IPv6 + if (candidate->componentId() == 1) { // RTP + if (mdesc.address().isEmpty() || mdesc.address() == "0.0.0.0") { + mdesc.setAddress(candidate->address()); + mdesc.setPort(candidate->port()); + } + } else { // RTCP + if (mdesc.rtcpAddress().isEmpty() || !mdesc.rtcpPort()) { + mdesc.setRtcpAddress(candidate->address()); + mdesc.setRtcpPort(candidate->port()); + } + } + } ResolveSetLocalDescriptionResult result = maybeResolveSetLocalDescription(); if (result == SetLocalDescriptionResolvedSuccessfully) From 1182c8ec7d00bc7cc76f17d2b842a459a0a71bdb Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Sat, 23 May 2015 11:55:06 +0200 Subject: [PATCH 093/155] MediaEndpointOwr: Handle candidate transport type correctly (tcpType not always present) --- .../mediastream/openwebrtc/MediaEndpointOwr.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 413d4e4026f61..5f7d186953635 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -267,11 +267,19 @@ void MediaEndpointOwr::internalAddRemoteCandidate(OwrSession* session, IceCandid return; ASSERT(candidateTypes.find(candidate.type()) != notFound); - ASSERT(candidateTcpTypes.find(candidate.tcpType()) != notFound); + printf("ASSERT: %d\n", (candidateTypes.find(candidate.type()) != notFound)); OwrCandidateType candidateType = static_cast(candidateTypes.find(candidate.type())); OwrComponentType componentId = static_cast(candidate.componentId()); - OwrTransportType transportType = static_cast(candidateTcpTypes.find(candidate.tcpType())); + OwrTransportType transportType; + + if (candidate.transport().upper() == "UDP") + transportType = OWR_TRANSPORT_TYPE_UDP; + else { + ASSERT(candidateTcpTypes.find(candidate.tcpType()) != notFound); + printf("ASSERT: %d\n", (candidateTcpTypes.find(candidate.tcpType()) != notFound)); + transportType = static_cast(candidateTcpTypes.find(candidate.tcpType())); + } OwrCandidate* owrCandidate = owr_candidate_new(candidateType, componentId); g_object_set(owrCandidate, "transport-type", transportType, From 26e3998f9bf5860453f1a4b8df4252cbcdb714c2 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Tue, 26 May 2015 02:09:41 -0700 Subject: [PATCH 094/155] Add libvpx to the webkitgtk deps --- Tools/gtk/jhbuild.modules | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index 2ee9f45c20362..6e73fc9282b54 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -309,6 +309,7 @@ + @@ -382,6 +383,11 @@ + + + + From 192db2e2d08d202aeefd8a6ac4e1b652763c6aec Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Wed, 27 May 2015 15:15:24 +0200 Subject: [PATCH 095/155] MediaPlayerPrivateGStreamerOwr: remove erroneous source type check The OwrSourceType enum is meant to hint about the origin of the source. In case of remote sources it doesn't make sense to check this. --- .../graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp index 8178bc1800b0e..f7778cacb28c5 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp @@ -186,10 +186,6 @@ bool MediaPlayerPrivateGStreamerOwr::internalLoad() RealtimeMediaSourceOwr* source = reinterpret_cast(track->source()); OwrMediaSource* mediaSource = OWR_MEDIA_SOURCE(source->mediaSource()); - OwrSourceType sourceType; - g_object_get(mediaSource, "type", &sourceType, nullptr); - if ((sourceType & OWR_SOURCE_TYPE_CAPTURE) != OWR_SOURCE_TYPE_CAPTURE) - continue; if (track->type() == RealtimeMediaSource::Audio) { if (m_audioSource && (m_audioSource.get() == source)) From d1f29a124622ed3a0de72c08af38c9af73758f0d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 13:54:03 +0200 Subject: [PATCH 096/155] RTCTrackEvent: initial implementation (replaces MediaStreamEvent) --- Source/WebCore/CMakeLists.txt | 4 +- .../Modules/mediastream/MediaStreamEvent.cpp | 88 ------------------- .../Modules/mediastream/MediaStreamEvent.h | 66 -------------- .../Modules/mediastream/MediaStreamEvent.idl | 31 ------- .../Modules/mediastream/RTCPeerConnection.idl | 3 +- .../Modules/mediastream/RTCTrackEvent.cpp | 88 +++++++++++++++++++ .../Modules/mediastream/RTCTrackEvent.h | 78 ++++++++++++++++ .../Modules/mediastream/RTCTrackEvent.idl | 38 ++++++++ Source/WebCore/bindings/js/JSDictionary.cpp | 6 ++ Source/WebCore/bindings/js/JSDictionary.h | 2 + Source/WebCore/dom/EventNames.h | 3 +- Source/WebCore/dom/EventNames.in | 2 +- 12 files changed, 217 insertions(+), 192 deletions(-) delete mode 100644 Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp delete mode 100644 Source/WebCore/Modules/mediastream/MediaStreamEvent.h delete mode 100644 Source/WebCore/Modules/mediastream/MediaStreamEvent.idl create mode 100644 Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp create mode 100644 Source/WebCore/Modules/mediastream/RTCTrackEvent.h create mode 100644 Source/WebCore/Modules/mediastream/RTCTrackEvent.idl diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index b5c782fd1014d..eb9be998ec14d 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -229,7 +229,6 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/MediaSourceStates.idl Modules/mediastream/MediaStream.idl Modules/mediastream/MediaStreamCapabilities.idl - Modules/mediastream/MediaStreamEvent.idl Modules/mediastream/MediaStreamTrack.idl Modules/mediastream/MediaStreamTrackEvent.idl Modules/mediastream/MediaStreamTrackSourcesCallback.idl @@ -258,6 +257,7 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/RTCStatsCallback.idl Modules/mediastream/RTCStatsReport.idl Modules/mediastream/RTCStatsResponse.idl + Modules/mediastream/RTCTrackEvent.idl Modules/mediastream/SourceInfo.idl Modules/navigatorcontentutils/NavigatorContentUtils.idl @@ -882,7 +882,6 @@ set(WebCore_SOURCES Modules/mediastream/MediaSourceStates.cpp Modules/mediastream/MediaStream.cpp Modules/mediastream/MediaStreamCapabilities.cpp - Modules/mediastream/MediaStreamEvent.cpp Modules/mediastream/MediaStreamRegistry.cpp Modules/mediastream/MediaStreamTrack.cpp Modules/mediastream/MediaStreamTrackEvent.cpp @@ -910,6 +909,7 @@ set(WebCore_SOURCES Modules/mediastream/RTCStatsReport.cpp Modules/mediastream/RTCStatsRequestImpl.cpp Modules/mediastream/RTCStatsResponse.cpp + Modules/mediastream/RTCTrackEvent.cpp Modules/mediastream/RTCVoidRequestImpl.cpp Modules/mediastream/SourceInfo.cpp Modules/mediastream/UserMediaController.cpp diff --git a/Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp b/Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp deleted file mode 100644 index cbc0246e0ee18..0000000000000 --- a/Source/WebCore/Modules/mediastream/MediaStreamEvent.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * 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 "MediaStreamEvent.h" - -#if ENABLE(MEDIA_STREAM) - -#include "EventNames.h" -#include "MediaStream.h" - -namespace WebCore { - -MediaStreamEventInit::MediaStreamEventInit() - : stream(0) -{ -} - -Ref MediaStreamEvent::create() -{ - return adoptRef(*new MediaStreamEvent); -} - -Ref MediaStreamEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr stream) -{ - return adoptRef(*new MediaStreamEvent(type, canBubble, cancelable, stream)); -} - -Ref MediaStreamEvent::create(const AtomicString& type, const MediaStreamEventInit& initializer) -{ - return adoptRef(*new MediaStreamEvent(type, initializer)); -} - -MediaStreamEvent::MediaStreamEvent() -{ -} - -MediaStreamEvent::MediaStreamEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr stream) - : Event(type, canBubble, cancelable) - , m_stream(stream) -{ -} - -MediaStreamEvent::MediaStreamEvent(const AtomicString& type, const MediaStreamEventInit& initializer) - : Event(type, initializer) - , m_stream(initializer.stream) -{ -} - -MediaStreamEvent::~MediaStreamEvent() -{ -} - -MediaStream* MediaStreamEvent::stream() const -{ - return m_stream.get(); -} - -EventInterface MediaStreamEvent::eventInterface() const -{ - return MediaStreamEventInterfaceType; -} - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) - diff --git a/Source/WebCore/Modules/mediastream/MediaStreamEvent.h b/Source/WebCore/Modules/mediastream/MediaStreamEvent.h deleted file mode 100644 index b61520e526eb7..0000000000000 --- a/Source/WebCore/Modules/mediastream/MediaStreamEvent.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * 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. - */ - -#ifndef MediaStreamEvent_h -#define MediaStreamEvent_h - -#if ENABLE(MEDIA_STREAM) - -#include "Event.h" -#include "MediaStream.h" -#include - -namespace WebCore { - -struct MediaStreamEventInit : public EventInit { - MediaStreamEventInit(); - - RefPtr stream; -}; - -class MediaStreamEvent : public Event { -public: - virtual ~MediaStreamEvent(); - - static Ref create(); - static Ref create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr); - static Ref create(const AtomicString& type, const MediaStreamEventInit& initializer); - - MediaStream* stream() const; - - virtual EventInterface eventInterface() const; - -private: - MediaStreamEvent(); - MediaStreamEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr); - MediaStreamEvent(const AtomicString& type, const MediaStreamEventInit&); - - RefPtr m_stream; -}; - -} // namespace WebCore - -#endif // ENABLE(MEDIA_STREAM) - -#endif // MediaStreamEvent_h diff --git a/Source/WebCore/Modules/mediastream/MediaStreamEvent.idl b/Source/WebCore/Modules/mediastream/MediaStreamEvent.idl deleted file mode 100644 index b44729ca3cbd1..0000000000000 --- a/Source/WebCore/Modules/mediastream/MediaStreamEvent.idl +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * 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. - */ - -[ - Conditional=MEDIA_STREAM, - ConstructorTemplate=Event -] interface MediaStreamEvent : Event { - [InitializedByEventConstructor] readonly attribute MediaStream stream; -}; - diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl index 562b5942927c4..0394126c89065 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.idl @@ -73,8 +73,7 @@ attribute EventHandler onnegotiationneeded; attribute EventHandler onicecandidate; attribute EventHandler onsignalingstatechange; - attribute EventHandler onaddstream; - attribute EventHandler onremovestream; + attribute EventHandler ontrack; attribute EventHandler oniceconnectionstatechange; attribute EventHandler ondatachannel; diff --git a/Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp b/Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp new file mode 100644 index 0000000000000..ce611ad29b2d9 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCTrackEvent.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "RTCTrackEvent.h" + +#if ENABLE(MEDIA_STREAM) + +#include "EventNames.h" +#include "MediaStreamTrack.h" +#include "RTCRtpReceiver.h" + +namespace WebCore { + +RTCTrackEventInit::RTCTrackEventInit() + : receiver(nullptr) + , track(nullptr) +{ +} + +Ref RTCTrackEvent::create() +{ + return adoptRef(*new RTCTrackEvent); +} + +Ref RTCTrackEvent::create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr&& receiver, RefPtr&& track) +{ + return adoptRef(*new RTCTrackEvent(type, canBubble, cancelable, WTF::move(receiver), WTF::move(track))); +} + +Ref RTCTrackEvent::create(const AtomicString& type, const RTCTrackEventInit& initializer) +{ + return adoptRef(*new RTCTrackEvent(type, initializer)); +} + +RTCTrackEvent::RTCTrackEvent() +{ +} + +RTCTrackEvent::RTCTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr&& receiver, RefPtr&& track) + : Event(type, canBubble, cancelable) + , m_receiver(receiver) + , m_track(track) +{ +} + +RTCTrackEvent::RTCTrackEvent(const AtomicString& type, const RTCTrackEventInit& initializer) + : Event(type, initializer) + , m_receiver(initializer.receiver) + , m_track(initializer.track) +{ +} + +RTCTrackEvent::~RTCTrackEvent() +{ +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + diff --git a/Source/WebCore/Modules/mediastream/RTCTrackEvent.h b/Source/WebCore/Modules/mediastream/RTCTrackEvent.h new file mode 100644 index 0000000000000..b83e42056a0aa --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCTrackEvent.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef RTCTrackEvent_h +#define RTCTrackEvent_h + +#if ENABLE(MEDIA_STREAM) + +#include "Event.h" +// #include "MediaStreamTrack.h" +#include + +namespace WebCore { + +class MediaStreamTrack; +class RTCRtpReceiver; + +struct RTCTrackEventInit : public EventInit { + RTCTrackEventInit(); + + RefPtr receiver; + RefPtr track; +}; + +class RTCTrackEvent : public Event { +public: + virtual ~RTCTrackEvent(); + + static Ref create(); + static Ref create(const AtomicString& type, bool canBubble, bool cancelable, RefPtr&&, RefPtr&&); + static Ref create(const AtomicString& type, const RTCTrackEventInit&); + + RTCRtpReceiver* receiver() const { return m_receiver.get(); } + MediaStreamTrack* track() const { return m_track.get(); } + + virtual EventInterface eventInterface() const { return RTCTrackEventInterfaceType; } + +private: + RTCTrackEvent(); + RTCTrackEvent(const AtomicString& type, bool canBubble, bool cancelable, RefPtr&&, RefPtr&&); + RTCTrackEvent(const AtomicString& type, const RTCTrackEventInit&); + + RefPtr m_receiver; + RefPtr m_track; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // RTCTrackEvent_h diff --git a/Source/WebCore/Modules/mediastream/RTCTrackEvent.idl b/Source/WebCore/Modules/mediastream/RTCTrackEvent.idl new file mode 100644 index 0000000000000..c8cbe00188b6e --- /dev/null +++ b/Source/WebCore/Modules/mediastream/RTCTrackEvent.idl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +[ + Conditional=MEDIA_STREAM, + ConstructorTemplate=Event +] interface RTCTrackEvent : Event { + [InitializedByEventConstructor] readonly attribute RTCRtpReceiver receiver; + [InitializedByEventConstructor] readonly attribute MediaStreamTrack track; +}; + diff --git a/Source/WebCore/bindings/js/JSDictionary.cpp b/Source/WebCore/bindings/js/JSDictionary.cpp index e984909e76b25..908106e24528d 100644 --- a/Source/WebCore/bindings/js/JSDictionary.cpp +++ b/Source/WebCore/bindings/js/JSDictionary.cpp @@ -50,6 +50,7 @@ #if ENABLE(MEDIA_STREAM) #include "JSMediaStream.h" #include "JSMediaStreamTrack.h" +#include "JSRTCRtpReceiver.h" #endif #if ENABLE(GAMEPAD) @@ -236,6 +237,11 @@ void JSDictionary::convertValue(JSC::ExecState*, JSC::JSValue value, RefPtr& result) +{ + result = JSRTCRtpReceiver::toWrapped(value); +} #endif #if ENABLE(FONT_LOAD_EVENTS) diff --git a/Source/WebCore/bindings/js/JSDictionary.h b/Source/WebCore/bindings/js/JSDictionary.h index e902f9a6ac6ac..0417745e93ad7 100644 --- a/Source/WebCore/bindings/js/JSDictionary.h +++ b/Source/WebCore/bindings/js/JSDictionary.h @@ -50,6 +50,7 @@ class Gamepad; class MediaKeyError; class MediaStream; class MediaStreamTrack; +class RTCRtpReceiver; class Node; class SerializedScriptValue; class Storage; @@ -128,6 +129,7 @@ class JSDictionary { #if ENABLE(MEDIA_STREAM) static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr& result); static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr& result); + static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr& result); #endif #if ENABLE(FONT_LOAD_EVENTS) static void convertValue(JSC::ExecState*, JSC::JSValue, RefPtr& result); diff --git a/Source/WebCore/dom/EventNames.h b/Source/WebCore/dom/EventNames.h index 0c4b3428923ea..7f468dfef8875 100644 --- a/Source/WebCore/dom/EventNames.h +++ b/Source/WebCore/dom/EventNames.h @@ -43,7 +43,6 @@ namespace WebCore { macro(abort) \ macro(active) \ macro(addsourcebuffer) \ - macro(addstream) \ macro(addtrack) \ macro(animationend) \ macro(animationiteration) \ @@ -164,7 +163,6 @@ namespace WebCore { macro(ratechange) \ macro(readystatechange) \ macro(removesourcebuffer) \ - macro(removestream) \ macro(removetrack) \ macro(reset) \ macro(resize) \ @@ -203,6 +201,7 @@ namespace WebCore { macro(touchend) \ macro(touchmove) \ macro(touchstart) \ + macro(track) \ macro(transitionend) \ macro(unload) \ macro(unmute) \ diff --git a/Source/WebCore/dom/EventNames.in b/Source/WebCore/dom/EventNames.in index c74f685877644..28b164c4ba126 100644 --- a/Source/WebCore/dom/EventNames.in +++ b/Source/WebCore/dom/EventNames.in @@ -33,11 +33,11 @@ WheelEvent XMLHttpRequestProgressEvent AudioProcessingEvent conditional=WEB_AUDIO OfflineAudioCompletionEvent conditional=WEB_AUDIO -MediaStreamEvent conditional=MEDIA_STREAM MediaStreamTrackEvent conditional=MEDIA_STREAM RTCIceCandidateEvent conditional=MEDIA_STREAM RTCDataChannelEvent conditional=MEDIA_STREAM RTCDTMFToneChangeEvent conditional=MEDIA_STREAM +RTCTrackEvent conditional=MEDIA_STREAM SpeechSynthesisEvent conditional=SPEECH_SYNTHESIS WebGLContextEvent conditional=WEBGL StorageEvent From 8d71993742ac4a21b84020908d8fefde40a7a941 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 14:09:02 +0200 Subject: [PATCH 097/155] RealtimeMediaSourceCenterOwr: Added basic source name hints via environment variables --- .../RealtimeMediaSourceCenterOwr.cpp | 28 +++++++++++++++---- .../openwebrtc/RealtimeMediaSourceCenterOwr.h | 5 +++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp index b8187bf67a9b7..e110c79dc258d 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp @@ -72,6 +72,15 @@ static void mediaSourcesAvailableCallback(GList* sources, gpointer userData) RealtimeMediaSourceCenterOwr::RealtimeMediaSourceCenterOwr() { initializeOpenWebRTC(); + + // Temporary solution to hint about preferred device names. + char* preferredSourceName = getenv("WEBKIT_AUDIO_SOURCE_NAME"); + if (preferredSourceName) + m_preferredAudioSourceName = String(preferredSourceName); + + preferredSourceName = getenv("WEBKIT_VIDEO_SOURCE_NAME"); + if (preferredSourceName) + m_preferredVideoSourceName = String(preferredSourceName); } RealtimeMediaSourceCenterOwr::~RealtimeMediaSourceCenterOwr() @@ -112,7 +121,7 @@ void RealtimeMediaSourceCenterOwr::createMediaStream(PassRefPtr audioSource = firstSource(RealtimeMediaSource::Audio); + RefPtr audioSource = selectSource(RealtimeMediaSource::Audio); if (audioSource) { audioSource->reset(); audioSources.append(audioSource.release()); @@ -122,7 +131,7 @@ void RealtimeMediaSourceCenterOwr::createMediaStream(PassRefPtr videoSource = firstSource(RealtimeMediaSource::Video); + RefPtr videoSource = selectSource(RealtimeMediaSource::Video); if (videoSource) { videoSource->reset(); videoSources.append(videoSource.release()); @@ -168,15 +177,22 @@ void RealtimeMediaSourceCenterOwr::mediaSourcesAvailable(GList* sources) m_client->constraintsValidated(); } -PassRefPtr RealtimeMediaSourceCenterOwr::firstSource(RealtimeMediaSource::Type type) +PassRefPtr RealtimeMediaSourceCenterOwr::selectSource(RealtimeMediaSource::Type type) { + RefPtr selectedSource = nullptr; + const String& preferredSourceName = type == RealtimeMediaSource::Audio ? m_preferredAudioSourceName : m_preferredVideoSourceName; + for (auto iter = m_sourceMap.begin(); iter != m_sourceMap.end(); ++iter) { RefPtr source = iter->value; - if (source->type() == type) - return source; + bool foundPreferred = source->name() == preferredSourceName; + if (source->type() == type && (!selectedSource || foundPreferred)) { + selectedSource = source; + if (foundPreferred) + break; + } } - return nullptr; + return selectedSource; } } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h index 65d9e64b69ae0..78e5147b05294 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h @@ -59,9 +59,12 @@ class RealtimeMediaSourceCenterOwr final : public RealtimeMediaSourceCenter { void mediaSourcesAvailable(GList* sources); private: - PassRefPtr firstSource(RealtimeMediaSource::Type); + PassRefPtr selectSource(RealtimeMediaSource::Type); RealtimeMediaSourceOwrMap m_sourceMap; RefPtr m_client; + + String m_preferredAudioSourceName; + String m_preferredVideoSourceName; }; } // namespace WebCore From 6929236862fc01fd9ea9058f10a84de265b40a13 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 14:27:33 +0200 Subject: [PATCH 098/155] MediaPayload: Add remaining properties (with JSON conversions) --- .../MediaEndpointConfigurationConversions.cpp | 41 +++++++++++++++++++ .../platform/mediastream/MediaPayload.h | 32 +++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp index ecaab600ce53d..f36f893067ae8 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp +++ b/Source/WebCore/platform/mediastream/MediaEndpointConfigurationConversions.cpp @@ -167,6 +167,33 @@ RefPtr fromJSON(const String& json) if (payloadsObject->getString(ASCIILiteral("encodingName"), stringValue)) payload->setEncodingName(stringValue); + if (payloadsObject->getInteger(ASCIILiteral("clockRate"), intValue)) + payload->setClockRate(intValue); + + if (payloadsObject->getInteger(ASCIILiteral("channels"), intValue)) + payload->setChannels(intValue); + + if (payloadsObject->getBoolean(ASCIILiteral("ccmfir"), boolValue)) + payload->setCcmfir(boolValue); + + if (payloadsObject->getBoolean(ASCIILiteral("nackpli"), boolValue)) + payload->setNackpli(boolValue); + + if (payloadsObject->getBoolean(ASCIILiteral("nack"), boolValue)) + payload->setNack(boolValue); + + RefPtr parametersObject = InspectorObject::create(); + if (payloadsObject->getObject(ASCIILiteral("parameters"), parametersObject)) { + if (parametersObject->getInteger(ASCIILiteral("packetizationMode"), intValue)) + payload->addParameter("packetizationMode", intValue); + + if (parametersObject->getInteger(ASCIILiteral("apt"), intValue)) + payload->addParameter("apt", intValue); + + if (parametersObject->getInteger(ASCIILiteral("rtxTime"), intValue)) + payload->addParameter("rtxTime", intValue); + } + mdesc->addPayload(WTF::move(payload)); } @@ -275,6 +302,20 @@ String toJSON(MediaEndpointConfiguration* configuration) payloadObject->setInteger(ASCIILiteral("type"), payload->type()); payloadObject->setString(ASCIILiteral("encodingName"), payload->encodingName()); + payloadObject->setInteger(ASCIILiteral("clockRate"), payload->clockRate()); + payloadObject->setInteger(ASCIILiteral("channels"), payload->channels()); + payloadObject->setBoolean(ASCIILiteral("ccmfir"), payload->ccmfir()); + payloadObject->setBoolean(ASCIILiteral("nackpli"), payload->nackpli()); + payloadObject->setBoolean(ASCIILiteral("nack"), payload->nack()); + + if (!payload->parameters().isEmpty()) { + RefPtr parametersObject = InspectorObject::create(); + + for (auto& name : payload->parameters().keys()) + parametersObject->setInteger(name, payload->parameters().get(name)); + + payloadObject->setObject(ASCIILiteral("parameters"), parametersObject); + } payloadsArray->pushObject(payloadObject); } diff --git a/Source/WebCore/platform/mediastream/MediaPayload.h b/Source/WebCore/platform/mediastream/MediaPayload.h index 55e8c263ccbe0..32f615509be56 100644 --- a/Source/WebCore/platform/mediastream/MediaPayload.h +++ b/Source/WebCore/platform/mediastream/MediaPayload.h @@ -33,8 +33,10 @@ #if ENABLE(MEDIA_STREAM) +#include #include #include +#include namespace WebCore { @@ -53,16 +55,46 @@ class MediaPayload : public RefCounted { void setEncodingName(const String & encodingName) { m_encodingName = encodingName; } unsigned clockRate() const { return m_clockRate; } + void setClockRate(unsigned clockRate) { m_clockRate = clockRate; } + + unsigned channels() const { return m_channels; } + void setChannels(unsigned channels) { m_channels = channels; } + + bool ccmfir() const { return m_ccmfir; } + void setCcmfir(bool ccmfir) { m_ccmfir = ccmfir; } + + bool nackpli() const { return m_nackpli; } + void setNackpli(bool nackpli) { m_nackpli = nackpli; } + + bool nack() const { return m_nack; } + void setNack(bool nack) { m_nack = nack; } + + const HashMap& parameters() const { return m_parameters; } + void addParameter(const String& name, unsigned value) { m_parameters.set(name, value); } private: MediaPayload() : m_type(0) , m_clockRate(0) + , m_channels(0) + , m_ccmfir(false) + , m_nackpli(false) + , m_nack(false) { } unsigned m_type; String m_encodingName; unsigned m_clockRate; + + // audio + unsigned m_channels; + + // video + bool m_ccmfir; + bool m_nackpli; + bool m_nack; + + HashMap m_parameters; }; } // namespace WebCore From b86eddbd041cfb1cc5c1948c729c09616c639571 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 15:30:36 +0200 Subject: [PATCH 099/155] MediaEndpointOwr: Use default port 9 on candidates --- .../platform/mediastream/openwebrtc/MediaEndpointOwr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 5f7d186953635..80ad0401d9d48 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -332,7 +332,7 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp iceCandidate->setComponentId(componentId); iceCandidate->setPriority(priority); iceCandidate->setAddress(address); - iceCandidate->setPort(port); + iceCandidate->setPort(port ? port : 9); if (transportType == OWR_TRANSPORT_TYPE_UDP) iceCandidate->setTransport("UDP"); @@ -343,7 +343,7 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp if (candidateType != OWR_CANDIDATE_TYPE_HOST) { iceCandidate->setRelatedAddress(relatedAddress); - iceCandidate->setRelatedPort(relatedPort); + iceCandidate->setRelatedPort(relatedPort ? relatedPort : 9); } mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->sessionIndex(session), WTF::move(iceCandidate), String(ufrag), String(password)); From b443d60e7602f507eeb10911bfb0528c34dc9c27 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 15:40:27 +0200 Subject: [PATCH 100/155] RTCPeerConnection: verify setLocalDescription() input --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 89abca08da1fd..aee40ff0e90c4 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -317,6 +317,15 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, m_localConfiguration = MediaEndpointConfigurationConversions::fromJSON(description->sdp()); m_localConfigurationType = description->type(); + if (!m_localConfiguration) { + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); + rejectCallback(error.get()); + }); + return; + } + bool hasNewMediaDescriptions = m_localConfiguration->mediaDescriptions().size() > previousNumberOfMediaDescriptions; bool isInitiator = descriptionType == DescriptionTypeOffer; From d0004197fe6f3c1f9edbd1f86e361905668d685f Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 15:43:14 +0200 Subject: [PATCH 101/155] RTCPeerConnection: Disable trickle (enable later) --- Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index aee40ff0e90c4..65e480db47336 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -629,6 +629,8 @@ void RTCPeerConnection::doneGatheringCandidates(unsigned mdescIndex) ASSERT(scriptExecutionContext()->isContextThread()); m_localConfiguration->mediaDescriptions()[mdescIndex]->setIceCandidateGatheringDone(true); + // Test: No trickle + maybeResolveSetLocalDescription(); maybeDispatchGatheringDone(); } @@ -690,6 +692,9 @@ bool RTCPeerConnection::isLocalConfigurationComplete() const for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { if (mdesc->dtlsFingerprint().isEmpty() || mdesc->iceUfrag().isEmpty()) return false; + // Test: No trickle + if (!mdesc->iceCandidateGatheringDone()) + return false; if (mdesc->type() == "audio" || mdesc->type() == "video") { if (!mdesc->ssrcs().size() || mdesc->cname().isEmpty()) return false; From a79d710f85eb4a093ce3be30117e04edcbecfd8c Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 15:50:03 +0200 Subject: [PATCH 102/155] RTCPeerConnection/MediaEndpointOwr: Fix payload handling --- .../Modules/mediastream/RTCPeerConnection.cpp | 66 ++++++++++++- .../mediastream/PeerMediaDescription.h | 2 + .../openwebrtc/MediaEndpointOwr.cpp | 93 +++++++++++-------- 3 files changed, 118 insertions(+), 43 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 65e480db47336..c89b81e08dcc4 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -215,6 +215,64 @@ static void updateMediaDescriptionsWithSenders(const Vector> createDefaultPayloads(const String& type) +{ + Vector> payloads; + RefPtr payload; + + if (type == "audio") { + payload = MediaPayload::create(); + payload->setType(111); + payload->setEncodingName("OPUS"); + payload->setClockRate(48000); + payload->setChannels(2); + payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(8); + payload->setEncodingName("PCMA"); + payload->setClockRate(8000); + payload->setChannels(1); + payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(0); + payload->setEncodingName("PCMU"); + payload->setClockRate(8000); + payload->setChannels(1); + payloads.append(payload); + } else { + payload = MediaPayload::create(); + payload->setType(103); + payload->setEncodingName("H264"); + payload->setClockRate(90000); + payload->setCcmfir(true); + payload->setNackpli(true); + payload->addParameter("packetizationMode", 1); + payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(100); + payload->setEncodingName("VP8"); + payload->setClockRate(90000); + payload->setCcmfir(true); + payload->setNackpli(true); + payload->setNack(true); + payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(120); + payload->setEncodingName("RTX"); + payload->setClockRate(90000); + payload->addParameter("apt", 100); + payload->addParameter("rtxTime", 200); + payloads.append(payload); + } + + return payloads; +} + void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { @@ -249,7 +307,7 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR mediaDescription->setMediaStreamTrackId(track->id()); mediaDescription->setType(track->kind()); mediaDescription->setMode("sendrecv"); - // FIXME: payloads + mediaDescription->setPayloads(createDefaultPayloads(track->kind())); mediaDescription->setRtcpMux(true); mediaDescription->setDtlsSetup("actpass"); @@ -258,12 +316,12 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR int extraMediaDescriptionCount = options->offerToReceiveAudio() + options->offerToReceiveVideo(); for (int i = 0; i < extraMediaDescriptionCount; ++i) { - bool audioType = i < options->offerToReceiveAudio(); + String type = i < options->offerToReceiveAudio() ? "audio" : "video"; RefPtr mediaDescription = PeerMediaDescription::create(); - mediaDescription->setType(audioType ? "audio" : "video"); + mediaDescription->setType(type); mediaDescription->setMode("recvonly"); - // FIXME: payloads + mediaDescription->setPayloads(createDefaultPayloads(type)); mediaDescription->setRtcpMux(true); mediaDescription->setDtlsSetup("actpass"); diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index 95c7e162d9af9..45ccad15105d4 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -63,6 +63,8 @@ class PeerMediaDescription : public RefCounted { const Vector>& payloads() const { return m_payloads; } void addPayload(RefPtr&& payload) { m_payloads.append(WTF::move(payload)); } + void setPayloads(Vector>&& payloads) { m_payloads = payloads; } + void setPayloads(const Vector>& payloads) { m_payloads = payloads; } bool rtcpMux() const { return m_rtcpMux; } void setRtcpMux(bool rtcpMux) { m_rtcpMux = rtcpMux; } diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index 80ad0401d9d48..b41f7ce80da9e 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -51,6 +51,7 @@ static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOw static const Vector candidateTypes = { "host", "srflx", "prflx", "relay" }; static const Vector candidateTcpTypes = { "", "active", "passive", "so" }; +static const Vector codecTypes = { "NONE", "PCMU", "PCMA", "OPUS", "H264", "VP8" }; static std::unique_ptr createMediaEndpointOwr(MediaEndpointClient* client) { @@ -100,6 +101,16 @@ void MediaEndpointOwr::prepareToReceive(MediaEndpointConfiguration* configuratio m_numberOfReceivePreparedSessions = m_sessions.size(); } +static RefPtr findRtxPayload(Vector> payloads, unsigned apt) +{ + for (auto& payload : payloads) { + if (payload->encodingName().upper() == "RTX" && payload->parameters().contains("apt") + && (payload->parameters().get("apt") == apt)) + return payload; + } + return nullptr; +} + void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration* configuration, bool isInitiator) { Vector sessionConfigs; @@ -133,26 +144,32 @@ void MediaEndpointOwr::prepareToSend(MediaEndpointConfiguration* configuration, if (!mdesc.source()) continue; - OwrPayload* sendPayload; + MediaPayload* payload = nullptr; + for (auto& p : mdesc.payloads()) { + if (p->encodingName().upper() != "RTX") { + payload = p.get(); + break; + } + } + + if (!payload) { + printf("prepareToSend: no payloads\n"); + return; + } + + RefPtr rtxPayload = findRtxPayload(mdesc.payloads(), payload->type()); RealtimeMediaSourceOwr* source = static_cast(mdesc.source()); - if (mdesc.type() == "audio") { - // { "encodingName": "OPUS", "type": 111, "clockRate": 48000, "channels": 2 }, - OwrCodecType codecType = OWR_CODEC_TYPE_OPUS; - gint64 payloadType = 111; - gint64 clockRate = 48000; - gint64 channels = 2; - - sendPayload = owr_audio_payload_new(codecType, payloadType, clockRate, channels); - } else { - // { "encodingName": "VP8", "type": 100, "clockRate": 90000, "ccmfir": true, "nackpli": true, "nack": true } - OwrCodecType codecType = OWR_CODEC_TYPE_VP8; - gint64 payloadType = 100; - gint64 clockRate = 90000; - gboolean ccmfir = true; - gboolean nackpli = true; - - sendPayload = owr_video_payload_new(codecType, payloadType, clockRate, ccmfir, nackpli); + ASSERT(codecTypes.find(payload->encodingName().upper()) != notFound); + OwrCodecType codecType = static_cast(codecTypes.find(payload->encodingName().upper())); + + OwrPayload* sendPayload; + if (mdesc.type() == "audio") + sendPayload = owr_audio_payload_new(codecType, payload->type(), payload->clockRate(), payload->channels()); + else { + sendPayload = owr_video_payload_new(codecType, payload->type(), payload->clockRate(), payload->ccmfir(), payload->nackpli()); + g_object_set(sendPayload, "rtx-payload-type", rtxPayload ? rtxPayload->type() : -1, + "rtx-time", rtxPayload && rtxPayload->parameters().contains("rtxTime") ? rtxPayload->parameters().get("rtxTime") : 0, nullptr); } owr_media_session_set_send_payload(OWR_MEDIA_SESSION(session), sendPayload); @@ -216,28 +233,26 @@ void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMe g_signal_connect(mediaSession, "notify::send-ssrc", G_CALLBACK(gotSendSsrc), this); g_signal_connect(mediaSession, "on-incoming-source", G_CALLBACK(gotIncomingSource), this); - OwrPayload* receivePayload; - - if (mediaDescription->type() == "audio") { - // { "encodingName": "OPUS", "type": 111, "clockRate": 48000, "channels": 2 }, - OwrCodecType codecType = OWR_CODEC_TYPE_OPUS; - gint64 payloadType = 111; - gint64 clockRate = 48000; - gint64 channels = 2; - - receivePayload = owr_audio_payload_new(codecType, payloadType, clockRate, channels); - } else { - // { "encodingName": "VP8", "type": 100, "clockRate": 90000, "ccmfir": true, "nackpli": true, "nack": true } - OwrCodecType codecType = OWR_CODEC_TYPE_VP8; - gint64 payloadType = 100; - gint64 clockRate = 90000; - gboolean ccmfir = true; - gboolean nackpli = true; - - receivePayload = owr_video_payload_new(codecType, payloadType, clockRate, ccmfir, nackpli); - } + for (auto& payload : mediaDescription->payloads()) { + if (payload->encodingName().upper() == "RTX") + continue; + + RefPtr rtxPayload = findRtxPayload(mediaDescription->payloads(), payload->type()); - owr_media_session_add_receive_payload(mediaSession, receivePayload); + ASSERT(codecTypes.find(payload->encodingName()) != notFound); + OwrCodecType codecType = static_cast(codecTypes.find(payload->encodingName())); + + OwrPayload* receivePayload; + if (mediaDescription->type() == "audio") + receivePayload = owr_audio_payload_new(codecType, payload->type(), payload->clockRate(), payload->channels()); + else { + receivePayload = owr_video_payload_new(codecType, payload->type(), payload->clockRate(), payload->ccmfir(), payload->nackpli()); + g_object_set(receivePayload, "rtx-payload-type", rtxPayload ? rtxPayload->type() : -1, + "rtx-time", rtxPayload && rtxPayload->parameters().contains("rtxTime") ? rtxPayload->parameters().get("rtxTime") : 0, nullptr); + } + + owr_media_session_add_receive_payload(mediaSession, receivePayload); + } } void MediaEndpointOwr::ensureTransportAgentAndSessions(bool isInitiator, const Vector& sessionConfigs) From 27aec380e2ffa67462df0ce30782c2c3d7b87c3a Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 15:54:14 +0200 Subject: [PATCH 103/155] RTCPeerConnection: Implement createAnswer() and setRemoteDescription() --- .../Modules/mediastream/RTCPeerConnection.cpp | 104 +++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index c89b81e08dcc4..8b4c877631912 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -332,7 +332,7 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR resolveCallback(WTF::move(offer)); } -void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) +void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { ec = INVALID_STATE_ERR; @@ -348,7 +348,51 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe return; } - // TODO + if (!m_remoteConfiguration) { + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidStateError (no remote description)"); + rejectCallback(error.get()); + }); + return; + } + + RefPtr configurationSnapshot = m_localConfiguration ? + MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); + + for (unsigned i = 0; i < m_remoteConfiguration->mediaDescriptions().size(); ++i) { + RefPtr remoteMediaDescription = m_remoteConfiguration->mediaDescriptions()[i]; + RefPtr localMediaDescription; + + if (i < configurationSnapshot->mediaDescriptions().size()) + localMediaDescription = configurationSnapshot->mediaDescriptions()[i]; + else { + localMediaDescription = PeerMediaDescription::create(); + localMediaDescription->setType(remoteMediaDescription->type()); + localMediaDescription->setDtlsSetup(remoteMediaDescription->dtlsSetup() == "active" ? "passive" : "active"); + + configurationSnapshot->addMediaDescription(localMediaDescription.copyRef()); + } + + localMediaDescription->setPayloads(remoteMediaDescription->payloads()); + + localMediaDescription->setRtcpMux(remoteMediaDescription->rtcpMux()); + + if (localMediaDescription->dtlsSetup() == "actpass") + localMediaDescription->setDtlsSetup("passive"); + } + + Vector senders; + for (auto& sender : m_senderSet.values()) + senders.append(sender.get()); + + updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); + + RefPtr answer = RTCSessionDescription::create("answer", MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get())); + + callOnMainThread([resolveCallback, answer] { + resolveCallback(answer); + }); } void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) @@ -408,6 +452,32 @@ RefPtr RTCPeerConnection::localDescription() const return RTCSessionDescription::create(m_localConfigurationType, MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())); } +static Vector> filterPayloads(const Vector>& remotePayloads, const String& type) +{ + Vector> defaultPayloads = createDefaultPayloads(type); + Vector> filteredPayloads; + + for (auto& remotePayload : remotePayloads) { + MediaPayload* defaultPayload = nullptr; + for (auto& p : defaultPayloads) { + if (p->encodingName() == remotePayload->encodingName().upper()) { + defaultPayload = p.get(); + break; + } + } + if (!defaultPayload) + continue; + + if (defaultPayload->parameters().contains("packetizationMode") && remotePayload->parameters().contains("packetizationMode") + && (defaultPayload->parameters().get("packetizationMode") != defaultPayload->parameters().get("packetizationMode"))) + continue; + + filteredPayloads.append(remotePayload); + } + + return filteredPayloads; +} + void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) { if (m_signalingState == SignalingStateClosed) { @@ -427,6 +497,36 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, return; } + m_remoteConfiguration = MediaEndpointConfigurationConversions::fromJSON(description->sdp()); + m_remoteConfigurationType = description->type(); + + if (!m_remoteConfiguration) { + callOnMainThread([rejectCallback] { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); + rejectCallback(error.get()); + }); + return; + } + + Vector senders; + for (auto& sender : m_senderSet.values()) + senders.append(sender.get()); + + for (auto& mediaDescription : m_remoteConfiguration->mediaDescriptions()) { + if (mediaDescription->type() != "audio" && mediaDescription->type() != "video") + continue; + + mediaDescription->setPayloads(filterPayloads(mediaDescription->payloads(), mediaDescription->type())); + + RTCRtpSender* sender = takeFirstSenderOfType(senders, mediaDescription->type()); + if (sender) + mediaDescription->setSource(sender->track()->source()); + } + + bool isInitiator = m_remoteConfigurationType == "answer"; + m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); + RefPtr protectedThis(this); callOnMainThread([targetState, resolveCallback, protectedThis]() mutable { protectedThis->m_signalingState = targetState; From 2e83987e49dd516a477899a68d7973b9c2deb299 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 27 May 2015 15:55:58 +0200 Subject: [PATCH 104/155] RTCPeerConnection/MediaEndpointOwr: Handle incoming sources --- .../Modules/mediastream/RTCPeerConnection.cpp | 28 ++++++++++++++++++- .../openwebrtc/MediaEndpointOwr.cpp | 28 +++++++++++++++++-- .../mediastream/openwebrtc/MediaEndpointOwr.h | 1 + 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 8b4c877631912..14bfb35190a12 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -56,6 +56,8 @@ #include "RTCRtpReceiver.h" #include "RTCRtpSender.h" #include "RTCSessionDescription.h" +#include "RTCTrackEvent.h" +#include "UUID.h" #include #include @@ -792,8 +794,32 @@ void RTCPeerConnection::doneGatheringCandidates(unsigned mdescIndex) maybeDispatchGatheringDone(); } -void RTCPeerConnection::gotRemoteSource(unsigned, RefPtr&&) +void RTCPeerConnection::gotRemoteSource(unsigned mdescIndex, RefPtr&& source) { + if (m_signalingState == SignalingStateClosed) + return; + + if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { + printf("Warning: No remote configuration for incoming source.\n"); + return; + } + + PeerMediaDescription& mediaDescription = *m_remoteConfiguration->mediaDescriptions()[mdescIndex]; + String trackId = mediaDescription.mediaStreamTrackId(); + + if (trackId.isEmpty()) { + // Non WebRTC media description (e.g. legacy) + trackId = createCanonicalUUIDString(); + } + + // FIXME: track should be set to muted (not supported yet) + // FIXME: MediaStream handling not implemented + + RefPtr trackPrivate = MediaStreamTrackPrivate::create(WTF::move(source), trackId); + RefPtr track = MediaStreamTrack::create(*scriptExecutionContext(), *trackPrivate); + RefPtr receiver = RTCRtpReceiver::create(track.copyRef()); + + scheduleDispatchEvent(RTCTrackEvent::create(eventNames().trackEvent, false, false, WTF::move(receiver), WTF::move(track))); } void RTCPeerConnection::stop() diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index b41f7ce80da9e..f499f704b9026 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -216,6 +216,11 @@ void MediaEndpointOwr::dispatchSendSSRC(unsigned sessionIndex, unsigned ssrc, co m_client->gotSendSSRC(sessionIndex, ssrc, cname); } +void MediaEndpointOwr::dispatchRemoteSource(unsigned sessionIndex, RefPtr&& source) +{ + m_client->gotRemoteSource(sessionIndex, WTF::move(source)); +} + void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription*) { g_signal_connect(session, "on-new-candidate", G_CALLBACK(gotCandidate), this); @@ -397,9 +402,28 @@ static void gotSendSsrc(OwrMediaSession* mediaSession, GParamSpec*, MediaEndpoin g_free(cname); } -static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*) +static void gotIncomingSource(OwrMediaSession* mediaSession, OwrMediaSource* source, MediaEndpointOwr* mediaEndpoint) { - printf("-> gotIncomingSource\n"); + String name; + String id("not used"); + OwrMediaType mediaType; + + g_object_get(source, "media-type", &mediaType, nullptr); + + RealtimeMediaSource::Type sourceType; + if (mediaType == OWR_MEDIA_TYPE_AUDIO) { + sourceType = RealtimeMediaSource::Audio; + name = "remote audio"; + } + else if (mediaType == OWR_MEDIA_TYPE_VIDEO) { + sourceType = RealtimeMediaSource::Video; + name = "remote video"; + } + else + ASSERT_NOT_REACHED(); + + RefPtr mediaSource = adoptRef(new RealtimeMediaSourceOwr(source, id, sourceType, name)); + mediaEndpoint->dispatchRemoteSource(mediaEndpoint->sessionIndex(OWR_SESSION(mediaSession)), WTF::move(mediaSource)); } } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index 81028e3e3faa2..e8fc786e50f7c 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -62,6 +62,7 @@ class MediaEndpointOwr : public MediaEndpoint { void dispatchGatheringDone(unsigned sessionIndex); void dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate); void dispatchSendSSRC(unsigned sessionIndex, unsigned ssrc, const String& cname); + void dispatchRemoteSource(unsigned sessionIndex, RefPtr&&); private: enum SessionType { SessionTypeMedia }; From c200b23b035f546dafb63eb20327480c28e9a75d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 2 Jun 2015 08:51:27 +0200 Subject: [PATCH 105/155] RTCPeerConnection: Only schedule callback handleEvent() calls (Promise callbacks have built-in scheduling) --- .../Modules/mediastream/RTCPeerConnection.cpp | 92 +++++++------------ .../bindings/js/JSRTCPeerConnectionCustom.cpp | 43 ++++++--- 2 files changed, 65 insertions(+), 70 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 14bfb35190a12..51a50ff9edd2e 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -284,10 +284,8 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR RefPtr options = RTCOfferOptions::create(offerOptions, ec); if (ec) { - callOnMainThread([rejectCallback] { - RefPtr error = DOMError::create("Invalid createOffer argument."); - rejectCallback(error.get()); - }); + RefPtr error = DOMError::create("Invalid createOffer argument."); + rejectCallback(error.get()); return; } @@ -343,19 +341,15 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe RefPtr options = RTCAnswerOptions::create(answerOptions, ec); if (ec) { - callOnMainThread([rejectCallback] { - RefPtr error = DOMError::create("Invalid createAnswer argument."); - rejectCallback(error.get()); - }); + RefPtr error = DOMError::create("Invalid createAnswer argument."); + rejectCallback(error.get()); return; } if (!m_remoteConfiguration) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidStateError (no remote description)"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidStateError (no remote description)"); + rejectCallback(error.get()); return; } @@ -391,10 +385,7 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); RefPtr answer = RTCSessionDescription::create("answer", MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get())); - - callOnMainThread([resolveCallback, answer] { - resolveCallback(answer); - }); + resolveCallback(answer); } void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) @@ -408,11 +399,9 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, SignalingState targetState = targetSignalingState(SetterTypeLocal, descriptionType); if (targetState == SignalingStateInvalid) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSessionDescriptionError"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError"); + rejectCallback(error.get()); return; } @@ -422,11 +411,9 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, m_localConfigurationType = description->type(); if (!m_localConfiguration) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); + rejectCallback(error.get()); return; } @@ -491,11 +478,9 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, SignalingState targetState = targetSignalingState(SetterTypeRemote, descriptionType); if (targetState == SignalingStateInvalid) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSessionDescriptionError"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError"); + rejectCallback(error.get()); return; } @@ -503,11 +488,9 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, m_remoteConfigurationType = description->type(); if (!m_remoteConfiguration) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); + rejectCallback(error.get()); return; } @@ -529,11 +512,10 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, bool isInitiator = m_remoteConfigurationType == "answer"; m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); - RefPtr protectedThis(this); - callOnMainThread([targetState, resolveCallback, protectedThis]() mutable { - protectedThis->m_signalingState = targetState; - resolveCallback(); - }); + // FIXME: event firing task should update state + m_signalingState = targetState; + + resolveCallback(); } RefPtr RTCPeerConnection::remoteDescription() const @@ -568,31 +550,25 @@ void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResol } if (!m_remoteConfiguration) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidStateError (no remote description)"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidStateError (no remote description)"); + rejectCallback(error.get()); return; } RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(rtcCandidate->candidate()); if (!candidate) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); + rejectCallback(error.get()); return; } unsigned mdescIndex = rtcCandidate->sdpMLineIndex(); if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { - callOnMainThread([rejectCallback] { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSdpMlineIndex (sdpMLineIndex out of range"); - rejectCallback(error.get()); - }); + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSdpMlineIndex (sdpMLineIndex out of range"); + rejectCallback(error.get()); return; } @@ -601,7 +577,7 @@ void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResol m_mediaEndpoint->addRemoteCandidate(*candidate, mdescIndex, mdesc.iceUfrag(), mdesc.icePassword()); - callOnMainThread(resolveCallback); + resolveCallback(); } String RTCPeerConnection::signalingState() const diff --git a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp index 10951b3a67754..a307f56c1b83a 100644 --- a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp +++ b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp @@ -95,11 +95,18 @@ static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnect RefPtr sessionDescriptionCallback = JSRTCSessionDescriptionCallback::create(asObject(exec->argument(0)), globalObject); RefPtr errorCallback = JSRTCPeerConnectionErrorCallback::create(asObject(exec->argument(1)), globalObject); - auto resolveCallback = [sessionDescriptionCallback](RefPtr description) mutable { - sessionDescriptionCallback->handleEvent(description.get()); + RefPtr protectedImpl = &impl; + auto resolveCallback = [protectedImpl, sessionDescriptionCallback](RefPtr description) mutable { + RefPtr protectedDescription = description; + protectedImpl->scriptExecutionContext()->postTask([sessionDescriptionCallback, protectedDescription](ScriptExecutionContext&) mutable { + sessionDescriptionCallback->handleEvent(protectedDescription.get()); + }); }; - auto rejectCallback = [errorCallback](RefPtr error) mutable { - errorCallback->handleEvent(error.get()); + auto rejectCallback = [protectedImpl, errorCallback](RefPtr error) mutable { + RefPtr protectedError = error; + protectedImpl->scriptExecutionContext()->postTask([errorCallback, protectedError](ScriptExecutionContext&) mutable { + errorCallback->handleEvent(protectedError.get()); + }); }; (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec); @@ -158,11 +165,17 @@ static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPee RefPtr voidCallback = JSVoidCallback::create(asObject(exec->argument(1)), globalObject); RefPtr errorCallback = JSRTCPeerConnectionErrorCallback::create(asObject(exec->argument(2)), globalObject); - auto resolveCallback = [voidCallback]() mutable { - voidCallback->handleEvent(); + RefPtr protectedImpl = &impl; + auto resolveCallback = [protectedImpl, voidCallback]() mutable { + protectedImpl->scriptExecutionContext()->postTask([voidCallback](ScriptExecutionContext&) mutable { + voidCallback->handleEvent(); + }); }; - auto rejectCallback = [errorCallback](RefPtr error) mutable { - errorCallback->handleEvent(error.get()); + auto rejectCallback = [protectedImpl, errorCallback](RefPtr error) mutable { + RefPtr protectedError = error; + protectedImpl->scriptExecutionContext()->postTask([errorCallback, protectedError](ScriptExecutionContext&) mutable { + errorCallback->handleEvent(protectedError.get()); + }); }; (impl.*implFunction)(description.get() , WTF::move(resolveCallback), WTF::move(rejectCallback), ec); @@ -213,11 +226,17 @@ JSValue JSRTCPeerConnection::addIceCandidate(ExecState* exec) RefPtr voidCallback = JSVoidCallback::create(asObject(exec->argument(1)), globalObject()); RefPtr errorCallback = JSRTCPeerConnectionErrorCallback::create(asObject(exec->argument(2)), globalObject()); - auto resolveCallback = [voidCallback]() mutable { - voidCallback->handleEvent(); + RefPtr protectedImpl = &impl(); + auto resolveCallback = [protectedImpl, voidCallback]() mutable { + protectedImpl->scriptExecutionContext()->postTask([voidCallback](ScriptExecutionContext&) mutable { + voidCallback->handleEvent(); + }); }; - auto rejectCallback = [errorCallback](RefPtr error) mutable { - errorCallback->handleEvent(error.get()); + auto rejectCallback = [protectedImpl, errorCallback](RefPtr error) mutable { + RefPtr protectedError = error; + protectedImpl->scriptExecutionContext()->postTask([errorCallback, protectedError](ScriptExecutionContext&) mutable { + errorCallback->handleEvent(protectedError.get()); + }); }; impl().addIceCandidate(candidate.get() , WTF::move(resolveCallback), WTF::move(rejectCallback), ec); From 801735cf43de0985ea6dd989e3f665f9d776d8fe Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 2 Jun 2015 09:30:05 +0200 Subject: [PATCH 106/155] RTCPeerConnection: Don't use RefPtr types as arguments to reject/resolve lambda functions --- .../Modules/mediastream/RTCPeerConnection.cpp | 24 +++++++------- .../Modules/mediastream/RTCPeerConnection.h | 4 +-- .../bindings/js/JSRTCPeerConnectionCustom.cpp | 32 +++++++++---------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 51a50ff9edd2e..9388669f86320 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -285,7 +285,7 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR RefPtr options = RTCOfferOptions::create(offerOptions, ec); if (ec) { RefPtr error = DOMError::create("Invalid createOffer argument."); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -329,7 +329,7 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR } RefPtr offer = RTCSessionDescription::create("offer", MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get())); - resolveCallback(WTF::move(offer)); + resolveCallback(*offer); } void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) @@ -342,14 +342,14 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe RefPtr options = RTCAnswerOptions::create(answerOptions, ec); if (ec) { RefPtr error = DOMError::create("Invalid createAnswer argument."); - rejectCallback(error.get()); + rejectCallback(*error); return; } if (!m_remoteConfiguration) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidStateError (no remote description)"); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -385,7 +385,7 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); RefPtr answer = RTCSessionDescription::create("answer", MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get())); - resolveCallback(answer); + resolveCallback(*answer); } void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) @@ -401,7 +401,7 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, if (targetState == SignalingStateInvalid) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError"); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -413,7 +413,7 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, if (!m_localConfiguration) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -480,7 +480,7 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, if (targetState == SignalingStateInvalid) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError"); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -490,7 +490,7 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, if (!m_remoteConfiguration) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -552,7 +552,7 @@ void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResol if (!m_remoteConfiguration) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidStateError (no remote description)"); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -560,7 +560,7 @@ void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResol if (!candidate) { // FIXME: Error type? RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); - rejectCallback(error.get()); + rejectCallback(*error); return; } @@ -568,7 +568,7 @@ void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResol if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidSdpMlineIndex (sdpMLineIndex out of range"); - rejectCallback(error.get()); + rejectCallback(*error); return; } diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 9243da0c31922..d18d464137a6f 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -63,9 +63,9 @@ class RTCPeerConnection final : public RefCounted, public Scr static PassRefPtr create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, ExceptionCode&); ~RTCPeerConnection(); - typedef std::function)> OfferAnswerResolveCallback; + typedef std::function OfferAnswerResolveCallback; typedef std::function VoidResolveCallback; - typedef std::function)> RejectCallback; + typedef std::function RejectCallback; Vector> getSenders() const; Vector> getReceivers() const; diff --git a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp index a307f56c1b83a..e28ab9befda8b 100644 --- a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp +++ b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp @@ -96,14 +96,14 @@ static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnect RefPtr errorCallback = JSRTCPeerConnectionErrorCallback::create(asObject(exec->argument(1)), globalObject); RefPtr protectedImpl = &impl; - auto resolveCallback = [protectedImpl, sessionDescriptionCallback](RefPtr description) mutable { - RefPtr protectedDescription = description; + auto resolveCallback = [protectedImpl, sessionDescriptionCallback](RTCSessionDescription& description) mutable { + RefPtr protectedDescription = &description; protectedImpl->scriptExecutionContext()->postTask([sessionDescriptionCallback, protectedDescription](ScriptExecutionContext&) mutable { sessionDescriptionCallback->handleEvent(protectedDescription.get()); }); }; - auto rejectCallback = [protectedImpl, errorCallback](RefPtr error) mutable { - RefPtr protectedError = error; + auto rejectCallback = [protectedImpl, errorCallback](DOMError& error) mutable { + RefPtr protectedError = &error; protectedImpl->scriptExecutionContext()->postTask([errorCallback, protectedError](ScriptExecutionContext&) mutable { errorCallback->handleEvent(protectedError.get()); }); @@ -124,11 +124,11 @@ static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnect } DeferredWrapper wrapper(exec, globalObject); - auto resolveCallback = [wrapper](RefPtr description) mutable { - wrapper.resolve(description.get()); + auto resolveCallback = [wrapper](RTCSessionDescription &description) mutable { + wrapper.resolve(&description); }; - auto rejectCallback = [wrapper](RefPtr error) mutable { - wrapper.reject(error.get()); + auto rejectCallback = [wrapper](DOMError& error) mutable { + wrapper.reject(&error); }; (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec); @@ -171,8 +171,8 @@ static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPee voidCallback->handleEvent(); }); }; - auto rejectCallback = [protectedImpl, errorCallback](RefPtr error) mutable { - RefPtr protectedError = error; + auto rejectCallback = [protectedImpl, errorCallback](DOMError& error) mutable { + RefPtr protectedError = &error; protectedImpl->scriptExecutionContext()->postTask([errorCallback, protectedError](ScriptExecutionContext&) mutable { errorCallback->handleEvent(protectedError.get()); }); @@ -188,8 +188,8 @@ static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPee auto resolveCallback = [wrapper]() mutable { wrapper.resolve(false); }; - auto rejectCallback = [wrapper](RefPtr error) mutable { - wrapper.reject(error.get()); + auto rejectCallback = [wrapper](DOMError& error) mutable { + wrapper.reject(&error); }; (impl.*implFunction)(description.get(), WTF::move(resolveCallback), WTF::move(rejectCallback), ec); @@ -232,8 +232,8 @@ JSValue JSRTCPeerConnection::addIceCandidate(ExecState* exec) voidCallback->handleEvent(); }); }; - auto rejectCallback = [protectedImpl, errorCallback](RefPtr error) mutable { - RefPtr protectedError = error; + auto rejectCallback = [protectedImpl, errorCallback](DOMError& error) mutable { + RefPtr protectedError = &error; protectedImpl->scriptExecutionContext()->postTask([errorCallback, protectedError](ScriptExecutionContext&) mutable { errorCallback->handleEvent(protectedError.get()); }); @@ -249,8 +249,8 @@ JSValue JSRTCPeerConnection::addIceCandidate(ExecState* exec) auto resolveCallback = [wrapper]() mutable { wrapper.resolve(false); }; - auto rejectCallback = [wrapper](RefPtr error) mutable { - wrapper.reject(error.get()); + auto rejectCallback = [wrapper](DOMError& error) mutable { + wrapper.reject(&error); }; impl().addIceCandidate(candidate.get(), WTF::move(resolveCallback), WTF::move(rejectCallback), ec); From 853f57af6571fcd9bcee7ec86ae152cc66e9b705 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 2 Jun 2015 09:55:21 +0200 Subject: [PATCH 107/155] RTCPeerConnection: Don't use h264 until openh264 is added to the jhbuild --- .../Modules/mediastream/RTCPeerConnection.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 9388669f86320..5cd8819663481 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -245,14 +245,14 @@ static Vector> createDefaultPayloads(const String& type) payload->setChannels(1); payloads.append(payload); } else { - payload = MediaPayload::create(); - payload->setType(103); - payload->setEncodingName("H264"); - payload->setClockRate(90000); - payload->setCcmfir(true); - payload->setNackpli(true); - payload->addParameter("packetizationMode", 1); - payloads.append(payload); + // payload = MediaPayload::create(); + // payload->setType(103); + // payload->setEncodingName("H264"); + // payload->setClockRate(90000); + // payload->setCcmfir(true); + // payload->setNackpli(true); + // payload->addParameter("packetizationMode", 1); + // payloads.append(payload); payload = MediaPayload::create(); payload->setType(100); From d563ddd08da14c2bf0776062930fa45ff3dc6886 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 4 Jun 2015 14:32:33 +0200 Subject: [PATCH 108/155] RTCPeerConnection: First version of SDP conversions with builtin sdp.js (works, but work in progress) --- .../Modules/mediastream/RTCPeerConnection.cpp | 97 ++- .../Modules/mediastream/RTCPeerConnection.h | 8 + .../platform/mediastream/SDPScriptResource.h | 593 ++++++++++++++++++ 3 files changed, 690 insertions(+), 8 deletions(-) create mode 100644 Source/WebCore/platform/mediastream/SDPScriptResource.h diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 5cd8819663481..cf4a10b9873dd 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -61,6 +61,14 @@ #include #include +// FIXME: Headers for sdp.js supported SDP conversion is kept on the side for now +#include "JSDOMWindow.h" +#include "ScriptController.h" +#include "ScriptGlobalObject.h" +#include "ScriptSourceCode.h" +#include "SDPScriptResource.h" +#include + namespace WebCore { static RefPtr createMediaEndpointInit(RTCConfiguration& rtcConfig) @@ -328,7 +336,8 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); } - RefPtr offer = RTCSessionDescription::create("offer", MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get())); + String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); + RefPtr offer = RTCSessionDescription::create("offer", toSDP(json)); resolveCallback(*offer); } @@ -384,7 +393,8 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); - RefPtr answer = RTCSessionDescription::create("answer", MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get())); + String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); + RefPtr answer = RTCSessionDescription::create("answer", toSDP(json)); resolveCallback(*answer); } @@ -407,7 +417,8 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, unsigned previousNumberOfMediaDescriptions = m_localConfiguration ? m_localConfiguration->mediaDescriptions().size() : 0; - m_localConfiguration = MediaEndpointConfigurationConversions::fromJSON(description->sdp()); + String json = fromSDP(description->sdp()); + m_localConfiguration = MediaEndpointConfigurationConversions::fromJSON(json); m_localConfigurationType = description->type(); if (!m_localConfiguration) { @@ -438,7 +449,8 @@ RefPtr RTCPeerConnection::localDescription() const if (!m_localConfiguration) return nullptr; - return RTCSessionDescription::create(m_localConfigurationType, MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())); + String json = MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get()); + return RTCSessionDescription::create(m_localConfigurationType, toSDP(json)); } static Vector> filterPayloads(const Vector>& remotePayloads, const String& type) @@ -484,7 +496,8 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, return; } - m_remoteConfiguration = MediaEndpointConfigurationConversions::fromJSON(description->sdp()); + String json = fromSDP(description->sdp()); + m_remoteConfiguration = MediaEndpointConfigurationConversions::fromJSON(json); m_remoteConfigurationType = description->type(); if (!m_remoteConfiguration) { @@ -523,7 +536,8 @@ RefPtr RTCPeerConnection::remoteDescription() const if (!m_remoteConfiguration) return nullptr; - return RTCSessionDescription::create(m_remoteConfigurationType, MediaEndpointConfigurationConversions::toJSON(m_remoteConfiguration.get())); + String json = MediaEndpointConfigurationConversions::toJSON(m_remoteConfiguration.get()); + return RTCSessionDescription::create(m_remoteConfigurationType, toSDP(json)); } void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionCode& ec) @@ -556,7 +570,8 @@ void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResol return; } - RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(rtcCandidate->candidate()); + String json = iceCandidateFromSDP(rtcCandidate->candidate()); + RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(json); if (!candidate) { // FIXME: Error type? RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); @@ -753,7 +768,8 @@ void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr iceCandidate = RTCIceCandidate::create(candidateString, "", mdescIndex); + String sdpFragment = iceCandidateToSDP(candidateString); + RefPtr iceCandidate = RTCIceCandidate::create(sdpFragment, "", mdescIndex); scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, WTF::move(iceCandidate))); } } @@ -893,6 +909,71 @@ void RTCPeerConnection::maybeDispatchGatheringDone() scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, nullptr)); } +String RTCPeerConnection::toSDP(const String& json) const +{ + return sdpConversion("toSDP", json); +} + +String RTCPeerConnection::fromSDP(const String& sdp) const +{ + return sdpConversion("fromSDP", sdp); +} + +String RTCPeerConnection::iceCandidateToSDP(const String& json) const +{ + return sdpConversion("iceCandidateToSDP", json); +} + +String RTCPeerConnection::iceCandidateFromSDP(const String& sdpFragment) const +{ + return sdpConversion("iceCandidateFromSDP", sdpFragment); +} + +String RTCPeerConnection::sdpConversion(const String& functionName, const String& argument) const +{ + Document* document = downcast(scriptExecutionContext()); + + if (!m_isolatedWorld) + m_isolatedWorld = DOMWrapperWorld::create(JSDOMWindow::commonVM()); + + ScriptController& scriptController = document->frame()->script(); + JSDOMGlobalObject* globalObject = JSC::jsCast(scriptController.globalObject(*m_isolatedWorld)); + JSC::ExecState* exec = globalObject->globalExec(); + JSC::JSLockHolder lock(exec); + + JSC::JSValue probeFunctionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, "toSDP")); + if (!probeFunctionValue.isFunction()) { + URL scriptURL; + scriptController.evaluateInWorld(ScriptSourceCode(SDPScriptResource::getString(), scriptURL), *m_isolatedWorld); + if (exec->hadException()) { + exec->clearException(); + return emptyString(); + } + } + + JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, functionName)); + if (!functionValue.isFunction()) + return emptyString(); + + JSC::JSObject* function = functionValue.toObject(exec); + JSC::CallData callData; + JSC::CallType callType = function->methodTable()->getCallData(function, callData); + if (callType == JSC::CallTypeNone) + return emptyString(); + + JSC::MarkedArgumentBuffer argList; + argList.append(JSC::jsString(exec, argument)); + + JSC::JSValue result = JSC::call(exec, function, callType, callData, globalObject, argList); + if (exec->hadException()) { + printf("sdpConversion: js function (%s) threw\n", functionName.ascii().data()); + exec->clearException(); + return emptyString(); + } + + return result.isString() ? result.getString(exec) : emptyString(); +} + const char* RTCPeerConnection::activeDOMObjectName() const { return "RTCPeerConnection"; diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index d18d464137a6f..03db99ee1725a 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -165,6 +165,12 @@ class RTCPeerConnection final : public RefCounted, public Scr ResolveSetLocalDescriptionResult maybeResolveSetLocalDescription(); void maybeDispatchGatheringDone(); + String toSDP(const String& json) const; + String fromSDP(const String& sdp) const; + String iceCandidateToSDP(const String& json) const; + String iceCandidateFromSDP(const String& sdpFragment) const; + String sdpConversion(const String& functionName, const String& argument) const; + void scheduleDispatchEvent(PassRefPtr); void scheduledEventTimerFired(); @@ -200,6 +206,8 @@ class RTCPeerConnection final : public RefCounted, public Scr std::unique_ptr m_mediaEndpoint; + mutable RefPtr m_isolatedWorld; + Timer m_scheduledEventTimer; Vector> m_scheduledEvents; diff --git a/Source/WebCore/platform/mediastream/SDPScriptResource.h b/Source/WebCore/platform/mediastream/SDPScriptResource.h new file mode 100644 index 0000000000000..aac4f3090b922 --- /dev/null +++ b/Source/WebCore/platform/mediastream/SDPScriptResource.h @@ -0,0 +1,593 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef SDPScriptResource_h +#define SDPScriptResource_h + +#if ENABLE(MEDIA_STREAM) + + +namespace WebCore { + +namespace SDPScriptResource { + +const char* script = "/*\ + * Copyright (C) 2014-2015 Ericsson AB. All rights reserved.\ + *\ + * 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT\ + * OWNER OR 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.\ + */\ +\ +\"use strict\";\ +\ +if (typeof(SDP) == \"undefined\")\ + var SDP = {};\ +\ +(function () {\ + var regexps = {\ + \"vline\": \"^v=([\\\\d]+).*$\",\ + \"oline\": \"^o=([\\\\w\\\\-@\\\\.]+) ([\\\\d]+) ([\\\\d]+) IN (IP[46]) ([\\\\d\\\\.a-f\\\\:]+).*$\",\ + \"sline\": \"^s=(.*)$\",\ + \"tline\": \"^t=([\\\\d]+) ([\\\\d]+).*$\",\ + \"cline\": \"^c=IN (IP[46]) ([\\\\d\\\\.a-f\\\\:]+).*$\",\ + \"msidsemantic\": \"^a=msid-semantic: *WMS .*$\",\ + \"mblock\": \"^m=(audio|video|application) ([\\\\d]+) ([A-Z/]+)([\\\\d ]*)$\\\\r?\\\\n\",\ + \"mode\": \"^a=(sendrecv|sendonly|recvonly|inactive).*$\",\ + \"rtpmap\": \"^a=rtpmap:${type} ([\\\\w\\\\-]+)/([\\\\d]+)/?([\\\\d]+)?.*$\",\ + \"fmtp\": \"^a=fmtp:${type} ([\\\\w\\\\-=;]+).*$\",\ + \"param\": \"([\\\\w\\\\-]+)=([\\\\w\\\\-]+);?\",\ + \"nack\": \"^a=rtcp-fb:${type} nack$\",\ + \"nackpli\": \"^a=rtcp-fb:${type} nack pli$\",\ + \"ccmfir\": \"^a=rtcp-fb:${type} ccm fir$\",\ + \"rtcp\": \"^a=rtcp:([\\\\d]+)( IN (IP[46]) ([\\\\d\\\\.a-f\\\\:]+))?.*$\",\ + \"rtcpmux\": \"^a=rtcp-mux.*$\",\ + \"cname\": \"^a=ssrc:(\\\\d+) cname:([\\\\w+/\\\\-@\\\\.]+).*$\",\ + \"msid\": \"^a=(ssrc:\\\\d+ )?msid:([\\\\w+/\\\\-=]+) +([\\\\w+/\\\\-=]+).*$\",\ + \"ufrag\": \"^a=ice-ufrag:([\\\\w+/]*).*$\",\ + \"pwd\": \"^a=ice-pwd:([\\\\w+/]*).*$\",\ + \"candidate\": \"^a=candidate:(\\\\d+) (\\\\d) (UDP|TCP) ([\\\\d\\\\.]*) ([\\\\d\\\\.a-f\\\\:]*) (\\\\d*)\" +\ + \" typ ([a-z]*)( raddr ([\\\\d\\\\.a-f\\\\:]*) rport (\\\\d*))?\" +\ + \"( tcptype (active|passive|so))?.*$\",\ + \"fingerprint\": \"^a=fingerprint:(sha-1|sha-256) ([A-Fa-f\\\\d\\:]+).*$\",\ + \"setup\": \"^a=setup:(actpass|active|passive).*$\",\ + \"sctpmap\": \"^a=sctpmap:${port} ([\\\\w\\\\-]+)( [\\\\d]+)?.*$\"\ + };\ +\ + var templates = {\ + \"sdp\":\ + \"v=${version}\\r\\n\" +\ + \"o=${username} ${sessionId} ${sessionVersion} ${netType} ${addressType} ${address}\\r\\n\" +\ + \"s=${sessionName}\\r\\n\" +\ + \"t=${startTime} ${stopTime}\\r\\n\" +\ + \"${msidsemanticLine}\",\ +\ + \"msidsemantic\": \"a=msid-semantic:WMS ${mediaStreamIds}\\r\\n\",\ +\ + \"mblock\":\ + \"m=${type} ${port} ${protocol} ${fmt}\\r\\n\" +\ + \"c=${netType} ${addressType} ${address}\\r\\n\" +\ + \"${rtcpLine}\" +\ + \"${rtcpMuxLine}\" +\ + \"a=${mode}\\r\\n\" +\ + \"${rtpMapLines}\" +\ + \"${fmtpLines}\" +\ + \"${nackLines}\" +\ + \"${nackpliLines}\" +\ + \"${ccmfirLines}\" +\ + \"${cnameLines}\" +\ + \"${msidLines}\" +\ + \"${iceCredentialLines}\" +\ + \"${candidateLines}\" +\ + \"${dtlsFingerprintLine}\" +\ + \"${dtlsSetupLine}\" +\ + \"${sctpmapLine}\",\ +\ + \"rtcp\": \"a=rtcp:${port}${[ ]netType}${[ ]addressType}${[ ]address}\\r\\n\",\ + \"rtcpMux\": \"a=rtcp-mux\\r\\n\",\ +\ + \"rtpMap\": \"a=rtpmap:${type} ${encodingName}/${clockRate}${[/]channels}\\r\\n\",\ + \"fmtp\": \"a=fmtp:${type} ${parameters}\\r\\n\",\ + \"nack\": \"a=rtcp-fb:${type} nack\\r\\n\",\ + \"nackpli\": \"a=rtcp-fb:${type} nack pli\\r\\n\",\ + \"ccmfir\": \"a=rtcp-fb:${type} ccm fir\\r\\n\",\ +\ + \"cname\": \"a=ssrc:${ssrc} cname:${cname}\\r\\n\",\ + \"msid\": \"a=${[ssrc:]ssrc[ ]}msid:${mediaStreamId} ${mediaStreamTrackId}\\r\\n\",\ +\ + \"iceCredentials\":\ + \"a=ice-ufrag:${ufrag}\\r\\n\" +\ + \"a=ice-pwd:${password}\\r\\n\",\ +\ + \"candidate\":\ + \"a=candidate:${foundation} ${componentId} ${transport} ${priority} ${address} ${port}\" +\ + \" typ ${type}${[ raddr ]relatedAddress}${[ rport ]relatedPort}${[ tcptype ]tcpType}\\r\\n\",\ +\ + \"dtlsFingerprint\": \"a=fingerprint:${fingerprintHashFunction} ${fingerprint}\\r\\n\",\ + \"dtlsSetup\": \"a=setup:${setup}\\r\\n\",\ +\ + \"sctpmap\": \"a=sctpmap:${port} ${app}${[ ]streams}\\r\\n\"\ + };\ +\ + function match(data, pattern, flags, alt) {\ + var r = new RegExp(pattern, flags);\ + return data.match(r) || alt && alt.match(r) || null;\ + }\ +\ + function addDefaults(obj, defaults) {\ + for (var p in defaults) {\ + if (!defaults.hasOwnProperty(p))\ + continue;\ + if (typeof(obj[p]) == \"undefined\")\ + obj[p] = defaults[p];\ + }\ + }\ +\ + function fillTemplate(template, info) {\ + var text = template;\ + for (var p in info) {\ + if (!info.hasOwnProperty(p))\ + continue;\ + var r = new RegExp(\"\\\\${(\\\\[[^\\\\]]+\\\\])?\" + p + \"(\\\\[[^\\\\]]+\\\\])?}\");\ + text = text.replace(r, function (_, prefix, suffix) {\ + if (!info[p] && info[p] != 0)\ + return \"\";\ + prefix = prefix ? prefix.substr(1, prefix.length - 2) : \"\";\ + suffix = suffix ? suffix.substr(1, suffix.length - 2) : \"\";\ + return prefix + info[p] + suffix;\ + });\ + }\ + return text;\ + }\ +\ + SDP.parse = function (sdpText) {\ + sdpText = new String(sdpText);\ + var sdpObj = {};\ + var parts = sdpText.split(new RegExp(regexps.mblock, \"m\")) || [sdpText];\ + var sblock = parts.shift();\ + var version = parseInt((match(sblock, regexps.vline, \"m\") || [])[1]);\ + if (!isNaN(version))\ + sdpObj.version = version;\ + var originator = match(sblock, regexps.oline, \"m\");;\ + if (originator) {\ + sdpObj.originator = {\ + \"username\": originator[1],\ + \"sessionId\": originator[2],\ + \"sessionVersion\": parseInt(originator[3]),\ + \"netType\": \"IN\",\ + \"addressType\": originator[4],\ + \"address\": originator[5]\ + };\ + }\ + var sessionName = match(sblock, regexps.sline, \"m\");\ + if (sessionName)\ + sdpObj.sessionName = sessionName[1];\ + var sessionTime = match(sblock, regexps.tline, \"m\");\ + if (sessionTime) {\ + sdpObj.startTime = parseInt(sessionTime[1]);\ + sdpObj.stopTime = parseInt(sessionTime[2]);\ + }\ + var hasMediaStreamId = !!match(sblock, regexps.msidsemantic, \"m\");\ + sdpObj.mediaDescriptions = [];\ +\ + for (var i = 0; i < parts.length; i += 5) {\ + var mediaDescription = {\ + \"type\": parts[i],\ + \"port\": parts[i + 1],\ + \"protocol\": parts[i + 2],\ + };\ + var fmt = parts[i + 3].replace(/^[\\s\\uFEFF\\xA0]+/, '')\ + .split(/ +/)\ + .map(function (x) {\ + return parseInt(x);\ + });\ + var mblock = parts[i + 4];\ +\ + var connection = match(mblock, regexps.cline, \"m\", sblock);\ + if (connection) {\ + mediaDescription.netType = \"IN\";\ + mediaDescription.addressType = connection[1];\ + mediaDescription.address = connection[2];\ + }\ + var mode = match(mblock, regexps.mode, \"m\", sblock);\ + if (mode)\ + mediaDescription.mode = mode[1];\ +\ + var payloadTypes = [];\ + if (match(mediaDescription.protocol, \"RTP/S?AVPF?\")) {\ + mediaDescription.payloads = [];\ + payloadTypes = fmt;\ + }\ + payloadTypes.forEach(function (payloadType) {\ + var payload = { \"type\": payloadType };\ + var rtpmapLine = fillTemplate(regexps.rtpmap, payload);\ + var rtpmap = match(mblock, rtpmapLine, \"m\");\ + if (rtpmap) {\ + payload.encodingName = rtpmap[1];\ + payload.clockRate = parseInt(rtpmap[2]);\ + if (mediaDescription.type == \"audio\")\ + payload.channels = parseInt(rtpmap[3]) || 1;\ + else if (mediaDescription.type == \"video\") {\ + var nackLine = fillTemplate(regexps.nack, payload);\ + payload.nack = !!match(mblock, nackLine, \"m\");\ + var nackpliLine = fillTemplate(regexps.nackpli, payload);\ + payload.nackpli = !!match(mblock, nackpliLine, \"m\");\ + var ccmfirLine = fillTemplate(regexps.ccmfir, payload);\ + payload.ccmfir = !!match(mblock, ccmfirLine, \"m\");\ + }\ + } else if (payloadType == 0 || payloadType == 8) {\ + payload.encodingName = payloadType == 8 ? \"PCMA\" : \"PCMU\";\ + payload.clockRate = 8000;\ + payload.channels = 1;\ + }\ + var fmtpLine = fillTemplate(regexps.fmtp, payload);\ + var fmtp = match(mblock, fmtpLine, \"m\");\ + if (fmtp) {\ + payload.parameters = {};\ + fmtp[1].replace(new RegExp(regexps.param, \"g\"),\ + function(_, key, value) {\ + key = key.replace(/-([a-z])/g, function (_, c) {\ + return c.toUpperCase();\ + });\ + payload.parameters[key] = isNaN(+value) ? value : +value;\ + });\ + }\ + mediaDescription.payloads.push(payload);\ + });\ +\ + var rtcp = match(mblock, regexps.rtcp, \"m\");\ + if (rtcp) {\ + mediaDescription.rtcp = {\ + \"netType\": \"IN\",\ + \"port\": parseInt(rtcp[1])\ + };\ + if (rtcp[2]) {\ + mediaDescription.rtcp.addressType = rtcp[3];\ + mediaDescription.rtcp.address = rtcp[4];\ + }\ + }\ + var rtcpmux = match(mblock, regexps.rtcpmux, \"m\", sblock);\ + if (rtcpmux) {\ + if (!mediaDescription.rtcp)\ + mediaDescription.rtcp = {};\ + mediaDescription.rtcp.mux = true;\ + }\ +\ + var cnameLines = match(mblock, regexps.cname, \"mg\");\ + if (cnameLines) {\ + mediaDescription.ssrcs = [];\ + cnameLines.forEach(function (line) {\ + var cname = match(line, regexps.cname, \"m\");\ + mediaDescription.ssrcs.push(parseInt(cname[1]));\ + if (!mediaDescription.cname)\ + mediaDescription.cname = cname[2];\ + });\ + }\ +\ + if (hasMediaStreamId) {\ + var msid = match(mblock, regexps.msid, \"m\");\ + if (msid) {\ + mediaDescription.mediaStreamId = msid[2];\ + mediaDescription.mediaStreamTrackId = msid[3];\ + }\ + }\ +\ + var ufrag = match(mblock, regexps.ufrag, \"m\", sblock);\ + var pwd = match(mblock, regexps.pwd, \"m\", sblock);\ + if (ufrag && pwd) {\ + mediaDescription.ice = {\ + \"ufrag\": ufrag[1],\ + \"password\": pwd[1]\ + };\ + }\ + var candidateLines = match(mblock, regexps.candidate, \"mig\");\ + if (candidateLines) {\ + if (!mediaDescription.ice)\ + mediaDescription.ice = {};\ + mediaDescription.ice.candidates = [];\ + candidateLines.forEach(function (line) {\ + var candidateLine = match(line, regexps.candidate, \"mi\");\ + var candidate = {\ + \"foundation\": candidateLine[1],\ + \"componentId\": parseInt(candidateLine[2]),\ + \"transport\": candidateLine[3].toUpperCase(),\ + \"priority\": parseInt(candidateLine[4]),\ + \"address\": candidateLine[5],\ + \"port\": parseInt(candidateLine[6]),\ + \"type\": candidateLine[7]\ + };\ + if (candidateLine[9])\ + candidate.relatedAddress = candidateLine[9];\ + if (!isNaN(candidateLine[10]))\ + candidate.relatedPort = parseInt(candidateLine[10]);\ + if (candidateLine[12])\ + candidate.tcpType = candidateLine[12];\ + else if (candidate.transport == \"TCP\") {\ + if (candidate.port == 0 || candidate.port == 9) {\ + candidate.tcpType = \"active\";\ + candidate.port = 9;\ + } else {\ + return;\ + }\ + }\ + mediaDescription.ice.candidates.push(candidate);\ + });\ + }\ +\ + var fingerprint = match(mblock, regexps.fingerprint, \"mi\", sblock);\ + if (fingerprint) {\ + mediaDescription.dtls = {\ + \"fingerprintHashFunction\": fingerprint[1].toLowerCase(),\ + \"fingerprint\": fingerprint[2].toUpperCase()\ + };\ + }\ + var setup = match(mblock, regexps.setup, \"m\", sblock);\ + if (setup) {\ + if (!mediaDescription.dtls)\ + mediaDescription.dtls = {};\ + mediaDescription.dtls.setup = setup[1];\ + }\ +\ + if (mediaDescription.protocol == \"DTLS/SCTP\") {\ + mediaDescription.sctp = {\ + \"port\": fmt[0]\ + };\ + var sctpmapLine = fillTemplate(regexps.sctpmap, mediaDescription.sctp);\ + var sctpmap = match(mblock, sctpmapLine, \"m\");\ + if (sctpmap) {\ + mediaDescription.sctp.app = sctpmap[1];\ + if (sctpmap[2])\ + mediaDescription.sctp.streams = parseInt(sctpmap[2]);\ + }\ + }\ +\ + sdpObj.mediaDescriptions.push(mediaDescription);\ + }\ +\ + return sdpObj;\ + };\ +\ + SDP.generate = function (sdpObj) {\ + sdpObj = JSON.parse(JSON.stringify(sdpObj));\ + addDefaults(sdpObj, {\ + \"version\": 0,\ + \"originator\": {},\ + \"sessionName\": \"-\",\ + \"startTime\": 0,\ + \"stopTime\": 0,\ + \"mediaDescriptions\": []\ + });\ + addDefaults(sdpObj.originator, {\ + \"username\": \"-\",\ + \"sessionId\": \"\" + Math.floor((Math.random() + +new Date()) * 1e6),\ + \"sessionVersion\": 1,\ + \"netType\": \"IN\",\ + \"addressType\": \"IP4\",\ + \"address\": \"127.0.0.1\"\ + });\ + var sdpText = fillTemplate(templates.sdp, sdpObj);\ + sdpText = fillTemplate(sdpText, sdpObj.originator);\ +\ + var msidsemanticLine = \"\";\ + var mediaStreamIds = [];\ + sdpObj.mediaDescriptions.forEach(function (mdesc) {\ + if (mdesc.mediaStreamId && mdesc.mediaStreamTrackId\ + && mediaStreamIds.indexOf(mdesc.mediaStreamId) == -1)\ + mediaStreamIds.push(mdesc.mediaStreamId);\ + });\ + if (mediaStreamIds.length) {\ + var msidsemanticLine = fillTemplate(templates.msidsemantic,\ + { \"mediaStreamIds\": mediaStreamIds.join(\" \") });\ + }\ + sdpText = fillTemplate(sdpText, { \"msidsemanticLine\": msidsemanticLine });\ +\ + sdpObj.mediaDescriptions.forEach(function (mediaDescription) {\ + addDefaults(mediaDescription, {\ + \"port\": 1,\ + \"protocol\": \"RTP/SAVPF\",\ + \"netType\": \"IN\",\ + \"addressType\": \"IP4\",\ + \"address\": \"0.0.0.0\",\ + \"mode\": \"sendrecv\",\ + \"payloads\": [],\ + \"rtcp\": {}\ + });\ + var mblock = fillTemplate(templates.mblock, mediaDescription);\ +\ + var payloadInfo = {\"rtpMapLines\": \"\", \"fmtpLines\": \"\", \"nackLines\": \"\",\ + \"nackpliLines\": \"\", \"ccmfirLines\": \"\"};\ + mediaDescription.payloads.forEach(function (payload) {\ + if (payloadInfo.fmt)\ + payloadInfo.fmt += \" \" + payload.type;\ + else\ + payloadInfo.fmt = payload.type;\ + if (!payload.channels || payload.channels == 1)\ + payload.channels = null;\ + payloadInfo.rtpMapLines += fillTemplate(templates.rtpMap, payload);\ + if (payload.parameters) {\ + var fmtpInfo = { \"type\": payload.type, \"parameters\": \"\" };\ + for (var p in payload.parameters) {\ + var param = p.replace(/([A-Z])([a-z])/g, function (_, a, b) {\ + return \"-\" + a.toLowerCase() + b;\ + });\ + if (fmtpInfo.parameters)\ + fmtpInfo.parameters += \";\";\ + fmtpInfo.parameters += param + \"=\" + payload.parameters[p];\ + }\ + payloadInfo.fmtpLines += fillTemplate(templates.fmtp, fmtpInfo);\ + }\ + if (payload.nack)\ + payloadInfo.nackLines += fillTemplate(templates.nack, payload);\ + if (payload.nackpli)\ + payloadInfo.nackpliLines += fillTemplate(templates.nackpli, payload);\ + if (payload.ccmfir)\ + payloadInfo.ccmfirLines += fillTemplate(templates.ccmfir, payload);\ + });\ + mblock = fillTemplate(mblock, payloadInfo);\ +\ + var rtcpInfo = {\"rtcpLine\": \"\", \"rtcpMuxLine\": \"\"};\ + if (mediaDescription.rtcp.port) {\ + addDefaults(mediaDescription.rtcp, {\ + \"netType\": \"IN\",\ + \"addressType\": \"IP4\",\ + \"address\": \"\"\ + });\ + if (!mediaDescription.rtcp.address)\ + mediaDescription.rtcp.netType = mediaDescription.rtcp.addressType = \"\";\ + rtcpInfo.rtcpLine = fillTemplate(templates.rtcp, mediaDescription.rtcp);\ + }\ + if (mediaDescription.rtcp.mux)\ + rtcpInfo.rtcpMuxLine = templates.rtcpMux;\ + mblock = fillTemplate(mblock, rtcpInfo);\ +\ + var srcAttributeLines = { \"cnameLines\": \"\", \"msidLines\": \"\" };\ + var srcAttributes = {\ + \"cname\": mediaDescription.cname,\ + \"mediaStreamId\": mediaDescription.mediaStreamId,\ + \"mediaStreamTrackId\": mediaDescription.mediaStreamTrackId\ + };\ + if (mediaDescription.cname && mediaDescription.ssrcs) {\ + mediaDescription.ssrcs.forEach(function (ssrc) {\ + srcAttributes.ssrc = ssrc;\ + srcAttributeLines.cnameLines += fillTemplate(templates.cname, srcAttributes);\ + if (mediaDescription.mediaStreamId && mediaDescription.mediaStreamTrackId)\ + srcAttributeLines.msidLines += fillTemplate(templates.msid, srcAttributes);\ + });\ + } else if (mediaDescription.mediaStreamId && mediaDescription.mediaStreamTrackId) {\ + srcAttributes.ssrc = null;\ + srcAttributeLines.msidLines += fillTemplate(templates.msid, srcAttributes);\ + }\ + mblock = fillTemplate(mblock, srcAttributeLines);\ +\ + var iceInfo = {\"iceCredentialLines\": \"\", \"candidateLines\": \"\"};\ + if (mediaDescription.ice) {\ + iceInfo.iceCredentialLines = fillTemplate(templates.iceCredentials,\ + mediaDescription.ice);\ + if (mediaDescription.ice.candidates) {\ + mediaDescription.ice.candidates.forEach(function (candidate) {\ + addDefaults(candidate, {\ + \"relatedAddress\": null,\ + \"relatedPort\": null,\ + \"tcpType\": null\ + });\ + iceInfo.candidateLines += fillTemplate(templates.candidate, candidate);\ + });\ + }\ + }\ + mblock = fillTemplate(mblock, iceInfo);\ +\ + var dtlsInfo = { \"dtlsFingerprintLine\": \"\", \"dtlsSetupLine\": \"\" };\ + if (mediaDescription.dtls) {\ + if (mediaDescription.dtls.fingerprint) {\ + dtlsInfo.dtlsFingerprintLine = fillTemplate(templates.dtlsFingerprint,\ + mediaDescription.dtls);\ + }\ + addDefaults(mediaDescription.dtls, {\"setup\": \"actpass\"});\ + dtlsInfo.dtlsSetupLine = fillTemplate(templates.dtlsSetup, mediaDescription.dtls);\ + }\ + mblock = fillTemplate(mblock, dtlsInfo);\ +\ + var sctpInfo = {\"sctpmapLine\": \"\", \"fmt\": \"\"};\ + if (mediaDescription.sctp) {\ + addDefaults(mediaDescription.sctp, {\"streams\": null});\ + sctpInfo.sctpmapLine = fillTemplate(templates.sctpmap, mediaDescription.sctp);\ + sctpInfo.fmt = mediaDescription.sctp.port;\ + }\ + mblock = fillTemplate(mblock, sctpInfo);\ +\ + sdpText += mblock;\ + });\ +\ + return sdpText;\ + };\ +\ + SDP.generateCandidateLine = function (candidateObj) {\ + addDefaults(candidateObj, {\ + \"relatedAddress\": null,\ + \"relatedPort\": null,\ + \"tcpType\": null\ + });\ + \ + return fillTemplate(templates.candidate, candidateObj);\ + };\ +\ +})();\ +\ +function toSDP(json) {\ + var object = JSON.parse(json);\ + return SDP.generate(object);\ +}\ +\ +function fromSDP(sdp) {\ + var object = SDP.parse(sdp);\ + return JSON.stringify(object);\ +}\ +\ +function iceCandidateToSDP(json) {\ + var candidate = JSON.parse(json);\ + return SDP.generateCandidateLine(candidate).substr(2);\ +}\ +\ +function iceCandidateFromSDP(sdpFragment) {\ + var iceInfo = SDP.parse(\"m=application 0 NONE\\r\\na=\" + sdpFragment + \"\\r\\n\").mediaDescriptions[0].ice;\ + return JSON.stringify(iceInfo.candidates[0]);\ +}"; + +String getString() +{ + return String(script); +} + +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // SDPScriptResource_h From de7b829743194d4f01051f197f9f7c449a120fa6 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Wed, 3 Jun 2015 23:52:21 -0700 Subject: [PATCH 109/155] Add openh264 to jhbuild --- Tools/gtk/jhbuild.modules | 11 ++++++++++- Tools/gtk/patches/openh264-configure.patch | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 Tools/gtk/patches/openh264-configure.patch diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index 6e73fc9282b54..b8a155a2ffd28 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -293,6 +293,14 @@ + + + + + + @@ -315,10 +323,11 @@ - + + diff --git a/Tools/gtk/patches/openh264-configure.patch b/Tools/gtk/patches/openh264-configure.patch new file mode 100644 index 0000000000000..d28a46ec8e8cd --- /dev/null +++ b/Tools/gtk/patches/openh264-configure.patch @@ -0,0 +1,9 @@ +--- /dev/null 2015-06-04 16:39:40.000000000 +1000 ++++ pseudo-configure 2015-06-04 16:39:42.000000000 +1000 +@@ -0,0 +1,5 @@ ++#!/bin/sh ++ ++sed -e "s:^PREFIX=.*:PREFIX=$JHBUILD_PREFIX:" Makefile > Makefile.tmp && mv Makefile.tmp Makefile ++X=build/x86-common.mk ++sed -e "s:^ASM =.*:ASM = yasm:" $X > ${X}.tmp && mv ${X}.tmp $X + From a8b73a6002b5f0981884c4adf377290be8d67bbd Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Thu, 4 Jun 2015 22:25:06 -0700 Subject: [PATCH 110/155] Install libopenh264 in the correct lib prefix --- Tools/gtk/patches/openh264-configure.patch | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Tools/gtk/patches/openh264-configure.patch b/Tools/gtk/patches/openh264-configure.patch index d28a46ec8e8cd..7bf1bd5a1ea0c 100644 --- a/Tools/gtk/patches/openh264-configure.patch +++ b/Tools/gtk/patches/openh264-configure.patch @@ -1,9 +1,12 @@ ---- /dev/null 2015-06-04 16:39:40.000000000 +1000 -+++ pseudo-configure 2015-06-04 16:39:42.000000000 +1000 -@@ -0,0 +1,5 @@ +--- /dev/null 2015-06-05 15:20:34.000000000 +1000 ++++ pseudo-configure 2015-06-05 15:20:37.000000000 +1000 +@@ -0,0 +1,8 @@ +#!/bin/sh + -+sed -e "s:^PREFIX=.*:PREFIX=$JHBUILD_PREFIX:" Makefile > Makefile.tmp && mv Makefile.tmp Makefile ++X=Makefile ++sed -e "s:^PREFIX=.*:PREFIX=$JHBUILD_PREFIX:" ${X} > ${X}.tmp && mv ${X}.tmp ${X} ++sed -e "s:^SHAREDLIB_DIR=.*:SHAREDLIB_DIR=$CMAKE_LIBRARY_PATH:" ${X} > ${X}.tmp && mv ${X}.tmp ${X} ++ +X=build/x86-common.mk +sed -e "s:^ASM =.*:ASM = yasm:" $X > ${X}.tmp && mv ${X}.tmp $X From eb0e6fd1d51d8e21447d818f75358703f1b6bc7d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 8 Jun 2015 13:17:11 +0200 Subject: [PATCH 111/155] UserMediaRequest: Fix merge build error --- Source/WebCore/Modules/mediastream/UserMediaRequest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp index cbce810f131b0..f57b83ccc499a 100644 --- a/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp +++ b/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp @@ -182,9 +182,9 @@ void UserMediaRequest::didCreateStream(PassRefPtr privateStr // 4 - Create the MediaStream and pass it to the success callback. RefPtr stream = MediaStream::create(*m_scriptExecutionContext, privateStream); for (auto& track : stream->getAudioTracks()) - track->applyConstraints(m_audioConstraints); + track->applyConstraints(*m_audioConstraints); for (auto& track : stream->getVideoTracks()) - track->applyConstraints(m_videoConstraints); + track->applyConstraints(*m_videoConstraints); m_resolveCallback(*stream); } From f08b035d7798416143abc0d81df3fc517b9474cf Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 9 Jun 2015 09:24:21 +0200 Subject: [PATCH 112/155] Align Ref/RefPtr usage with upstream --- Source/WebCore/Modules/mediastream/MediaStream.cpp | 14 +++++++------- Source/WebCore/Modules/mediastream/MediaStream.h | 8 ++++---- .../Modules/mediastream/MediaStreamTrack.cpp | 4 ++-- .../WebCore/Modules/mediastream/MediaStreamTrack.h | 2 +- .../Modules/mediastream/RTCIceCandidate.cpp | 4 ++-- .../WebCore/Modules/mediastream/RTCIceCandidate.h | 2 +- Source/WebCore/Modules/mediastream/RTCIceServer.h | 4 ++-- .../Modules/mediastream/RTCPeerConnection.cpp | 4 ++-- .../Modules/mediastream/RTCPeerConnection.h | 2 +- .../WebCore/Modules/mediastream/RTCRtpReceiver.cpp | 4 ++-- .../WebCore/Modules/mediastream/RTCRtpReceiver.h | 2 +- .../WebCore/Modules/mediastream/RTCRtpSender.cpp | 4 ++-- Source/WebCore/Modules/mediastream/RTCRtpSender.h | 2 +- .../Modules/mediastream/RTCSessionDescription.cpp | 8 ++++---- .../Modules/mediastream/RTCSessionDescription.h | 4 ++-- 15 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStream.cpp b/Source/WebCore/Modules/mediastream/MediaStream.cpp index fb8f00a39eed4..87cc02eea4edd 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStream.cpp @@ -39,26 +39,26 @@ namespace WebCore { -RefPtr MediaStream::create(ScriptExecutionContext& context) +Ref MediaStream::create(ScriptExecutionContext& context) { return MediaStream::create(context, MediaStreamPrivate::create()); } -RefPtr MediaStream::create(ScriptExecutionContext& context, MediaStream* stream) +Ref MediaStream::create(ScriptExecutionContext& context, MediaStream* stream) { ASSERT(stream); - return adoptRef(new MediaStream(context, stream->getTracks())); + return adoptRef(*new MediaStream(context, stream->getTracks())); } -RefPtr MediaStream::create(ScriptExecutionContext& context, const Vector>& tracks) +Ref MediaStream::create(ScriptExecutionContext& context, const Vector>& tracks) { - return adoptRef(new MediaStream(context, tracks)); + return adoptRef(*new MediaStream(context, tracks)); } -RefPtr MediaStream::create(ScriptExecutionContext& context, RefPtr&& streamPrivate) +Ref MediaStream::create(ScriptExecutionContext& context, RefPtr&& streamPrivate) { - return adoptRef(new MediaStream(context, WTF::move(streamPrivate))); + return adoptRef(*new MediaStream(context, WTF::move(streamPrivate))); } MediaStream::MediaStream(ScriptExecutionContext& context, const Vector>& tracks) diff --git a/Source/WebCore/Modules/mediastream/MediaStream.h b/Source/WebCore/Modules/mediastream/MediaStream.h index b420d0de49439..d981887554dc4 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.h +++ b/Source/WebCore/Modules/mediastream/MediaStream.h @@ -52,10 +52,10 @@ class MediaStream final : public RefCounted, public URLRegistrable, virtual void didAddOrRemoveTrack() = 0; }; - static RefPtr create(ScriptExecutionContext&); - static RefPtr create(ScriptExecutionContext&, MediaStream*); - static RefPtr create(ScriptExecutionContext&, const Vector>&); - static RefPtr create(ScriptExecutionContext&, RefPtr&&); + static Ref create(ScriptExecutionContext&); + static Ref create(ScriptExecutionContext&, MediaStream*); + static Ref create(ScriptExecutionContext&, const Vector>&); + static Ref create(ScriptExecutionContext&, RefPtr&&); virtual ~MediaStream(); String id() const { return m_private->id(); } diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index dfc1a19a0d631..ccc07ca685909 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -47,9 +47,9 @@ namespace WebCore { -RefPtr MediaStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) +Ref MediaStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) { - return adoptRef(new MediaStreamTrack(context, privateTrack)); + return adoptRef(*new MediaStreamTrack(context, privateTrack)); } MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 3655f1eb14961..8a90af9a2ce94 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -56,7 +56,7 @@ class MediaStreamTrack final : public RefCounted, public Scrip virtual void trackDidEnd() = 0; }; - static RefPtr create(ScriptExecutionContext&, MediaStreamTrackPrivate&); + static Ref create(ScriptExecutionContext&, MediaStreamTrackPrivate&); virtual ~MediaStreamTrack(); const AtomicString& kind() const; diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp index da36cb46c24b1..d30a214b48787 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.cpp @@ -74,9 +74,9 @@ RefPtr RTCIceCandidate::create(const Dictionary& dictionary, Ex return adoptRef(new RTCIceCandidate(candidate, sdpMid, sdpMLineIndex)); } -RefPtr RTCIceCandidate::create(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex) +Ref RTCIceCandidate::create(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex) { - return adoptRef(new RTCIceCandidate(candidate, sdpMid, sdpMLineIndex)); + return adoptRef(*new RTCIceCandidate(candidate, sdpMid, sdpMLineIndex)); } RTCIceCandidate::RTCIceCandidate(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex) diff --git a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h index cf4ca9d2957ea..1778452b02f5f 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceCandidate.h +++ b/Source/WebCore/Modules/mediastream/RTCIceCandidate.h @@ -47,7 +47,7 @@ class RTCIceCandidateDescriptor; class RTCIceCandidate : public RefCounted, public ScriptWrappable { public: static RefPtr create(const Dictionary&, ExceptionCode&); - static RefPtr create(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex); + static Ref create(const String& candidate, const String& sdpMid, unsigned short sdpMLineIndex); virtual ~RTCIceCandidate(); const String& candidate() const; diff --git a/Source/WebCore/Modules/mediastream/RTCIceServer.h b/Source/WebCore/Modules/mediastream/RTCIceServer.h index 07057590ce675..5ba0d0dbd54f5 100644 --- a/Source/WebCore/Modules/mediastream/RTCIceServer.h +++ b/Source/WebCore/Modules/mediastream/RTCIceServer.h @@ -37,9 +37,9 @@ namespace WebCore { class RTCIceServer : public RefCounted { public: - static PassRefPtr create(const Vector& urls, const String& credential, const String& username) + static Ref create(const Vector& urls, const String& credential, const String& username) { - return adoptRef(new RTCIceServer(urls, credential, username)); + return adoptRef(*new RTCIceServer(urls, credential, username)); } virtual ~RTCIceServer() { } diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index cf4a10b9873dd..b7ad300b4c279 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -80,7 +80,7 @@ static RefPtr createMediaEndpointInit(RTCConfiguration& rtcCo return MediaEndpointInit::create(iceServers, rtcConfig.iceTransportPolicy(), rtcConfig.bundlePolicy()); } -PassRefPtr RTCPeerConnection::create(ScriptExecutionContext& context, const Dictionary& rtcConfiguration, ExceptionCode& ec) +RefPtr RTCPeerConnection::create(ScriptExecutionContext& context, const Dictionary& rtcConfiguration, ExceptionCode& ec) { printf("-> RTCConfiguration::create\n"); @@ -96,7 +96,7 @@ PassRefPtr RTCPeerConnection::create(ScriptExecutionContext& return nullptr; printf("RTCPeerConnection: before release\n"); - return peerConnection.release(); + return peerConnection; } RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr configuration, ExceptionCode& ec) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 03db99ee1725a..5b96859f54e81 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -60,7 +60,7 @@ class RTCStatsCallback; class RTCPeerConnection final : public RefCounted, public ScriptWrappable, public MediaEndpointClient, public EventTargetWithInlineData, public ActiveDOMObject { public: - static PassRefPtr create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, ExceptionCode&); + static RefPtr create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, ExceptionCode&); ~RTCPeerConnection(); typedef std::function OfferAnswerResolveCallback; diff --git a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp index 12bd342d70787..710a7edd219f3 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp +++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.cpp @@ -35,9 +35,9 @@ namespace WebCore { -RefPtr RTCRtpReceiver::create(RefPtr&& track) +Ref RTCRtpReceiver::create(RefPtr&& track) { - return adoptRef(new RTCRtpReceiver(WTF::move(track))); + return adoptRef(*new RTCRtpReceiver(WTF::move(track))); } RTCRtpReceiver::RTCRtpReceiver(RefPtr&& track) diff --git a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h index 83120a40a018c..520930aa43d5b 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h +++ b/Source/WebCore/Modules/mediastream/RTCRtpReceiver.h @@ -39,7 +39,7 @@ namespace WebCore { class RTCRtpReceiver : public RTCRtpSenderReceiverBase { public: - static RefPtr create(RefPtr&&); + static Ref create(RefPtr&&); virtual ~RTCRtpReceiver(); private: diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp index 3d957d374be26..4720945f0e033 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.cpp @@ -35,9 +35,9 @@ namespace WebCore { -RefPtr RTCRtpSender::create(RefPtr&& track, const String& mediaStreamId) +Ref RTCRtpSender::create(RefPtr&& track, const String& mediaStreamId) { - return adoptRef(new RTCRtpSender(WTF::move(track), mediaStreamId)); + return adoptRef(*new RTCRtpSender(WTF::move(track), mediaStreamId)); } RTCRtpSender::RTCRtpSender(RefPtr&& track, const String& mediaStreamId) diff --git a/Source/WebCore/Modules/mediastream/RTCRtpSender.h b/Source/WebCore/Modules/mediastream/RTCRtpSender.h index fc19cdd8e4a3c..df1081b7daaeb 100644 --- a/Source/WebCore/Modules/mediastream/RTCRtpSender.h +++ b/Source/WebCore/Modules/mediastream/RTCRtpSender.h @@ -40,7 +40,7 @@ namespace WebCore { class RTCRtpSender : public RTCRtpSenderReceiverBase { public: - static RefPtr create(RefPtr&&, const String& mediaStreamId); + static Ref create(RefPtr&&, const String& mediaStreamId); virtual ~RTCRtpSender(); const String& mediaStreamId() const { return m_mediaStreamId; } diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp index ef0b61747d256..dbe240671eef8 100644 --- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp +++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp @@ -63,14 +63,14 @@ RefPtr RTCSessionDescription::create(const Dictionary& di return adoptRef(new RTCSessionDescription(type, sdp)); } -RefPtr RTCSessionDescription::create(const RTCSessionDescription* description) +Ref RTCSessionDescription::create(const RTCSessionDescription* description) { - return adoptRef(new RTCSessionDescription(description->type(), description->sdp())); + return adoptRef(*new RTCSessionDescription(description->type(), description->sdp())); } -RefPtr RTCSessionDescription::create(const String& type, const String& sdp) +Ref RTCSessionDescription::create(const String& type, const String& sdp) { - return adoptRef(new RTCSessionDescription(type, sdp)); + return adoptRef(*new RTCSessionDescription(type, sdp)); } RTCSessionDescription::RTCSessionDescription(const String& type, const String& sdp) diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h index f6f1eec9e9881..60908607fbaa1 100644 --- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h +++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h @@ -46,8 +46,8 @@ class Dictionary; class RTCSessionDescription : public RefCounted, public ScriptWrappable { public: static RefPtr create(const Dictionary&, ExceptionCode&); - static RefPtr create(const RTCSessionDescription*); - static RefPtr create(const String& type, const String& sdp); + static Ref create(const RTCSessionDescription*); + static Ref create(const String& type, const String& sdp); virtual ~RTCSessionDescription(); const String& type() const; From c33e3f15163d6dae42ba17f518279fb3b7d57530 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Thu, 11 Jun 2015 12:07:28 +0200 Subject: [PATCH 113/155] RTCPeerConnection: Update Promise bindings (and stop throwing from Promise-based methods) --- .../Modules/mediastream/RTCPeerConnection.cpp | 27 +++++---- .../Modules/mediastream/RTCPeerConnection.h | 10 ++-- .../bindings/js/JSRTCPeerConnectionCustom.cpp | 57 ++++++++----------- 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index b7ad300b4c279..2fbb91db84824 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -283,13 +283,15 @@ static Vector> createDefaultPayloads(const String& type) return payloads; } -void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) +void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback) { if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; + RefPtr error = DOMError::create("InvalidStateError"); + rejectCallback(*error); return; } + ExceptionCode ec = 0; RefPtr options = RTCOfferOptions::create(offerOptions, ec); if (ec) { RefPtr error = DOMError::create("Invalid createOffer argument."); @@ -341,13 +343,15 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR resolveCallback(*offer); } -void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) +void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback) { if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; + RefPtr error = DOMError::create("InvalidStateError"); + rejectCallback(*error); return; } + ExceptionCode ec = 0; RefPtr options = RTCAnswerOptions::create(answerOptions, ec); if (ec) { RefPtr error = DOMError::create("Invalid createAnswer argument."); @@ -398,10 +402,11 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe resolveCallback(*answer); } -void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) +void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; + RefPtr error = DOMError::create("InvalidStateError"); + rejectCallback(*error); return; } @@ -479,10 +484,11 @@ static Vector> filterPayloads(const Vector error = DOMError::create("InvalidStateError"); + rejectCallback(*error); return; } @@ -556,10 +562,11 @@ void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionC m_mediaEndpoint->setConfiguration(createMediaEndpointInit(*m_configuration)); } -void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback, ExceptionCode& ec) +void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { if (m_signalingState == SignalingStateClosed) { - ec = INVALID_STATE_ERR; + RefPtr error = DOMError::create("InvalidStateError"); + rejectCallback(*error); return; } diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 5b96859f54e81..7b7127ea3952f 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -73,19 +73,19 @@ class RTCPeerConnection final : public RefCounted, public Scr RefPtr addTrack(RefPtr&&, const MediaStream* stream, ExceptionCode&); void removeTrack(RTCRtpSender*, ExceptionCode&); - void createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback, RejectCallback, ExceptionCode&); - void createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback, RejectCallback, ExceptionCode&); + void createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback, RejectCallback); + void createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback, RejectCallback); - void setLocalDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback, ExceptionCode&); + void setLocalDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback); RefPtr localDescription() const; - void setRemoteDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback, ExceptionCode&); + void setRemoteDescription(RTCSessionDescription*, VoidResolveCallback, RejectCallback); RefPtr remoteDescription() const; String signalingState() const; void updateIce(const Dictionary& rtcConfiguration, ExceptionCode&); - void addIceCandidate(RTCIceCandidate*, VoidResolveCallback, RejectCallback, ExceptionCode&); + void addIceCandidate(RTCIceCandidate*, VoidResolveCallback, RejectCallback); String iceGatheringState() const; String iceConnectionState() const; diff --git a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp index e28ab9befda8b..279d1b3b9bbc6 100644 --- a/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp +++ b/Source/WebCore/bindings/js/JSRTCPeerConnectionCustom.cpp @@ -77,10 +77,9 @@ EncodedJSValue JSC_HOST_CALL constructJSRTCPeerConnection(ExecState* exec) return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), RTCPeerConnection, peerConnection.get())); } -static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnection::*implFunction)(const Dictionary&, RTCPeerConnection::OfferAnswerResolveCallback, RTCPeerConnection::RejectCallback, ExceptionCode&), JSDOMGlobalObject* globalObject, ExecState* exec) +static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnection::*implFunction)(const Dictionary&, RTCPeerConnection::OfferAnswerResolveCallback, RTCPeerConnection::RejectCallback), JSDOMGlobalObject* globalObject, ExecState* exec) { Dictionary options; - ExceptionCode ec = 0; if (exec->argumentCount() > 1 && exec->argument(0).isFunction() && exec->argument(1).isFunction()) { // legacy callbacks mode @@ -109,8 +108,8 @@ static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnect }); }; - (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec); - setDOMException(exec, ec); + (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback)); + return jsUndefined(); } @@ -123,7 +122,9 @@ static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnect } } - DeferredWrapper wrapper(exec, globalObject); + JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(exec, globalObject); + DeferredWrapper wrapper(exec, globalObject, promiseDeferred); + auto resolveCallback = [wrapper](RTCSessionDescription &description) mutable { wrapper.resolve(&description); }; @@ -131,13 +132,9 @@ static JSValue createOfferOrAnswer(RTCPeerConnection& impl, void (RTCPeerConnect wrapper.reject(&error); }; - (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback), ec); - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } + (impl.*implFunction)(options, WTF::move(resolveCallback), WTF::move(rejectCallback)); - return wrapper.promise(); + return promiseDeferred->promise(); } JSValue JSRTCPeerConnection::createOffer(ExecState* exec) @@ -150,10 +147,8 @@ JSValue JSRTCPeerConnection::createAnswer(ExecState* exec) return createOfferOrAnswer(impl(), &RTCPeerConnection::createAnswer, globalObject(), exec); } -static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPeerConnection::*implFunction)(RTCSessionDescription*, RTCPeerConnection::VoidResolveCallback, RTCPeerConnection::RejectCallback, ExceptionCode&), JSDOMGlobalObject* globalObject, ExecState* exec) +static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPeerConnection::*implFunction)(RTCSessionDescription*, RTCPeerConnection::VoidResolveCallback, RTCPeerConnection::RejectCallback), JSDOMGlobalObject* globalObject, ExecState* exec) { - ExceptionCode ec = 0; - RefPtr description = JSRTCSessionDescription::toWrapped(exec->argument(0)); if (!description) { throwVMError(exec, createTypeError(exec, "First argument must be a RTCSessionDescription")); @@ -178,13 +173,15 @@ static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPee }); }; - (impl.*implFunction)(description.get() , WTF::move(resolveCallback), WTF::move(rejectCallback), ec); - setDOMException(exec, ec); + (impl.*implFunction)(description.get() , WTF::move(resolveCallback), WTF::move(rejectCallback)); + return jsUndefined(); } // Promised-based mode - DeferredWrapper wrapper(exec, globalObject); + JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(exec, globalObject); + DeferredWrapper wrapper(exec, globalObject, promiseDeferred); + auto resolveCallback = [wrapper]() mutable { wrapper.resolve(false); }; @@ -192,13 +189,9 @@ static JSValue setLocalOrRemoteDescription(RTCPeerConnection& impl, void (RTCPee wrapper.reject(&error); }; - (impl.*implFunction)(description.get(), WTF::move(resolveCallback), WTF::move(rejectCallback), ec); - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } + (impl.*implFunction)(description.get(), WTF::move(resolveCallback), WTF::move(rejectCallback)); - return wrapper.promise(); + return promiseDeferred->promise(); } JSValue JSRTCPeerConnection::setLocalDescription(ExecState* exec) @@ -213,8 +206,6 @@ JSValue JSRTCPeerConnection::setRemoteDescription(ExecState* exec) JSValue JSRTCPeerConnection::addIceCandidate(ExecState* exec) { - ExceptionCode ec = 0; - RefPtr candidate = JSRTCIceCandidate::toWrapped(exec->argument(0)); if (!candidate) { throwVMError(exec, createTypeError(exec, "First argument must be a RTCIceCandidate")); @@ -239,13 +230,15 @@ JSValue JSRTCPeerConnection::addIceCandidate(ExecState* exec) }); }; - impl().addIceCandidate(candidate.get() , WTF::move(resolveCallback), WTF::move(rejectCallback), ec); - setDOMException(exec, ec); + impl().addIceCandidate(candidate.get() , WTF::move(resolveCallback), WTF::move(rejectCallback)); + return jsUndefined(); } // Promised-based mode - DeferredWrapper wrapper(exec, globalObject()); + JSPromiseDeferred* promiseDeferred = JSPromiseDeferred::create(exec, globalObject()); + DeferredWrapper wrapper(exec, globalObject(), promiseDeferred); + auto resolveCallback = [wrapper]() mutable { wrapper.resolve(false); }; @@ -253,13 +246,9 @@ JSValue JSRTCPeerConnection::addIceCandidate(ExecState* exec) wrapper.reject(&error); }; - impl().addIceCandidate(candidate.get(), WTF::move(resolveCallback), WTF::move(rejectCallback), ec); - if (ec) { - setDOMException(exec, ec); - return jsUndefined(); - } + impl().addIceCandidate(candidate.get(), WTF::move(resolveCallback), WTF::move(rejectCallback)); - return wrapper.promise(); + return promiseDeferred->promise(); } } // namespace WebCore From fd5a433a1013a2dd75d5c4971f0cbe331bda348e Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 15 Jun 2015 11:46:07 +0200 Subject: [PATCH 114/155] MediaStreamTrack: Remove 'detach source' concept --- .../Modules/mediastream/MediaStreamTrack.cpp | 7 +- .../mediastream/MediaStreamTrackPrivate.cpp | 64 +++++++++---------- .../mediastream/MediaStreamTrackPrivate.h | 20 +++--- .../mediastream/RealtimeMediaSource.cpp | 20 +++++- .../mediastream/RealtimeMediaSource.h | 3 +- 5 files changed, 60 insertions(+), 54 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index ccc07ca685909..8ef2f06b39908 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -134,12 +134,12 @@ void MediaStreamTrack::stopProducingData() // the "ImplementedAs" IDL attribute. This is done because ActiveDOMObject requires // a "stop" method. - if (remote()) + if (remote() || ended()) return; m_isEnded = true; - m_private->detachSource(); + m_private->endTrack(); } RefPtr MediaStreamTrack::getConstraints() const @@ -202,9 +202,6 @@ void MediaStreamTrack::trackEnded() m_isEnded = true; - // The spec says "detach source" here, but the source is already detached by the - // platform object at this point. - dispatchEvent(Event::create(eventNames().endedEvent, false, false)); for (auto& observer : m_observers) diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index fa24faf0166c7..e335ae041b334 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -50,47 +50,47 @@ MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& : RefCounted() , m_source(other.source()) , m_client(nullptr) - , m_type(other.type()) , m_id(createCanonicalUUIDString()) - , m_label(other.label()) , m_enabled(other.enabled()) - , m_isReadonly(other.readonly()) - , m_isRemote(other.remote()) + , m_isEnded(other.ended()) { - // This constructor is only used by the clone() function and the cloned track (other) may have - // been detached from its source. - if (m_source) - m_source->addObserver(this); + m_source->addObserver(this); } MediaStreamTrackPrivate::MediaStreamTrackPrivate(RefPtr&& source, const String& id) : RefCounted() , m_source(source) , m_client(nullptr) - , m_type(m_source->type()) , m_id(id) - , m_label(m_source->name()) , m_enabled(true) - , m_isReadonly(m_source->readonly()) - , m_isRemote(m_source->remote()) + , m_isEnded(false) { m_source->addObserver(this); } MediaStreamTrackPrivate::~MediaStreamTrackPrivate() { - if (m_source) - m_source->removeObserver(this); + m_source->removeObserver(this); } -bool MediaStreamTrackPrivate::ended() const +const String& MediaStreamTrackPrivate::label() const { - return m_source ? m_source->stopped() : true; + return m_source->name(); } bool MediaStreamTrackPrivate::muted() const { - return m_source ? m_source->muted() : true; + return m_source->muted(); +} + +bool MediaStreamTrackPrivate::readonly() const +{ + return m_source->readonly(); +} + +bool MediaStreamTrackPrivate::remote() const +{ + return m_source->remote(); } void MediaStreamTrackPrivate::setEnabled(bool enabled) @@ -99,14 +99,13 @@ void MediaStreamTrackPrivate::setEnabled(bool enabled) m_enabled = enabled; } -void MediaStreamTrackPrivate::detachSource() +void MediaStreamTrackPrivate::endTrack() { - if (!m_source) + if (ended()) return; - // The source will stop itself when out of consumers (observers in this case). - m_source->removeObserver(this); - m_source = nullptr; + m_isEnded = true; + m_source->requestStop(this); } RefPtr MediaStreamTrackPrivate::clone() @@ -114,6 +113,11 @@ RefPtr MediaStreamTrackPrivate::clone() return adoptRef(new MediaStreamTrackPrivate(*this)); } +RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const +{ + return m_source->type(); +} + RefPtr MediaStreamTrackPrivate::constraints() const { return m_constraints; @@ -121,19 +125,11 @@ RefPtr MediaStreamTrackPrivate::constraints() const const RealtimeMediaSourceStates& MediaStreamTrackPrivate::states() const { - if (!m_source) { - DEPRECATED_DEFINE_STATIC_LOCAL(const RealtimeMediaSourceStates, noState, ()); - return noState; - } - return m_source->states(); } RefPtr MediaStreamTrackPrivate::capabilities() const { - if (!m_source) - return 0; - return m_source->capabilities(); } @@ -145,8 +141,10 @@ void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints&) void MediaStreamTrackPrivate::sourceReadyStateChanged() { - // Don't depend on the client to detach the source. - detachSource(); + if (ended()) + return; + + m_isEnded = true; if (m_client) m_client->trackEnded(); @@ -165,7 +163,7 @@ void MediaStreamTrackPrivate::sourceEnabledChanged() bool MediaStreamTrackPrivate::observerIsEnabled() { - return enabled(); + return !m_isEnded; } } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index a1da3ad4ad445..7e1ec333fc57c 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -53,14 +53,14 @@ class MediaStreamTrackPrivate : public RefCounted, publ virtual ~MediaStreamTrackPrivate(); const String& id() const { return m_id; } - const String& label() const { return m_label; } + const String& label() const; - bool ended() const; + bool ended() const { return m_isEnded; } bool muted() const; - bool readonly() const { return m_isReadonly; } - bool remote() const { return m_isRemote; } + bool readonly() const; + bool remote() const; bool enabled() const { return m_enabled; } void setEnabled(bool); @@ -68,12 +68,11 @@ class MediaStreamTrackPrivate : public RefCounted, publ RefPtr clone(); RealtimeMediaSource* source() const { return m_source.get(); } + RealtimeMediaSource::Type type() const; - void detachSource(); - - void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; } + void endTrack(); - RealtimeMediaSource::Type type() const { return m_type; } + void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; } const RealtimeMediaSourceStates& states() const; RefPtr capabilities() const; @@ -99,12 +98,9 @@ class MediaStreamTrackPrivate : public RefCounted, publ MediaStreamTrackPrivateClient* m_client; RefPtr m_constraints; - RealtimeMediaSource::Type m_type; String m_id; - String m_label; bool m_enabled; - bool m_isReadonly; - bool m_isRemote; + bool m_isEnded; }; } // namespace WebCore diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp index ddda564d34973..0c03d82678c6e 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp @@ -99,20 +99,34 @@ bool RealtimeMediaSource::readonly() const return m_readonly; } -void RealtimeMediaSource::stop() +void RealtimeMediaSource::stop(Observer* callingObserver) { if (stopped()) return; m_stopped = true; - for (auto& observer : m_observers) - observer->sourceReadyStateChanged(); + for (auto observer : m_observers) { + if (observer != callingObserver) + observer->sourceReadyStateChanged(); + } // There are no more consumers of this source's data, shut it down as appropriate. stopProducingData(); } +void RealtimeMediaSource::requestStop(Observer* callingObserver) +{ + if (stopped()) + return; + + for (auto observer : m_observers) { + if (observer->observerIsEnabled()) + return; + } + stop(callingObserver); +} + } // namespace WebCore #endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h index 879e1782f78a7..7618f55406175 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h @@ -98,7 +98,8 @@ class RealtimeMediaSource : public RefCounted { virtual void startProducingData() { } virtual void stopProducingData() { } - void stop(); + void stop(Observer* callingObserver = nullptr); + void requestStop(Observer* callingObserver = nullptr); void reset(); From abf4098bf0228a0946cc4b0aa5b5dd49a1c07905 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 16 Jun 2015 18:19:11 +0200 Subject: [PATCH 115/155] getUserMedia: Updated legacy binding and unskipped some tests --- .../mediastream/argument-types-expected.txt | 42 +++++++++--------- .../mediastream/getusermedia-expected.txt | 6 +++ .../fast/mediastream/getusermedia.html | 9 ++++ .../script-tests/argument-types.js | 44 +++++++++---------- LayoutTests/platform/gtk/TestExpectations | 3 -- .../WebCore/bindings/js/JSNavigatorCustom.cpp | 20 ++++----- 6 files changed, 66 insertions(+), 58 deletions(-) diff --git a/LayoutTests/fast/mediastream/argument-types-expected.txt b/LayoutTests/fast/mediastream/argument-types-expected.txt index 0b94be6b461df..4224d40202299 100644 --- a/LayoutTests/fast/mediastream/argument-types-expected.txt +++ b/LayoutTests/fast/mediastream/argument-types-expected.txt @@ -13,30 +13,30 @@ PASS navigator.webkitGetUserMedia(42) threw exception TypeError: Not enough argu PASS navigator.webkitGetUserMedia(Infinity) threw exception TypeError: Not enough arguments. PASS navigator.webkitGetUserMedia(-Infinity) threw exception TypeError: Not enough arguments. PASS navigator.webkitGetUserMedia(emptyFunction) threw exception TypeError: Not enough arguments. -PASS navigator.webkitGetUserMedia({video: true}, emptyFunction) did not throw exception. -PASS navigator.webkitGetUserMedia(undefined, emptyFunction) threw exception TypeError: First argument of webkitGetUserMedia must be a valid Dictionary. -PASS navigator.webkitGetUserMedia(null, emptyFunction) threw exception TypeError: First argument of webkitGetUserMedia must be a valid Dictionary. -PASS navigator.webkitGetUserMedia({ }, emptyFunction) threw exception Error: NotSupportedError: DOM Exception 9. -PASS navigator.webkitGetUserMedia(true, emptyFunction) threw exception TypeError: First argument of webkitGetUserMedia must be a valid Dictionary. -PASS navigator.webkitGetUserMedia(42, emptyFunction) threw exception TypeError: First argument of webkitGetUserMedia must be a valid Dictionary. -PASS navigator.webkitGetUserMedia(Infinity, emptyFunction) threw exception TypeError: First argument of webkitGetUserMedia must be a valid Dictionary. -PASS navigator.webkitGetUserMedia(-Infinity, emptyFunction) threw exception TypeError: First argument of webkitGetUserMedia must be a valid Dictionary. -PASS navigator.webkitGetUserMedia(emptyFunction, emptyFunction) threw exception Error: NotSupportedError: DOM Exception 9. -PASS navigator.webkitGetUserMedia({video: true}, "foobar") threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, undefined) threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, null) threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, {}) threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, true) threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, 42) threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, Infinity) threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, -Infinity) threw exception TypeError: Argument 2 ('successCallback') to Navigator.webkitGetUserMedia must be a function. +PASS navigator.webkitGetUserMedia({video: true}, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia(undefined, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia(null, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({ }, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia(true, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia(42, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia(Infinity, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia(-Infinity, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia(emptyFunction, emptyFunction) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, "foobar") threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, undefined) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, null) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, {}) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, true) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, 42) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, Infinity) threw exception TypeError: Not enough arguments. +PASS navigator.webkitGetUserMedia({video: true}, -Infinity) threw exception TypeError: Not enough arguments. PASS navigator.webkitGetUserMedia({ }, emptyFunction, emptyFunction) threw exception Error: NotSupportedError: DOM Exception 9. PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, emptyFunction) did not throw exception. -PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, undefined) did not throw exception. -PASS navigator.webkitGetUserMedia({audio:true, video:true}, emptyFunction, undefined) did not throw exception. -PASS navigator.webkitGetUserMedia({audio:true}, emptyFunction, undefined) did not throw exception. +PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, undefined) threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. +PASS navigator.webkitGetUserMedia({audio:true, video:true}, emptyFunction, undefined) threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. +PASS navigator.webkitGetUserMedia({audio:true}, emptyFunction, undefined) threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, "video") threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. -PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, null) did not throw exception. +PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, null) threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, {}) threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, true) threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({video: true}, emptyFunction, 42) threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. diff --git a/LayoutTests/fast/mediastream/getusermedia-expected.txt b/LayoutTests/fast/mediastream/getusermedia-expected.txt index a6856f2d96560..dca5fb961cf6e 100644 --- a/LayoutTests/fast/mediastream/getusermedia-expected.txt +++ b/LayoutTests/fast/mediastream/getusermedia-expected.txt @@ -4,26 +4,32 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE PASS navigator.webkitGetUserMedia({audio:false, video:false}, error, error); threw exception Error: NotSupportedError: DOM Exception 9. +PASS navigator.webkitGetUserMedia({audio:false, video:false}, error, null); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({audio:true}, gotStream1, error); did not throw exception. PASS Stream generated. PASS stream.getAudioTracks().length is 1 PASS stream.getVideoTracks().length is 0 +PASS navigator.webkitGetUserMedia({video:true}, gotStream2, null); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({video:true}, gotStream2, error); did not throw exception. PASS Stream generated. PASS stream.getAudioTracks().length is 0 PASS stream.getVideoTracks().length is 1 +PASS navigator.webkitGetUserMedia({audio:true, video:true}, gotStream3, null); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({audio:true, video:true}, gotStream3, error); did not throw exception. PASS Stream generated. PASS stream.getAudioTracks().length is 1 PASS stream.getVideoTracks().length is 1 +PASS navigator.webkitGetUserMedia({audio:{mandatory:{}, optional:[]}, video:true}, gotStream4, null); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({audio:{mandatory:{}, optional:[]}, video:true}, gotStream4, error); did not throw exception. PASS Stream generated. PASS stream.getAudioTracks().length is 1 PASS stream.getVideoTracks().length is 1 +PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, null); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_but_unsupported_1':0}, optional:[]}, video:true}, gotStreamInError, error1); did not throw exception. PASS Error callback called. PASS errorArg.name is "ConstraintNotSatisfiedError" PASS errorArg.constraintName is "valid_but_unsupported_1" +PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream5, 0); threw exception TypeError: Argument 3 ('errorCallback') to Navigator.webkitGetUserMedia must be a function. PASS navigator.webkitGetUserMedia({audio:{mandatory:{'valid_and_supported_1':1}, optional:[{'valid_but_unsupported_1':0}]}, video:true}, gotStream5, error); did not throw exception. PASS Stream generated. PASS stream.getAudioTracks().length is 1 diff --git a/LayoutTests/fast/mediastream/getusermedia.html b/LayoutTests/fast/mediastream/getusermedia.html index c817e9901d7e2..13fae130672bd 100644 --- a/LayoutTests/fast/mediastream/getusermedia.html +++ b/LayoutTests/fast/mediastream/getusermedia.html @@ -9,6 +9,13 @@ + +

@@ -14,20 +15,6 @@ var audioTrack; var videoTrack; - function error() { - testFailed('Stream generation failed.'); - finishJSTest(); - } - - function getUserMedia(dictionary, callback) { - try { - navigator.webkitGetUserMedia(dictionary, callback, error); - } catch (e) { - testFailed('webkitGetUserMedia threw exception :' + e); - finishJSTest(); - } - } - function tryAddTrack(stream, track) { try { stream.addTrack(track); @@ -51,13 +38,21 @@ } function shouldFireActive() { - debug("Stream2 is active."); + debug("
Stream2 is active."); + shouldBe('stream2.active', 'true'); finishJSTest(); } function shouldFireInActive() { - debug("Stream2 is inactive."); - finishJSTest(); + debug("
Stream2 is inactive."); + shouldBe('stream2.active', 'false'); + + debug("
*** add non-ended track"); + shouldNotBe('audioTrack.readyState', '"ended"'); + tryAddTrack(stream2, audioTrack); + + debug("
*** active attribute is still false (until event is fired)"); + shouldBe('stream2.active', 'false'); } function gotStream2(s) { @@ -124,22 +119,22 @@ shouldBe('stream1.getAudioTracks().length', '2'); shouldBe('stream1.getVideoTracks().length', '2'); - debug("
*** remove all tracks, stream.ended should return true"); + debug("
*** remove all tracks, stream will become inactive"); tryRemoveTrack(stream2, stream2.getAudioTracks()[0]); tryRemoveTrack(stream2, stream2.getVideoTracks()[0]); shouldBe('stream2.getAudioTracks().length', '0'); shouldBe('stream2.getVideoTracks().length', '0'); - debug("
*** it should be impossible to remove a track after the stream has ended"); - shouldThrow('stream2.removeTrack(audioTrack)', '"Error: InvalidStateError: DOM Exception 11"'); + debug("
*** active attribute is still true (until event is fired)"); + shouldBe('stream2.active', 'true'); } function gotStream1(s) { stream1 = s; - getUserMedia({audio:true, video:true}, gotStream2); + getUserMedia("allow", {audio:true, video:true}, gotStream2); } - getUserMedia({audio:true, video:true}, gotStream1); + getUserMedia("allow", {audio:true, video:true}, gotStream1); window.jsTestIsAsync = true; window.successfullyParsed = true; diff --git a/LayoutTests/fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html b/LayoutTests/fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html index be9ba5e7b17d2..620bb32a6e9da 100644 --- a/LayoutTests/fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html +++ b/LayoutTests/fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html @@ -2,28 +2,13 @@ + + + + +

@@ -40,20 +41,6 @@ return true; } - function error() { - testFailed('Stream generation failed.'); - finishJSTest(); - } - - function getUserMedia(dictionary, callback) { - try { - navigator.webkitGetUserMedia(dictionary, callback, error); - } catch (e) { - testFailed('webkitGetUserMedia threw exception :' + e); - finishJSTest(); - } - } - function gotStream(s) { localStream = s; testPassed('Got local stream.'); @@ -104,7 +91,7 @@ shouldBeTrue('checkIdAttribute(newStream.id)'); } - getUserMedia({video:true, audio:true}, gotStream); + getUserMedia("allow", {video:true, audio:true}, gotStream); window.jsTestIsAsync = true; window.successfullyParsed = true; diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-clone-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrack-clone-expected.txt new file mode 100644 index 0000000000000..9ef68ded54474 --- /dev/null +++ b/LayoutTests/fast/mediastream/MediaStreamTrack-clone-expected.txt @@ -0,0 +1,26 @@ +Tests MediaStreamTrack.clone() + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS getUserMedia succeeded. + +videoTrack = mediaStream.getVideoTracks()[0] +Initialize event handler attributes on videoTrack + +videoTrack2 = videoTrack.clone() +PASS videoTrack.id is not videoTrack2.id +PASS videoTrack.kind is videoTrack2.kind +PASS videoTrack.label is videoTrack2.label +PASS videoTrack.muted is videoTrack2.muted +PASS videoTrack.enabled is videoTrack2.enabled +PASS videoTrack.readyState is videoTrack2.readyState +PASS videoTrack.onmute is not videoTrack2.onmute +PASS videoTrack.onunmute is not videoTrack2.onunmute +PASS videoTrack.onended is not videoTrack2.onended +PASS videoTrack.onoverconstrained is not videoTrack2.onoverconstrained +PASS videoTrack.readyState is not videoTrack2.readyState +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-clone.html b/LayoutTests/fast/mediastream/MediaStreamTrack-clone.html new file mode 100644 index 0000000000000..17c6f1d1495fe --- /dev/null +++ b/LayoutTests/fast/mediastream/MediaStreamTrack-clone.html @@ -0,0 +1,60 @@ + + + + + + + + +

+
+ + + diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-getSources-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrack-getSources-expected.txt deleted file mode 100644 index 0d0a43ba9af2d..0000000000000 --- a/LayoutTests/fast/mediastream/MediaStreamTrack-getSources-expected.txt +++ /dev/null @@ -1,34 +0,0 @@ -Tests MediaStreamTrack::getSources. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - - -*** calling MediaStreamTrack.getSources() *** -PASS MediaStreamTrack.getSources(gotSources1); did not throw exception. -PASS callback called. -sources1[0].sourceId = "239c24b1-2b15-11e3-8224-0800200c9a66" -sources1[0].label = "Mock audio device" -sources1[0].kind = "audio" -sources1[1].sourceId = "239c24b0-2b15-11e3-8224-0800200c9a66" -sources1[1].label = "Mock video device" -sources1[1].kind = "video" - -*** calling navigator.webkitGetUserMedia() *** -PASS navigator.webkitGetUserMedia(constraints, callback, error) did not throw exception. -PASS callback called. - -*** calling MediaStreamTrack.getSources() *** -PASS MediaStreamTrack.getSources(gotSources2); did not throw exception. -PASS callback called. -PASS sources2.length == sources1.length is true -PASS sources2[0].sourceId === sources1[0].sourceId is true -PASS sources2[0].label === sources1[0].label is true -PASS sources2[0].kind === sources1[0].kind is true -PASS sources2[1].sourceId === sources1[1].sourceId is true -PASS sources2[1].label === sources1[1].label is true -PASS sources2[1].kind === sources1[1].kind is true -PASS successfullyParsed is true - -TEST COMPLETE - diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-getSources.html b/LayoutTests/fast/mediastream/MediaStreamTrack-getSources.html deleted file mode 100644 index 44cd3c899b70d..0000000000000 --- a/LayoutTests/fast/mediastream/MediaStreamTrack-getSources.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - -

-
- - - - diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-kind-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrack-kind-expected.txt new file mode 100644 index 0000000000000..06c6b430135aa --- /dev/null +++ b/LayoutTests/fast/mediastream/MediaStreamTrack-kind-expected.txt @@ -0,0 +1,13 @@ +Test MediaStreamTrack kind + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS mediaStream.getVideoTracks().length is 1 +PASS mediaStream.getAudioTracks().length is 1 +PASS mediaStream.getAudioTracks()[0].kind is "audio" +PASS mediaStream.getVideoTracks()[0].kind is "video" +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-kind.html b/LayoutTests/fast/mediastream/MediaStreamTrack-kind.html new file mode 100644 index 0000000000000..689606af6554d --- /dev/null +++ b/LayoutTests/fast/mediastream/MediaStreamTrack-kind.html @@ -0,0 +1,35 @@ + + + + + + + + +

+
+ + + diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-stop-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrack-stop-expected.txt new file mode 100644 index 0000000000000..47f36ebc8fcad --- /dev/null +++ b/LayoutTests/fast/mediastream/MediaStreamTrack-stop-expected.txt @@ -0,0 +1,32 @@ +Test MediaStreamTrack stop() + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +*** extract track +PASS track.readyState is "live" +*** store track attributes that should be preserved +kind = track.kind +id = track.id +label = track.label +enabled = track.enabled +readonly = track.readonly +remote = track.remote +muted = track.muted +*** stop track +PASS track.readyState is "ended" +*** compare against stored attribute values +PASS track.kind is kind +PASS track.id is id +PASS track.label is label +PASS track.enabled is enabled +PASS track.readonly is readonly +PASS track.remote is remote +PASS track.muted is muted +*** toggle enable (should now throw) +PASS track.enabled = !track.enabled did not throw exception. +PASS track.enabled is not enabled +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/mediastream/MediaStreamTrack-stop.html b/LayoutTests/fast/mediastream/MediaStreamTrack-stop.html new file mode 100644 index 0000000000000..8c750e9b6349f --- /dev/null +++ b/LayoutTests/fast/mediastream/MediaStreamTrack-stop.html @@ -0,0 +1,64 @@ + + + + + + + + +

+
+ + + diff --git a/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt b/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt index 8a5994ac82f13..bbfb4a4dca030 100644 --- a/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt +++ b/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor-expected.txt @@ -3,7 +3,6 @@ This tests the constructor for the MediaStreamTrackEvent DOM class. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". -PASS getUserMedia({audio:true, video:true}, gotStream) did not throw exception. *** getUserMedia() succeeded, test stream *** PASS mediaStream is non-null. diff --git a/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor.html b/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor.html index 067795c1633ad..561c46c7678f4 100644 --- a/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor.html +++ b/LayoutTests/fast/mediastream/MediaStreamTrackEvent-constructor.html @@ -2,6 +2,7 @@ + diff --git a/LayoutTests/fast/mediastream/resources/getUserMedia-helper.js b/LayoutTests/fast/mediastream/resources/getUserMedia-helper.js new file mode 100644 index 0000000000000..6225aafeb235e --- /dev/null +++ b/LayoutTests/fast/mediastream/resources/getUserMedia-helper.js @@ -0,0 +1,22 @@ +function getUserMedia(permission, constraints, successCallback, errorCallback) { + if (window.testRunner) + testRunner.setUserMediaPermission(permission == "allow"); + else { + debug("This test can not be run without the testRunner"); + finishJSTest(); + } + + navigator.mediaDevices.getUserMedia(constraints).then(successCallback, reject).catch(defaultRejectOrCatch); + + function reject(e) { + if (errorCallback) + errorCallback(e); + else + defaultRejectOrCatch(e); + } +} + +function defaultRejectOrCatch(e) { + testFailed('getUserMedia failed:' + e); + finishJSTest(); +} diff --git a/LayoutTests/platform/gtk/TestExpectations b/LayoutTests/platform/gtk/TestExpectations index 8d51e35bfea42..55ca3e6063200 100644 --- a/LayoutTests/platform/gtk/TestExpectations +++ b/LayoutTests/platform/gtk/TestExpectations @@ -314,16 +314,7 @@ webkit.org/b/85211 ietestcenter/css3/flexbox/flexbox-align-stretch-001.htm [ Ima webkit.org/b/85212 ietestcenter/css3/flexbox/flexbox-layout-002.htm [ ImageOnlyFailure ] # Mediastream implementation is not complete yet. -webkit.org/b/79203 fast/mediastream/MediaStream-add-ended-tracks.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStream-add-remove-tracks.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStream-add-tracks-to-inactive-stream.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStream-clone.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStreamConstructor.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStream-construct-with-ended-tracks.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStream-getTracks.html [ Skip ] webkit.org/b/79203 fast/mediastream/MediaStream-MediaElement-srcObject.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStreamTrackEvent-constructor.html [ Skip ] -webkit.org/b/79203 fast/mediastream/MediaStreamTrack-getSources.html [ Skip ] webkit.org/b/79203 fast/mediastream/MediaStreamTrack.html [ Skip ] webkit.org/b/79203 fast/mediastream/MediaStreamTrack-onended.html [ Skip ] webkit.org/b/79203 fast/mediastream/RTCIceCandidate.html [ Skip ] From cc4ad25a2c2f635e22880f1a977303241f49509d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 23 Jun 2015 14:22:27 +0200 Subject: [PATCH 117/155] MediaStreamTrack: Remove unused event scheduling functions --- .../Modules/mediastream/MediaStreamTrack.cpp | 28 ------------------- .../Modules/mediastream/MediaStreamTrack.h | 5 ---- 2 files changed, 33 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 8ef2f06b39908..4dede4861f4c9 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -55,7 +55,6 @@ Ref MediaStreamTrack::create(ScriptExecutionContext& context, MediaStreamTrack::MediaStreamTrack(ScriptExecutionContext& context, MediaStreamTrackPrivate& privateTrack) : RefCounted() , ActiveDOMObject(&context) - , m_eventDispatchScheduled(false) , m_private(privateTrack) , m_isMuted(m_private->muted()) , m_isEnded(m_private->ended()) @@ -245,33 +244,6 @@ bool MediaStreamTrack::canSuspendForPageCache() const return false; } -void MediaStreamTrack::scheduleEventDispatch(RefPtr&& event) -{ - { - MutexLocker locker(m_mutex); - m_scheduledEvents.append(event); - if (m_eventDispatchScheduled) - return; - m_eventDispatchScheduled = true; - } - - RefPtr protectedThis(this); - callOnMainThread([protectedThis] { - Vector> events; - { - MutexLocker locker(protectedThis->m_mutex); - protectedThis->m_eventDispatchScheduled = false; - events = WTF::move(protectedThis->m_scheduledEvents); - } - - if (!protectedThis->scriptExecutionContext()) - return; - - for (auto& event : events) - protectedThis->dispatchEvent(event.release()); - }); -} - } // namespace WebCore #endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 8a90af9a2ce94..743b1c46184ac 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -101,7 +101,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip explicit MediaStreamTrack(MediaStreamTrack&); void configureTrackRendering(); - void scheduleEventDispatch(RefPtr&&); // ActiveDOMObject API. void stop() override final; @@ -116,10 +115,6 @@ class MediaStreamTrack final : public RefCounted, public Scrip void trackEnded(); void trackMutedChanged(); - Vector> m_scheduledEvents; - bool m_eventDispatchScheduled; - Mutex m_mutex; - Vector m_observers; Ref m_private; From 550b6ef52e5b8d771a2481ef4e63c15e0dace53f Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Tue, 23 Jun 2015 15:01:29 +0200 Subject: [PATCH 118/155] Add/update copyright stuff --- Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp | 2 +- Source/WebCore/Modules/mediastream/MediaStreamTrack.h | 2 +- Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp | 1 + Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h | 1 + Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp index 4dede4861f4c9..bdf44695d3a88 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. - * Copyright (C) 2011 Ericsson AB. All rights reserved. + * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved. * Copyright (C) 2013 Apple Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). * diff --git a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h index 743b1c46184ac..f4402e9068481 100644 --- a/Source/WebCore/Modules/mediastream/MediaStreamTrack.h +++ b/Source/WebCore/Modules/mediastream/MediaStreamTrack.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google Inc. All rights reserved. - * Copyright (C) 2011 Ericsson AB. All rights reserved. + * Copyright (C) 2011, 2015 Ericsson AB. All rights reserved. * Copyright (C) 2013 Apple Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). * diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp index e335ae041b334..ab977b32fee36 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h index 7e1ec333fc57c..298623d6b033f 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h +++ b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp index 0c03d82678c6e..a71af8a60617d 100644 --- a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp +++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2012 Google Inc. All rights reserved. * Copyright (C) 2013 Apple Inc. All rights reserved. * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2015 Ericsson AB. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions From 66b84a45f37bdecf66cd2800f4a48278bc4a481d Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Wed, 24 Jun 2015 15:30:43 +0200 Subject: [PATCH 119/155] MediaStreamPrivate: Remove bad WTF::move() --- Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp index a563ad55f7661..69b0b0b507782 100644 --- a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp +++ b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp @@ -114,7 +114,7 @@ void MediaStreamPrivate::addTrack(RefPtr&& track, Notif if (m_trackSet.contains(track->id())) return; - m_trackSet.add(track->id(), WTF::move(track)); + m_trackSet.add(track->id(), track); if (m_client && notifyClientOption == NotifyClient) m_client->didAddTrackToPrivate(*track.get()); From 09fff9fa4fc58ab652c1b091c08e03547da9674a Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Fri, 26 Jun 2015 13:04:22 +0200 Subject: [PATCH 120/155] Use OpenWebRTC if MEDIA_STREAM is enabled --- Source/cmake/OptionsWPE.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake index 7326a6bb3ad98..b84a0d22b1e39 100644 --- a/Source/cmake/OptionsWPE.cmake +++ b/Source/cmake/OptionsWPE.cmake @@ -37,6 +37,8 @@ if (ENABLE_DXDRM) add_definitions(-DUSE_DXDRM=1) endif () + + set(ENABLE_WEBCORE ON) set(ENABLE_WEBKIT OFF) set(ENABLE_WEBKIT2 ON) @@ -88,6 +90,11 @@ else () endif () endif () +if (ENABLE_MEDIA_STREAM) + find_package(OpenWebRTC REQUIRED) + add_definitions(-DUSE_OPENWEBRTC) +endif () + if (ENABLE_SUBTLE_CRYPTO) find_package(GnuTLS 3.0.0) if (NOT GNUTLS_FOUND) From 209da0841d465ed910b2582172c7baa5de4ea896 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Sat, 27 Jun 2015 01:10:31 +0200 Subject: [PATCH 121/155] cmake is now able to find OpenWebRTC --- Source/cmake/FindOpenWebRTC.cmake | 49 ++++++++++++++++++++++++------- Source/cmake/OptionsWPE.cmake | 12 ++++---- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/Source/cmake/FindOpenWebRTC.cmake b/Source/cmake/FindOpenWebRTC.cmake index 2fface0b660a5..13561614a751c 100644 --- a/Source/cmake/FindOpenWebRTC.cmake +++ b/Source/cmake/FindOpenWebRTC.cmake @@ -30,19 +30,48 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. find_package(PkgConfig) -pkg_check_modules(OPENWEBRTC openwebrtc-0.1 openwebrtc-gst-0.1) +pkg_check_modules(PC_OPENWEBRTC openwebrtc-0.3 openwebrtc-gst-0.3) -set(VERSION_OK TRUE) -if (OPENWEBRTC_VERSION) - if (OPENWEBRTC_FIND_VERSION_EXACT) - if (NOT("${OPENWEBRTC_FIND_VERSION}" VERSION_EQUAL "${OPENWEBRTC_VERSION}")) - set(VERSION_OK FALSE) - endif () - else () - if ("${OPENWEBRTC_VERSION}" VERSION_LESS "${OPENWEBRTC_FIND_VERSION}") - set(VERSION_OK FALSE) +if ("${PC_OPENWEBRTC_FOUND}") + set(OPENWEBRTC_FOUND "${PC_OPENWEBRTC_FOUND}") + + # Find Include paths + set(OPENWEBRTC_INCLUDE_DIRS "${PC_OPENWEBRTC_INCLUDE_DIRS}") + find_path(OWR_INCLUDE_DIR NAMES owr.h + HINTS ${PC_OPENWEBRTC_INCLUDE_DIRS} + PATH_SUFFIXES owr + ) + list(APPEND OPENWEBRTC_INCLUDE_DIRS "${OWR_INCLUDE_DIR}" ) + + find_path(OPENWEBRTC_GST_INCLUDE_DIR NAMES gst.h + HINTS ${PC_OPENWEBRTC_INCLUDE_DIRS} + PATH_SUFFIXES gst + ) + list(APPEND OPENWEBRTC_INCLUDE_DIRS "${OPENWEBRTC_GST_INCLUDE_DIR}" ) + + # Find Libraries + find_library(OPENWEBRTC_LIBRARIES NAMES openwebrtc + HINTS ${PC_OPENWEBRTC_LIBRARY_DIRS} ${PC_OPENWEBRTC_LIBDIR} + ) + + find_library(OPENWEBRTC_GST_LIBRARIES NAMES openwebrtc_gst + HINTS ${PC_OPENWEBRTC_LIBRARY_DIRS} ${PC_OPENWEBRTC_LIBDIR} + ) + list(APPEND OPENWEBRTC_LIBRARIES "${OPENWEBRTC_GST_LIBRARIES}") + + set(VERSION_OK TRUE) + if (PC_OPENWEBRTC_VERSION) + if (PC_OPENWEBRTC_FIND_VERSION_EXACT) + if (NOT("${PC_OPENWEBRTC_FIND_VERSION}" VERSION_EQUAL "${PC_OPENWEBRTC_VERSION}")) + set(VERSION_OK FALSE) + endif () + else () + if ("${PC_OPENWEBRTC_VERSION}" VERSION_LESS "${PC_OPENWEBRTC_FIND_VERSION}") + set(VERSION_OK FALSE) + endif () endif () endif () + endif () include(FindPackageHandleStandardArgs) diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake index b84a0d22b1e39..afa5f27af717e 100644 --- a/Source/cmake/OptionsWPE.cmake +++ b/Source/cmake/OptionsWPE.cmake @@ -37,8 +37,6 @@ if (ENABLE_DXDRM) add_definitions(-DUSE_DXDRM=1) endif () - - set(ENABLE_WEBCORE ON) set(ENABLE_WEBKIT OFF) set(ENABLE_WEBKIT2 ON) @@ -61,7 +59,6 @@ find_package(ICU REQUIRED) find_package(Threads REQUIRED) find_package(ZLIB REQUIRED) find_package(GLIB 2.40.0 REQUIRED COMPONENTS gio gobject gthread gmodule) - find_package(Cairo 1.10.2 REQUIRED) find_package(CairoGL 1.10.2 REQUIRED COMPONENTS cairo-egl) find_package(Fontconfig 2.8.0 REQUIRED) @@ -75,12 +72,11 @@ find_package(PNG REQUIRED) find_package(Sqlite REQUIRED) find_package(Wayland 1.6.0 REQUIRED) find_package(WebP REQUIRED) - find_package(OpenGLES2 REQUIRED) find_package(EGL REQUIRED) find_package(WaylandEGL REQUIRED) - find_package(Athol 0.1) + if (ATHOL_FOUND) set(ENABLE_ATHOL_SHELL ON) else () @@ -95,6 +91,12 @@ if (ENABLE_MEDIA_STREAM) add_definitions(-DUSE_OPENWEBRTC) endif () +if (OPENWEBRTC_FOUND) + target_link_libraries( WPENetworkProcess ${OPENWEBRTC_LIBRARIES} ) + target_link_libraries( WPEWebProcess ${OPENWEBRTC_LIBRARIES} ) + include_directories( ${OPENWEBRTC_INCLUDE_DIRS} ) +endif () + if (ENABLE_SUBTLE_CRYPTO) find_package(GnuTLS 3.0.0) if (NOT GNUTLS_FOUND) From b2439eddc196a56508f966251d8815c97bad7060 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Sat, 27 Jun 2015 01:27:40 +0200 Subject: [PATCH 122/155] Update OptionsWPE.cmake removed useless check --- Source/cmake/OptionsWPE.cmake | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake index afa5f27af717e..7f0660931232b 100644 --- a/Source/cmake/OptionsWPE.cmake +++ b/Source/cmake/OptionsWPE.cmake @@ -91,12 +91,6 @@ if (ENABLE_MEDIA_STREAM) add_definitions(-DUSE_OPENWEBRTC) endif () -if (OPENWEBRTC_FOUND) - target_link_libraries( WPENetworkProcess ${OPENWEBRTC_LIBRARIES} ) - target_link_libraries( WPEWebProcess ${OPENWEBRTC_LIBRARIES} ) - include_directories( ${OPENWEBRTC_INCLUDE_DIRS} ) -endif () - if (ENABLE_SUBTLE_CRYPTO) find_package(GnuTLS 3.0.0) if (NOT GNUTLS_FOUND) From 5433d852f586ac718b95dc7d4d17155c710f0173 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Sat, 27 Jun 2015 11:16:07 +0200 Subject: [PATCH 123/155] add ENABLE_MEDIA_STREAM to include OpenWebRTC --- Source/WebCore/PlatformWPE.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake index f772a92bded44..17370701174af 100644 --- a/Source/WebCore/PlatformWPE.cmake +++ b/Source/WebCore/PlatformWPE.cmake @@ -336,3 +336,12 @@ if (ENABLE_ENCRYPTED_MEDIA OR ENABLE_ENCRYPTED_MEDIA_V2) platform/graphics/gstreamer/WebKitMediaAesCtr.c ) endif () + +if (ENABLE_MEDIA_STREAM) + list(APPEND WebCore_SYSTEM_INCLUDE_DIRECTORIES + ${OPENWEBRTC_INCLUDE_DIRS} + ) + list(APPEND WebCore_LIBRARIES + ${OPENWEBRTC_LIBRARIES} + ) +endif () From 0911f8c80c5cc4c2f9d88004f579a2d9aaab9cc0 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Sat, 27 Jun 2015 11:25:03 +0200 Subject: [PATCH 124/155] Update FindOpenWebRTC.cmake --- Source/cmake/FindOpenWebRTC.cmake | 44 +++++++++++-------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/Source/cmake/FindOpenWebRTC.cmake b/Source/cmake/FindOpenWebRTC.cmake index 13561614a751c..f5a3a216bc17e 100644 --- a/Source/cmake/FindOpenWebRTC.cmake +++ b/Source/cmake/FindOpenWebRTC.cmake @@ -30,49 +30,37 @@ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. find_package(PkgConfig) -pkg_check_modules(PC_OPENWEBRTC openwebrtc-0.3 openwebrtc-gst-0.3) +pkg_check_modules(OPENWEBRTC openwebrtc-0.3 openwebrtc-gst-0.3) -if ("${PC_OPENWEBRTC_FOUND}") - set(OPENWEBRTC_FOUND "${PC_OPENWEBRTC_FOUND}") - - # Find Include paths - set(OPENWEBRTC_INCLUDE_DIRS "${PC_OPENWEBRTC_INCLUDE_DIRS}") - find_path(OWR_INCLUDE_DIR NAMES owr.h - HINTS ${PC_OPENWEBRTC_INCLUDE_DIRS} +if ("${OPENWEBRTC_FOUND}") + find_path( + OWR_INCLUDE_DIR + NAMES owr.h + HINTS ${OPENWEBRTC_INCLUDE_DIRS} PATH_SUFFIXES owr ) list(APPEND OPENWEBRTC_INCLUDE_DIRS "${OWR_INCLUDE_DIR}" ) - find_path(OPENWEBRTC_GST_INCLUDE_DIR NAMES gst.h - HINTS ${PC_OPENWEBRTC_INCLUDE_DIRS} + find_path( + OWR_GST_INCLUDE_DIR + NAMES gst.h + HINTS ${OPENWEBRTC_INCLUDE_DIRS} PATH_SUFFIXES gst ) - list(APPEND OPENWEBRTC_INCLUDE_DIRS "${OPENWEBRTC_GST_INCLUDE_DIR}" ) - - # Find Libraries - find_library(OPENWEBRTC_LIBRARIES NAMES openwebrtc - HINTS ${PC_OPENWEBRTC_LIBRARY_DIRS} ${PC_OPENWEBRTC_LIBDIR} - ) - - find_library(OPENWEBRTC_GST_LIBRARIES NAMES openwebrtc_gst - HINTS ${PC_OPENWEBRTC_LIBRARY_DIRS} ${PC_OPENWEBRTC_LIBDIR} - ) - list(APPEND OPENWEBRTC_LIBRARIES "${OPENWEBRTC_GST_LIBRARIES}") - + list(APPEND OPENWEBRTC_INCLUDE_DIRS "${OWR_GST_INCLUDE_DIR}" ) set(VERSION_OK TRUE) - if (PC_OPENWEBRTC_VERSION) - if (PC_OPENWEBRTC_FIND_VERSION_EXACT) - if (NOT("${PC_OPENWEBRTC_FIND_VERSION}" VERSION_EQUAL "${PC_OPENWEBRTC_VERSION}")) + if (OPENWEBRTC_VERSION) + if (OPENWEBRTC_FIND_VERSION_EXACT) + if (NOT("${PC_OPENWEBRTC_FIND_VERSION}" VERSION_EQUAL "${OPENWEBRTC_VERSION}")) set(VERSION_OK FALSE) endif () else () - if ("${PC_OPENWEBRTC_VERSION}" VERSION_LESS "${PC_OPENWEBRTC_FIND_VERSION}") + if ("${OPENWEBRTC_VERSION}" VERSION_LESS "${OPENWEBRTC_FIND_VERSION}") set(VERSION_OK FALSE) endif () endif () endif () - endif () include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENWEBRTC DEFAULT_MSG OPENWEBRTC_INCLUDE_DIRS OPENWEBRTC_LIBRARIES VERSION_OK) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OPENWEBRTC DEFAULT_MSG OPENWEBRTC_FOUND OPENWEBRTC_LIBRARIES OPENWEBRTC_INCLUDE_DIRS VERSION_OK) From 5fab30e53edae6aa80416b01f909fa14a47e0d31 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Mon, 29 Jun 2015 02:36:09 +0200 Subject: [PATCH 125/155] Missing source files added to ENABLE_MEDIA_STREAM --- Source/WebCore/PlatformWPE.cmake | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake index 17370701174af..91acc4b7d9598 100644 --- a/Source/WebCore/PlatformWPE.cmake +++ b/Source/WebCore/PlatformWPE.cmake @@ -12,6 +12,7 @@ list(APPEND WebCore_INCLUDE_DIRECTORIES "${WEBCORE_DIR}/platform/graphics/opentype" "${WEBCORE_DIR}/platform/graphics/wayland" "${WEBCORE_DIR}/platform/linux" + "${WEBCORE_DIR}/platform/mediastream" "${WEBCORE_DIR}/platform/mediastream/openwebrtc" "${WEBCORE_DIR}/platform/mock/mediasource" "${WEBCORE_DIR}/platform/network/soup" @@ -107,8 +108,6 @@ list(APPEND WebCore_SOURCES platform/image-decoders/webp/WEBPImageDecoder.cpp platform/image-encoders/JPEGImageEncoder.cpp platform/linux/MemoryPressureHandlerLinux.cpp - platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp - platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp platform/network/soup/AuthenticationChallengeSoup.cpp platform/network/soup/CertificateInfo.cpp platform/network/soup/CookieJarSoup.cpp @@ -344,4 +343,12 @@ if (ENABLE_MEDIA_STREAM) list(APPEND WebCore_LIBRARIES ${OPENWEBRTC_LIBRARIES} ) + list(APPEND WebCore_SOURCES + platform/graphics/MediaPlayer.cpp + platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp + platform/mediastream/MediaEndpoint.cpp + platform/mediastream/openwebrtc/MediaEndpointOwr.cpp + platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp + platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp + ) endif () From 5d88166273e439b9de59c2bdc3ae04ceaff5b131 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Wed, 1 Jul 2015 20:21:35 -0700 Subject: [PATCH 126/155] gtk: jhbuild: bump gstreamer deps to 1.5.2 --- Tools/gtk/jhbuild.modules | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index a5c3cf5335502..370445de832d7 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -304,7 +304,7 @@
- + - + @@ -322,7 +322,7 @@ - + @@ -332,7 +332,7 @@ - + @@ -340,7 +340,7 @@ - + From 0cd54f5274458302e21c637999f0822600eb8abb Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Thu, 2 Jul 2015 04:35:59 -0700 Subject: [PATCH 127/155] jhbuild: gtk: add orc as a dependency --- Tools/gtk/jhbuild.modules | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index 370445de832d7..7cff6c05e73d9 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -25,6 +25,7 @@ + @@ -303,6 +304,12 @@ + + + + @@ -312,6 +319,7 @@ autogenargs="--disable-examples --disable-gtk-doc"> +
From 5071ae6da3deb95f78375e3961a55f1cd6f89624 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Sun, 24 May 2015 23:26:35 -0700 Subject: [PATCH 128/155] HTMLMediaElement: lookup blob URLs in the MediaStreamRegistry Fixes code like: video.src = URL.createObjectURL(media_stream) --- Source/WebCore/html/HTMLMediaElement.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp index 03ce98aa42164..aab36fd0a65ce 100644 --- a/Source/WebCore/html/HTMLMediaElement.cpp +++ b/Source/WebCore/html/HTMLMediaElement.cpp @@ -1253,9 +1253,11 @@ void HTMLMediaElement::loadResource(const URL& initialURL, ContentType& contentT } else #endif #if ENABLE(MEDIA_STREAM) - if (m_mediaStreamSrcObject) - m_player->load(m_mediaStreamSrcObject->privateStream()); - else + if (!m_mediaStreamSrcObject && url.protocolIs(mediaSourceBlobProtocol)) + m_mediaStreamSrcObject = static_cast(MediaStreamRegistry::registry().lookup(url.string())); + if (m_mediaStreamSrcObject) + m_player->load(m_mediaStreamSrcObject->privateStream()); + else #endif if (!m_player->load(url, contentType, keySystem)) mediaLoadingFailed(MediaPlayer::FormatError); From 88873475e0c0bedadca0ff4b3b2ad62133265cf6 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Fri, 3 Jul 2015 07:03:26 +0200 Subject: [PATCH 129/155] add MEDIA_STREAM as feature --- Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig | 4 +++- Source/WebCore/Configurations/FeatureDefines.xcconfig | 4 +++- Source/WebKit2/Configurations/FeatureDefines.xcconfig | 4 +++- Source/cmake/OptionsWPE.cmake | 3 +++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig index d1eeb2b24b57d..38a436a3c3a3b 100644 --- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -140,6 +140,8 @@ ENABLE_MEDIA_SOURCE_macosx_101000 = ENABLE_MEDIA_SOURCE; ENABLE_MEDIA_SOURCE_macosx_101100 = ENABLE_MEDIA_SOURCE; ENABLE_MEDIA_SOURCE_macosx_101200 = ENABLE_MEDIA_SOURCE; +ENABLE_MEDIA_STREAM = ENABLE_MEDIA_STREAM; + ENABLE_MEDIA_STATISTICS = ; ENABLE_METER_ELEMENT[sdk=macosx*] = ENABLE_METER_ELEMENT; ENABLE_MHTML = ; @@ -224,4 +226,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT; ENABLE_SATURATED_LAYOUT_ARITHMETIC = ENABLE_SATURATED_LAYOUT_ARITHMETIC; -FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PICTURE_SIZES) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SATURATED_LAYOUT_ARITHMETIC) $(ENABLE_VIDEO_PRESENTATION_MODE); +FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PICTURE_SIZES) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SATURATED_LAYOUT_ARITHMETIC) $(ENABLE_VIDEO_PRESENTATION_MODE); diff --git a/Source/WebCore/Configurations/FeatureDefines.xcconfig b/Source/WebCore/Configurations/FeatureDefines.xcconfig index d1eeb2b24b57d..38a436a3c3a3b 100644 --- a/Source/WebCore/Configurations/FeatureDefines.xcconfig +++ b/Source/WebCore/Configurations/FeatureDefines.xcconfig @@ -140,6 +140,8 @@ ENABLE_MEDIA_SOURCE_macosx_101000 = ENABLE_MEDIA_SOURCE; ENABLE_MEDIA_SOURCE_macosx_101100 = ENABLE_MEDIA_SOURCE; ENABLE_MEDIA_SOURCE_macosx_101200 = ENABLE_MEDIA_SOURCE; +ENABLE_MEDIA_STREAM = ENABLE_MEDIA_STREAM; + ENABLE_MEDIA_STATISTICS = ; ENABLE_METER_ELEMENT[sdk=macosx*] = ENABLE_METER_ELEMENT; ENABLE_MHTML = ; @@ -224,4 +226,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT; ENABLE_SATURATED_LAYOUT_ARITHMETIC = ENABLE_SATURATED_LAYOUT_ARITHMETIC; -FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PICTURE_SIZES) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SATURATED_LAYOUT_ARITHMETIC) $(ENABLE_VIDEO_PRESENTATION_MODE); +FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PICTURE_SIZES) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SATURATED_LAYOUT_ARITHMETIC) $(ENABLE_VIDEO_PRESENTATION_MODE); diff --git a/Source/WebKit2/Configurations/FeatureDefines.xcconfig b/Source/WebKit2/Configurations/FeatureDefines.xcconfig index d1eeb2b24b57d..38a436a3c3a3b 100644 --- a/Source/WebKit2/Configurations/FeatureDefines.xcconfig +++ b/Source/WebKit2/Configurations/FeatureDefines.xcconfig @@ -140,6 +140,8 @@ ENABLE_MEDIA_SOURCE_macosx_101000 = ENABLE_MEDIA_SOURCE; ENABLE_MEDIA_SOURCE_macosx_101100 = ENABLE_MEDIA_SOURCE; ENABLE_MEDIA_SOURCE_macosx_101200 = ENABLE_MEDIA_SOURCE; +ENABLE_MEDIA_STREAM = ENABLE_MEDIA_STREAM; + ENABLE_MEDIA_STATISTICS = ; ENABLE_METER_ELEMENT[sdk=macosx*] = ENABLE_METER_ELEMENT; ENABLE_MHTML = ; @@ -224,4 +226,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT; ENABLE_SATURATED_LAYOUT_ARITHMETIC = ENABLE_SATURATED_LAYOUT_ARITHMETIC; -FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PICTURE_SIZES) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SATURATED_LAYOUT_ARITHMETIC) $(ENABLE_VIDEO_PRESENTATION_MODE); +FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_AVF_CAPTIONS) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_ES6_ARROWFUNCTION_SYNTAX) $(ENABLE_ES6_CLASS_SYNTAX) $(ENABLE_ES6_TEMPLATE_LITERAL_SYNTAX) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS3_TEXT) $(ENABLE_CSS3_TEXT_LINE_BREAK) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_ICONDATABASE) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MATHML) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_PICTURE_SIZES) $(ENABLE_POINTER_LOCK) $(ENABLE_PROMISES) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RUBBER_BANDING) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_STREAMS_API) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_OTF_CONVERTER) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TEMPLATE_ELEMENT) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_DATACUE_VALUE) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBVTT_REGIONS) $(ENABLE_XHR_TIMEOUT) $(ENABLE_XSLT) $(ENABLE_FTL_JIT) $(ENABLE_JIT) $(ENABLE_SATURATED_LAYOUT_ARITHMETIC) $(ENABLE_VIDEO_PRESENTATION_MODE); diff --git a/Source/cmake/OptionsWPE.cmake b/Source/cmake/OptionsWPE.cmake index 7f0660931232b..cd98feb3ca47f 100644 --- a/Source/cmake/OptionsWPE.cmake +++ b/Source/cmake/OptionsWPE.cmake @@ -88,6 +88,9 @@ endif () if (ENABLE_MEDIA_STREAM) find_package(OpenWebRTC REQUIRED) + if (NOT OPENWEBRTC_FOUND) + message(FATAL_ERROR "OpenWebRTC is needed for ENABLE_MEDIA_STREAM") + endif () add_definitions(-DUSE_OPENWEBRTC) endif () From 9af8492daf41925fc4502024b3f0b185827d7e1f Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Fri, 3 Jul 2015 07:25:36 +0200 Subject: [PATCH 130/155] small cleanup --- Source/WebCore/PlatformWPE.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake index 91acc4b7d9598..424da28dd807d 100644 --- a/Source/WebCore/PlatformWPE.cmake +++ b/Source/WebCore/PlatformWPE.cmake @@ -344,9 +344,7 @@ if (ENABLE_MEDIA_STREAM) ${OPENWEBRTC_LIBRARIES} ) list(APPEND WebCore_SOURCES - platform/graphics/MediaPlayer.cpp platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp - platform/mediastream/MediaEndpoint.cpp platform/mediastream/openwebrtc/MediaEndpointOwr.cpp platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp From c682eed46c66209c5fdff9432dbfd34c26d8c710 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Fri, 3 Jul 2015 10:55:42 +0200 Subject: [PATCH 131/155] post-merge build fixes --- Source/WebCore/Modules/mediastream/MediaStream.cpp | 2 +- .../gstreamer/MediaPlayerPrivateGStreamerOwr.cpp | 14 +++++--------- .../gstreamer/MediaPlayerPrivateGStreamerOwr.h | 5 ++--- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaStream.cpp b/Source/WebCore/Modules/mediastream/MediaStream.cpp index c1791eedfe72a..7aac5c0ac5ecd 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.cpp +++ b/Source/WebCore/Modules/mediastream/MediaStream.cpp @@ -124,7 +124,7 @@ void MediaStream::addTrack(RefPtr&& track) void MediaStream::removeTrack(MediaStreamTrack* track) { - if (!internalRemoveTrack(track, StreamModifier::DOMAPI)) + if (!internalRemoveTrack(track, StreamModifier::DomAPI)) return; for (auto& observer : m_observers) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp index f7778cacb28c5..3c4a8869525f3 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp @@ -275,9 +275,9 @@ void MediaPlayerPrivateGStreamerOwr::createGSTAudioSinkBin() m_audioRenderer = owr_gst_audio_renderer_new(m_audioSink.get()); } -void MediaPlayerPrivateGStreamerOwr::sourceReadyStateChanged() +void MediaPlayerPrivateGStreamerOwr::sourceStopped() { - LOG_MEDIA_MESSAGE("Source state changed"); + LOG_MEDIA_MESSAGE("Source stopped"); if (!m_streamPrivate || !m_streamPrivate->active()) stop(); @@ -298,14 +298,10 @@ void MediaPlayerPrivateGStreamerOwr::sourceMutedChanged() LOG_MEDIA_MESSAGE("Source muted state changed"); } -void MediaPlayerPrivateGStreamerOwr::sourceEnabledChanged() +bool MediaPlayerPrivateGStreamerOwr::preventSourceFromStopping() { - LOG_MEDIA_MESSAGE("Source enabled state changed"); -} - -bool MediaPlayerPrivateGStreamerOwr::observerIsEnabled() -{ - return true; + LOG_MEDIA_MESSAGE("Prevent source from stopping"); + return false; } GstElement* MediaPlayerPrivateGStreamerOwr::createVideoSink() diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h index 9aa4072e47326..fb9124026ef29 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.h @@ -82,10 +82,9 @@ class MediaPlayerPrivateGStreamerOwr : public MediaPlayerPrivateGStreamerBase, p virtual bool isLiveStream() const { return true; } // RealtimeMediaSource::Observer implementation - virtual void sourceReadyStateChanged() override final; + virtual void sourceStopped() override final; virtual void sourceMutedChanged() override final; - virtual void sourceEnabledChanged() override final; - virtual bool observerIsEnabled() override final; + virtual bool preventSourceFromStopping() override final; protected: virtual GstElement* createVideoSink(); From 4b48d65a6c8abf7f81cbf60643d2aad0cbd13d15 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Mon, 6 Jul 2015 12:48:23 +0200 Subject: [PATCH 132/155] [WPE] Fix build errors with OpenGL ES --- Source/WebCore/platform/graphics/ANGLEWebKitBridge.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h index 9a6a2c2417a37..5cc1ad238fe87 100644 --- a/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h +++ b/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h @@ -35,11 +35,15 @@ #include #elif PLATFORM(WIN) #include "OpenGLESShims.h" -#elif PLATFORM(GTK) || PLATFORM(EFL) +#elif PLATFORM(GTK) || PLATFORM(EFL) || PLATFORM(WPE) +#if USE(OPENGL_ES_2) +#include +#else #include "OpenGLShims.h" #endif +#endif -#if !PLATFORM(GTK) && !PLATFORM(EFL) && !PLATFORM(WIN) && !defined(BUILDING_WITH_CMAKE) +#if !PLATFORM(GTK) && !PLATFORM(EFL) && !PLATFORM(WPE) && !PLATFORM(WIN) && !defined(BUILDING_WITH_CMAKE) #include "ANGLE/ShaderLang.h" #elif PLATFORM(WIN) && !defined(BUILDING_WITH_CMAKE) #include "GLSLANG/ShaderLang.h" @@ -74,7 +78,7 @@ struct ANGLEShaderSymbol { return symbolType == SHADER_SYMBOL_TYPE_UNIFORM && (dataType == GL_SAMPLER_2D || dataType == GL_SAMPLER_CUBE -#if !PLATFORM(IOS) +#if !PLATFORM(IOS) && !((PLATFORM(EFL) || PLATFORM(GTK) || PLATFORM(WPE)) && USE(OPENGL_ES_2)) || dataType == GL_SAMPLER_2D_RECT_ARB #endif ); @@ -110,3 +114,4 @@ class ANGLEWebKitBridge { } // namespace WebCore #endif + From 4774ccfd3fadadb51ec4884ee6188262c75c24a0 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 15:13:00 +0200 Subject: [PATCH 133/155] [CoordinatedGraphics] Fixed flush overlay layer call. --- .../platform/graphics/texmap/GraphicsLayerTextureMapper.cpp | 2 +- .../graphics/texmap/coordinated/CompositingCoordinator.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp index 547e2496614ad..560e0a23b35b0 100644 --- a/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp +++ b/Source/WebCore/platform/graphics/texmap/GraphicsLayerTextureMapper.cpp @@ -26,7 +26,7 @@ #include "TextureMapperAnimation.h" #include -#if USE(TEXTURE_MAPPER) +#if USE(TEXTURE_MAPPER) && !USE(COORDINATED_GRAPHICS) namespace WebCore { diff --git a/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp b/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp index caa53297335ac..d29c5370a95bf 100644 --- a/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp +++ b/Source/WebCore/platform/graphics/texmap/coordinated/CompositingCoordinator.cpp @@ -98,7 +98,7 @@ bool CompositingCoordinator::flushPendingLayerChanges() m_client->didFlushRootLayer(m_visibleContentsRect); if (m_overlayCompositingLayer) - m_overlayCompositingLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size())); + m_overlayCompositingLayer->flushCompositingState(FloatRect(FloatPoint(), m_rootLayer->size()), m_page->mainFrame().view()->viewportIsStable()); bool didSync = m_page->mainFrame().view()->flushCompositingStateIncludingSubframes(); From 53f0cdf69e6ed7e8b8c6d8156e96a9938db31ad8 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 15:20:57 +0200 Subject: [PATCH 134/155] [WPE] Fixed functions definitions now using Scrollbar directly. --- Source/WebCore/platform/wpe/ScrollbarThemeWPE.cpp | 10 +++++----- Source/WebCore/platform/wpe/ScrollbarThemeWPE.h | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Source/WebCore/platform/wpe/ScrollbarThemeWPE.cpp b/Source/WebCore/platform/wpe/ScrollbarThemeWPE.cpp index 9e7088c78eca7..42cdb24e960a8 100644 --- a/Source/WebCore/platform/wpe/ScrollbarThemeWPE.cpp +++ b/Source/WebCore/platform/wpe/ScrollbarThemeWPE.cpp @@ -30,31 +30,31 @@ namespace WebCore { -bool ScrollbarThemeWPE::hasButtons(ScrollbarThemeClient*) +bool ScrollbarThemeWPE::hasButtons(Scrollbar&) { notImplemented(); return true; } -bool ScrollbarThemeWPE::hasThumb(ScrollbarThemeClient*) +bool ScrollbarThemeWPE::hasThumb(Scrollbar&) { notImplemented(); return true; } -IntRect ScrollbarThemeWPE::backButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool) +IntRect ScrollbarThemeWPE::backButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool) { notImplemented(); return IntRect(); } -IntRect ScrollbarThemeWPE::forwardButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool) +IntRect ScrollbarThemeWPE::forwardButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool) { notImplemented(); return IntRect(); } -IntRect ScrollbarThemeWPE::trackRect(ScrollbarThemeClient*, bool) +IntRect ScrollbarThemeWPE::trackRect(Scrollbar&, bool) { notImplemented(); return IntRect(); diff --git a/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h b/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h index 7dbfab098f35a..4438ebb8707e4 100644 --- a/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h +++ b/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h @@ -34,13 +34,13 @@ class ScrollbarThemeWPE final : public ScrollbarThemeComposite { public: ScrollbarThemeWPE() = default; virtual ~ScrollbarThemeWPE() = default; - - virtual bool hasButtons(ScrollbarThemeClient*) override; - virtual bool hasThumb(ScrollbarThemeClient*) override; - - virtual IntRect backButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool painting = false) override; - virtual IntRect forwardButtonRect(ScrollbarThemeClient*, ScrollbarPart, bool painting = false) override; - virtual IntRect trackRect(ScrollbarThemeClient*, bool painting = false) override; + + virtual bool hasButtons(Scrollbar&) { return true; } + virtual bool hasThumb(Scrollbar&); + + virtual IntRect backButtonRect(Scrollbar&, ScrollbarPart, bool painting = false); + virtual IntRect forwardButtonRect(Scrollbar&, ScrollbarPart, bool painting = false); + virtual IntRect trackRect(Scrollbar&, bool painting = false); }; } // namespace WebCore From 2b515ac251e559f46603fbfd81772e6e7402cd86 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 15:22:50 +0200 Subject: [PATCH 135/155] [WPE] User media device perissions contolled by enviroment variable. --- .../UserMediaPermissionRequestManager.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp index 10f3f993b0103..dd882e040ad8f 100644 --- a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp @@ -30,6 +30,8 @@ #include #include +#include + using namespace WebCore; namespace WebKit { @@ -46,7 +48,16 @@ UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& pa } void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) -{ +#if PLATFORM(WPE) + // The user permission request dialog is not supported by WPE, so + // there for check a environment varible to contol the grant + bool allowed = FALSE; + + if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) { + allowed = TRUE; + } + UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(request, allowed); +#else Document* document = downcast(request.scriptExecutionContext()); Frame* frame = document ? document->frame() : nullptr; @@ -63,7 +74,9 @@ void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) ASSERT(webFrame); SecurityOrigin* origin = request.securityOrigin(); + m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame->frameID(), origin->databaseIdentifier(), request.requiresAudio(), request.requiresVideo())); +#endif } void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest& request) From 838de77dc68329a84eefcc6c1b08fcdc57976779 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 15:36:14 +0200 Subject: [PATCH 136/155] [WPE] fixed user media permission request. --- .../MediaStream/UserMediaPermissionRequestManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp index dd882e040ad8f..93a06b5ae6347 100644 --- a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp @@ -48,13 +48,14 @@ UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& pa } void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) +{ #if PLATFORM(WPE) // The user permission request dialog is not supported by WPE, so // there for check a environment varible to contol the grant - bool allowed = FALSE; + bool allowed = false; if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) { - allowed = TRUE; + allowed = true; } UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(request, allowed); #else From 8d19b54cc6da555990114ce91da430d024b61923 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 17:49:23 +0200 Subject: [PATCH 137/155] [WPE] fix build errors --- Source/WebKit2/UIProcess/API/wpe/PageClientImpl.cpp | 8 ++++++++ Source/WebKit2/UIProcess/API/wpe/PageClientImpl.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.cpp b/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.cpp index de87d6c7a1e47..69d8707c63c73 100644 --- a/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.cpp +++ b/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.cpp @@ -223,6 +223,10 @@ void PageClientImpl::navigationGestureWillEnd(bool, WebBackForwardListItem&) { } +void PageClientImpl::navigationGestureDidEnd() +{ +} + void PageClientImpl::navigationGestureDidEnd(bool, WebBackForwardListItem&) { } @@ -239,6 +243,10 @@ void PageClientImpl::didFinishLoadForMainFrame() { } +void PageClientImpl::didFailLoadForMainFrame() +{ +} + void PageClientImpl::didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) { } diff --git a/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.h b/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.h index 70617d1f70ee7..e1c183082062d 100644 --- a/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.h +++ b/Source/WebKit2/UIProcess/API/wpe/PageClientImpl.h @@ -95,11 +95,13 @@ class PageClientImpl final : public PageClient { virtual void navigationGestureDidBegin() override; virtual void navigationGestureWillEnd(bool, WebBackForwardListItem&) override; + virtual void navigationGestureDidEnd() override; virtual void navigationGestureDidEnd(bool, WebBackForwardListItem&) override; virtual void willRecordNavigationSnapshot(WebBackForwardListItem&) override; virtual void didFirstVisuallyNonEmptyLayoutForMainFrame() override; virtual void didFinishLoadForMainFrame() override; + virtual void didFailLoadForMainFrame() override; virtual void didSameDocumentNavigationForMainFrame(SameDocumentNavigationType) override; virtual void didChangeBackgroundColor() override; From dcf7cf0f62ca8eb8c0777bceb3b619f40944e8fd Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 17:52:39 +0200 Subject: [PATCH 138/155] [WPE] fix build errors --- .../UserMediaPermissionRequestManager.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp index 93a06b5ae6347..04b621ce915f3 100644 --- a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp @@ -51,13 +51,21 @@ void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) { #if PLATFORM(WPE) // The user permission request dialog is not supported by WPE, so - // there for check a environment varible to contol the grant + // there for check a environment varible to contol the grant + uint64_t requestID = m_requestToIDMap.take(&request); + + if (!requestID) + return; + + m_idToRequestMap.remove(requestID); + bool allowed = false; - if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) { - allowed = true; - } - UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(request, allowed); + if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) + allowed = true; + + UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(requestID, allowed); + #else Document* document = downcast(request.scriptExecutionContext()); Frame* frame = document ? document->frame() : nullptr; From ceabd94ff25e9706451abe0eae06e0d597c34b39 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 18:10:33 +0200 Subject: [PATCH 139/155] [WPE] Add missing function. --- Source/WebKit2/UIProcess/wpe/WebInspectorProxyWPE.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/WebKit2/UIProcess/wpe/WebInspectorProxyWPE.cpp b/Source/WebKit2/UIProcess/wpe/WebInspectorProxyWPE.cpp index 4851d07f62b8f..4ea1c0461c931 100644 --- a/Source/WebKit2/UIProcess/wpe/WebInspectorProxyWPE.cpp +++ b/Source/WebKit2/UIProcess/wpe/WebInspectorProxyWPE.cpp @@ -134,6 +134,11 @@ void WebInspectorProxy::platformSetToolbarHeight(unsigned) notImplemented(); } +void WebInspectorProxy::platformStartWindowDrag() +{ + notImplemented(); +} + void WebInspectorProxy::platformSave(const String&, const String&, bool, bool) { notImplemented(); From ee6b07e4d48be66e56cde78fcb0363be508e031c Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 20:24:54 +0200 Subject: [PATCH 140/155] [WPE] fix build error --- Source/WebCore/platform/wpe/ScrollbarThemeWPE.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h b/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h index 4438ebb8707e4..2f8d1cfaaaf05 100644 --- a/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h +++ b/Source/WebCore/platform/wpe/ScrollbarThemeWPE.h @@ -35,7 +35,7 @@ class ScrollbarThemeWPE final : public ScrollbarThemeComposite { ScrollbarThemeWPE() = default; virtual ~ScrollbarThemeWPE() = default; - virtual bool hasButtons(Scrollbar&) { return true; } + virtual bool hasButtons(Scrollbar&); virtual bool hasThumb(Scrollbar&); virtual IntRect backButtonRect(Scrollbar&, ScrollbarPart, bool painting = false); From 837d84981cd52cba0928c771f7bc281fee13dcfe Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Tue, 7 Jul 2015 21:43:42 +0200 Subject: [PATCH 141/155] [WPE] Added WPE UserMediaPermissionRequestManager --- Source/WebKit2/CMakeLists.txt | 2 - Source/WebKit2/PlatformEfl.cmake | 2 + Source/WebKit2/PlatformGTK.cmake | 2 + Source/WebKit2/PlatformWPE.cmake | 1 + .../UserMediaPermissionRequestManager.cpp | 19 ---- .../UserMediaPermissionRequestManagerWPE.cpp | 87 +++++++++++++++++++ 6 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp diff --git a/Source/WebKit2/CMakeLists.txt b/Source/WebKit2/CMakeLists.txt index 4b78ad26e38a4..47518aba51738 100644 --- a/Source/WebKit2/CMakeLists.txt +++ b/Source/WebKit2/CMakeLists.txt @@ -548,8 +548,6 @@ set(WebKit2_SOURCES WebProcess/MediaCache/WebMediaCacheManager.cpp - WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp - WebProcess/Network/NetworkProcessConnection.cpp WebProcess/Network/WebResourceLoadScheduler.cpp WebProcess/Network/WebResourceLoader.cpp diff --git a/Source/WebKit2/PlatformEfl.cmake b/Source/WebKit2/PlatformEfl.cmake index 9c1cd8145073e..dfd0837844a95 100644 --- a/Source/WebKit2/PlatformEfl.cmake +++ b/Source/WebKit2/PlatformEfl.cmake @@ -185,6 +185,8 @@ list(APPEND WebKit2_SOURCES WebProcess/InjectedBundle/efl/InjectedBundleEfl.cpp WebProcess/MediaCache/WebMediaKeyStorageManager.cpp + + WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp diff --git a/Source/WebKit2/PlatformGTK.cmake b/Source/WebKit2/PlatformGTK.cmake index 461183bfffcd0..6827144836cd8 100644 --- a/Source/WebKit2/PlatformGTK.cmake +++ b/Source/WebKit2/PlatformGTK.cmake @@ -317,6 +317,8 @@ list(APPEND WebKit2_SOURCES WebProcess/MediaCache/WebMediaKeyStorageManager.cpp + WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp + WebProcess/Plugins/Netscape/unix/PluginProxyUnix.cpp WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp diff --git a/Source/WebKit2/PlatformWPE.cmake b/Source/WebKit2/PlatformWPE.cmake index ba7039f96d117..3bf2e1296f44a 100644 --- a/Source/WebKit2/PlatformWPE.cmake +++ b/Source/WebKit2/PlatformWPE.cmake @@ -92,6 +92,7 @@ list(APPEND WebKit2_SOURCES WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp WebProcess/InjectedBundle/wpe/InjectedBundleWPE.cpp WebProcess/MediaCache/WebMediaKeyStorageManager.cpp + WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp WebProcess/WebCoreSupport/wpe/WebContextMenuClientWPE.cpp WebProcess/WebCoreSupport/wpe/WebEditorClientWPE.cpp diff --git a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp index 04b621ce915f3..56a2a16f1ee40 100644 --- a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp @@ -49,24 +49,6 @@ UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& pa void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) { -#if PLATFORM(WPE) - // The user permission request dialog is not supported by WPE, so - // there for check a environment varible to contol the grant - uint64_t requestID = m_requestToIDMap.take(&request); - - if (!requestID) - return; - - m_idToRequestMap.remove(requestID); - - bool allowed = false; - - if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) - allowed = true; - - UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(requestID, allowed); - -#else Document* document = downcast(request.scriptExecutionContext()); Frame* frame = document ? document->frame() : nullptr; @@ -85,7 +67,6 @@ void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) SecurityOrigin* origin = request.securityOrigin(); m_page.send(Messages::WebPageProxy::RequestUserMediaPermissionForFrame(requestID, webFrame->frameID(), origin->databaseIdentifier(), request.requiresAudio(), request.requiresVideo())); -#endif } void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest& request) diff --git a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp new file mode 100644 index 0000000000000..47df706cf0ee0 --- /dev/null +++ b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "UserMediaPermissionRequestManager.h" + +#if ENABLE(MEDIA_STREAM) + +#include "WebCoreArgumentCoders.h" +#include "WebFrame.h" +#include "WebPage.h" +#include "WebPageProxyMessages.h" +#include +#include +#include +#include + +#include + +using namespace WebCore; + +namespace WebKit { + +static uint64_t generateRequestID() +{ + static uint64_t uniqueRequestID = 1; + return uniqueRequestID++; +} + +UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& page) + : m_page(page) +{ +} + +void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) +{ + uint64_t requestID = m_requestToIDMap.take(&request); + + bool allowed = false; + + // The user permission request dialog is not supported by WPE, so + // there for check a environment varible to contol the grant + if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) + allowed = true; + + UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(requestID, allowed); +} + +void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest& request) +{ + uint64_t requestID = m_requestToIDMap.take(&request); + if (!requestID) + return; + m_idToRequestMap.remove(requestID); +} + +void UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed) +{ + RefPtr request = m_idToRequestMap.take(requestID); + if (!request) + return; + m_requestToIDMap.remove(request); + + if (allowed) + request->userMediaAccessGranted(); + else + request->userMediaAccessDenied(); +} + +} // namespace WebKit + +#endif // ENABLE(MEDIA_STREAM) From 07387137704ac675391e992f61537a17a0a87563 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Wed, 8 Jul 2015 08:16:00 +0200 Subject: [PATCH 142/155] [WPE] corrected path --- Source/WebKit2/PlatformWPE.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebKit2/PlatformWPE.cmake b/Source/WebKit2/PlatformWPE.cmake index 3bf2e1296f44a..54841370dac93 100644 --- a/Source/WebKit2/PlatformWPE.cmake +++ b/Source/WebKit2/PlatformWPE.cmake @@ -92,7 +92,7 @@ list(APPEND WebKit2_SOURCES WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp WebProcess/InjectedBundle/wpe/InjectedBundleWPE.cpp WebProcess/MediaCache/WebMediaKeyStorageManager.cpp - WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp + WebProcess/MediaStream/wpe/UserMediaPermissionRequestManager.cpp WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp WebProcess/WebCoreSupport/wpe/WebContextMenuClientWPE.cpp WebProcess/WebCoreSupport/wpe/WebEditorClientWPE.cpp From 7c492d3669c3e743702976dd9a6770a091caad04 Mon Sep 17 00:00:00 2001 From: Bram Oosterhuis Date: Wed, 8 Jul 2015 08:33:06 +0200 Subject: [PATCH 143/155] [WPE] corrected filename --- Source/WebKit2/PlatformWPE.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebKit2/PlatformWPE.cmake b/Source/WebKit2/PlatformWPE.cmake index 54841370dac93..cc1c5375bcbdb 100644 --- a/Source/WebKit2/PlatformWPE.cmake +++ b/Source/WebKit2/PlatformWPE.cmake @@ -92,7 +92,7 @@ list(APPEND WebKit2_SOURCES WebProcess/Cookies/soup/WebKitSoupCookieJarSqlite.cpp WebProcess/InjectedBundle/wpe/InjectedBundleWPE.cpp WebProcess/MediaCache/WebMediaKeyStorageManager.cpp - WebProcess/MediaStream/wpe/UserMediaPermissionRequestManager.cpp + WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp WebProcess/WebCoreSupport/wpe/WebContextMenuClientWPE.cpp WebProcess/WebCoreSupport/wpe/WebEditorClientWPE.cpp From cf12603bdebe00c20657ce04f1021f247b0b3334 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Wed, 8 Jul 2015 13:56:49 +0200 Subject: [PATCH 144/155] [WPE] fix for get user permissions --- .../wpe/UserMediaPermissionRequestManagerWPE.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp index 47df706cf0ee0..0142b425a03b1 100644 --- a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp @@ -54,10 +54,11 @@ void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) bool allowed = false; // The user permission request dialog is not supported by WPE, so - // there for check a environment varible to contol the grant - if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) + // there for check a environment variable to contol the grant + if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")){ allowed = true; - + } + UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(requestID, allowed); } From b2c72aab55f614ef596984b3eb0c00a93a617cf8 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Wed, 8 Jul 2015 15:12:25 +0200 Subject: [PATCH 145/155] [WPE] fixed get user permissions --- .../UserMediaPermissionRequestManagerWPE.cpp | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp index 0142b425a03b1..c6e4e36812f0c 100644 --- a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp @@ -31,6 +31,7 @@ #include #include +#include "NotImplemented.h" using namespace WebCore; @@ -49,17 +50,16 @@ UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& pa void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) { - uint64_t requestID = m_requestToIDMap.take(&request); - - bool allowed = false; - // The user permission request dialog is not supported by WPE, so // there for check a environment variable to contol the grant - if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")){ - allowed = true; - } - - UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(requestID, allowed); + if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) + { + request.userMediaAccessGranted(); + } + else + { + request.userMediaAccessDenied(); + } } void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest& request) @@ -72,15 +72,7 @@ void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest& request) void UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed) { - RefPtr request = m_idToRequestMap.take(requestID); - if (!request) - return; - m_requestToIDMap.remove(request); - - if (allowed) - request->userMediaAccessGranted(); - else - request->userMediaAccessDenied(); + notImplemented(); } } // namespace WebKit From ae8b078be642e9b55c379f5bfea9f52ef96c0cf0 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 7 Aug 2015 10:56:45 +0200 Subject: [PATCH 146/155] RTCPeerConnection: Extract MediaEndpoint from RTCPeerConnection and add a new abstraction layer (PeerConnectionBackend) --- Source/WebCore/CMakeLists.txt | 1 + .../MediaEndpointPeerConnection.cpp | 663 +++++++++++++++++ .../mediastream/MediaEndpointPeerConnection.h | 109 +++ .../mediastream/PeerConnectionBackend.cpp | 47 ++ .../mediastream/PeerConnectionBackend.h | 96 +++ .../mediastream/PeerConnectionStates.h | 72 ++ .../Modules/mediastream/RTCPeerConnection.cpp | 679 ++---------------- .../Modules/mediastream/RTCPeerConnection.h | 79 +- 8 files changed, 1065 insertions(+), 681 deletions(-) create mode 100644 Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp create mode 100644 Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h create mode 100644 Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp create mode 100644 Source/WebCore/Modules/mediastream/PeerConnectionBackend.h create mode 100644 Source/WebCore/Modules/mediastream/PeerConnectionStates.h diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index a98a46ac24fb0..d4bfd7fd5a3c4 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -902,6 +902,7 @@ set(WebCore_SOURCES Modules/mediastream/MediaConstraintsImpl.cpp Modules/mediastream/MediaDeviceInfo.cpp Modules/mediastream/MediaDevices.cpp + Modules/mediastream/MediaEndpointPeerConnection.cpp Modules/mediastream/MediaSourceStates.cpp Modules/mediastream/MediaStream.cpp Modules/mediastream/MediaStreamCapabilities.cpp diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp new file mode 100644 index 0000000000000..ad14fdc3bd4d0 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp @@ -0,0 +1,663 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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" + +#if ENABLE(MEDIA_STREAM) +#include "MediaEndpointPeerConnection.h" + +#include "CryptoDigest.h" +#include "DOMError.h" +#include "MediaEndpointConfigurationConversions.h" +#include "MediaStreamTrack.h" +#include "PeerConnectionBackend.h" +#include "PeerMediaDescription.h" +#include "RTCConfiguration.h" +#include "RTCIceCandidate.h" +#include "RTCIceCandidateEvent.h" +#include "RTCOfferAnswerOptions.h" +#include "RTCSessionDescription.h" +#include "RTCRtpReceiver.h" +#include "RTCRtpSender.h" +#include "RTCTrackEvent.h" +#include "UUID.h" +#include + +// FIXME: Headers for sdp.js supported SDP conversion is kept on the side for now +#include "Document.h" +#include "Frame.h" +#include "JSDOMWindow.h" +#include "ScriptController.h" +#include "ScriptGlobalObject.h" +#include "ScriptSourceCode.h" +#include "SDPScriptResource.h" +#include + +namespace WebCore { + +using namespace PeerConnectionStates; + +static std::unique_ptr createMediaEndpointPeerConnection(PeerConnectionBackendClient* client) +{ + return std::unique_ptr(new MediaEndpointPeerConnection(client)); +} + +CreatePeerConnectionBackend PeerConnectionBackend::create = createMediaEndpointPeerConnection; + +static RefPtr createMediaEndpointInit(RTCConfiguration& rtcConfig) +{ + Vector> iceServers; + for (auto& server : rtcConfig.iceServers()) + iceServers.append(IceServerInfo::create(server->urls(), server->credential(), server->username())); + + return MediaEndpointInit::create(iceServers, rtcConfig.iceTransportPolicy(), rtcConfig.bundlePolicy()); +} + +MediaEndpointPeerConnection::MediaEndpointPeerConnection(PeerConnectionBackendClient* client) + : m_client(client) +{ + m_mediaEndpoint = MediaEndpoint::create(this); + ASSERT(m_mediaEndpoint); +} + +MediaEndpointPeerConnection::~MediaEndpointPeerConnection() +{ +} + +static RefPtr takeFirstSenderOfType(Vector>& senders, const String& type) +{ + for (unsigned i = 0; i < senders.size(); ++i) { + if (senders[i]->track()->kind() == type) { + RefPtr sender = senders[i]; + senders.remove(i); + return sender; + } + } + return nullptr; +} + +// FIXME: This information should be fetched from the platform +static Vector> createDefaultPayloads(const String& type) +{ + Vector> payloads; + RefPtr payload; + + if (type == "audio") { + payload = MediaPayload::create(); + payload->setType(111); + payload->setEncodingName("OPUS"); + payload->setClockRate(48000); + payload->setChannels(2); + payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(8); + payload->setEncodingName("PCMA"); + payload->setClockRate(8000); + payload->setChannels(1); + payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(0); + payload->setEncodingName("PCMU"); + payload->setClockRate(8000); + payload->setChannels(1); + payloads.append(payload); + } else { + // payload = MediaPayload::create(); + // payload->setType(103); + // payload->setEncodingName("H264"); + // payload->setClockRate(90000); + // payload->setCcmfir(true); + // payload->setNackpli(true); + // payload->addParameter("packetizationMode", 1); + // payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(100); + payload->setEncodingName("VP8"); + payload->setClockRate(90000); + payload->setCcmfir(true); + payload->setNackpli(true); + payload->setNack(true); + payloads.append(payload); + + payload = MediaPayload::create(); + payload->setType(120); + payload->setEncodingName("RTX"); + payload->setClockRate(90000); + payload->addParameter("apt", 100); + payload->addParameter("rtxTime", 200); + payloads.append(payload); + } + + return payloads; +} + +static void updateMediaDescriptionsWithSenders(const Vector>& mediaDescriptions, Vector>& senders) +{ + // Remove any sender(s) from the senders list that already have their tracks represented by a media + // description. Mark media descriptions that don't have a sender/track (anymore) as "available". + for (auto& mdesc : mediaDescriptions) { + const String& mdescTrackId = mdesc->mediaStreamTrackId(); + bool foundSender = senders.removeFirstMatching([mdescTrackId](const RefPtr& sender) -> bool { + return sender->track()->id() == mdescTrackId; + }); + if (!foundSender) { + mdesc->setMediaStreamId(emptyString()); + mdesc->setMediaStreamTrackId(emptyString()); + } + } + + // Remove any sender(s) from the senders list that can be matched (by track type) to an "available" + // media description. Mark media descriptions that don't get matched with a sender as receive only. + for (auto& mdesc : mediaDescriptions) { + if (mdesc->mediaStreamTrackId() != emptyString()) + continue; + + RefPtr sender = takeFirstSenderOfType(senders, mdesc->type()); + if (sender) { + mdesc->setMediaStreamId(sender->mediaStreamId()); + mdesc->setMediaStreamTrackId(sender->track()->id()); + mdesc->setMode("sendrecv"); + } else + mdesc->setMode("recvonly"); + } +} + +void MediaEndpointPeerConnection::createOffer(const RefPtr& options, OfferAnswerResolveCallback resolveCallback, RejectCallback) +{ + RefPtr configurationSnapshot = m_localConfiguration ? + MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); + + Vector> senders = m_client->getSenders(); + updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); + + // Add media descriptions for remaining senders. + for (auto& sender : senders) { + RefPtr mediaDescription = PeerMediaDescription::create(); + MediaStreamTrack* track = sender->track(); + + mediaDescription->setMediaStreamId(sender->mediaStreamId()); + mediaDescription->setMediaStreamTrackId(track->id()); + mediaDescription->setType(track->kind()); + mediaDescription->setMode("sendrecv"); + mediaDescription->setPayloads(createDefaultPayloads(track->kind())); + mediaDescription->setRtcpMux(true); + mediaDescription->setDtlsSetup("actpass"); + + configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); + } + + int extraMediaDescriptionCount = options->offerToReceiveAudio() + options->offerToReceiveVideo(); + for (int i = 0; i < extraMediaDescriptionCount; ++i) { + String type = i < options->offerToReceiveAudio() ? "audio" : "video"; + RefPtr mediaDescription = PeerMediaDescription::create(); + + mediaDescription->setType(type); + mediaDescription->setMode("recvonly"); + mediaDescription->setPayloads(createDefaultPayloads(type)); + mediaDescription->setRtcpMux(true); + mediaDescription->setDtlsSetup("actpass"); + + configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); + } + + String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); + RefPtr offer = RTCSessionDescription::create("offer", toSDP(json)); + resolveCallback(*offer); +} + +void MediaEndpointPeerConnection::createAnswer(const RefPtr&, OfferAnswerResolveCallback resolveCallback, RejectCallback) +{ + RefPtr configurationSnapshot = m_localConfiguration ? + MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); + + for (unsigned i = 0; i < m_remoteConfiguration->mediaDescriptions().size(); ++i) { + RefPtr remoteMediaDescription = m_remoteConfiguration->mediaDescriptions()[i]; + RefPtr localMediaDescription; + + if (i < configurationSnapshot->mediaDescriptions().size()) + localMediaDescription = configurationSnapshot->mediaDescriptions()[i]; + else { + localMediaDescription = PeerMediaDescription::create(); + localMediaDescription->setType(remoteMediaDescription->type()); + localMediaDescription->setDtlsSetup(remoteMediaDescription->dtlsSetup() == "active" ? "passive" : "active"); + + configurationSnapshot->addMediaDescription(localMediaDescription.copyRef()); + } + + localMediaDescription->setPayloads(remoteMediaDescription->payloads()); + + localMediaDescription->setRtcpMux(remoteMediaDescription->rtcpMux()); + + if (localMediaDescription->dtlsSetup() == "actpass") + localMediaDescription->setDtlsSetup("passive"); + } + + Vector> senders = m_client->getSenders(); + updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); + + String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); + RefPtr answer = RTCSessionDescription::create("answer", toSDP(json)); + resolveCallback(*answer); +} + +void MediaEndpointPeerConnection::setLocalDescription(RTCSessionDescription* description, PeerConnectionStates::SignalingState targetState, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) +{ + unsigned previousNumberOfMediaDescriptions = m_localConfiguration ? m_localConfiguration->mediaDescriptions().size() : 0; + + String json = fromSDP(description->sdp()); + m_localConfiguration = MediaEndpointConfigurationConversions::fromJSON(json); + m_localConfigurationType = description->type(); + + if (!m_localConfiguration) { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); + rejectCallback(*error); + return; + } + + bool hasNewMediaDescriptions = m_localConfiguration->mediaDescriptions().size() > previousNumberOfMediaDescriptions; + bool isInitiator = m_localConfigurationType == "offer"; + + m_resolveSetLocalDescription = [this, targetState, resolveCallback]() mutable { + m_client->changeSignalingState(targetState); + resolveCallback(); + }; + + if (hasNewMediaDescriptions) + m_mediaEndpoint->prepareToReceive(m_localConfiguration.get(), isInitiator); + + if (m_remoteConfiguration) + m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); +} + +RefPtr MediaEndpointPeerConnection::localDescription() const +{ + if (!m_localConfiguration) + return nullptr; + + String json = MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get()); + return RTCSessionDescription::create(m_localConfigurationType, toSDP(json)); +} + +static Vector> filterPayloads(const Vector>& remotePayloads, const String& type) +{ + Vector> defaultPayloads = createDefaultPayloads(type); + Vector> filteredPayloads; + + for (auto& remotePayload : remotePayloads) { + MediaPayload* defaultPayload = nullptr; + for (auto& p : defaultPayloads) { + if (p->encodingName() == remotePayload->encodingName().upper()) { + defaultPayload = p.get(); + break; + } + } + if (!defaultPayload) + continue; + + if (defaultPayload->parameters().contains("packetizationMode") && remotePayload->parameters().contains("packetizationMode") + && (defaultPayload->parameters().get("packetizationMode") != defaultPayload->parameters().get("packetizationMode"))) + continue; + + filteredPayloads.append(remotePayload); + } + + return filteredPayloads; +} + +void MediaEndpointPeerConnection::setRemoteDescription(RTCSessionDescription* description, PeerConnectionStates::SignalingState targetState, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) +{ + String json = fromSDP(description->sdp()); + m_remoteConfiguration = MediaEndpointConfigurationConversions::fromJSON(json); + m_remoteConfigurationType = description->type(); + + if (!m_remoteConfiguration) { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); + rejectCallback(*error); + return; + } + + Vector> senders = m_client->getSenders(); + + for (auto& mediaDescription : m_remoteConfiguration->mediaDescriptions()) { + if (mediaDescription->type() != "audio" && mediaDescription->type() != "video") + continue; + + mediaDescription->setPayloads(filterPayloads(mediaDescription->payloads(), mediaDescription->type())); + + RefPtr sender = takeFirstSenderOfType(senders, mediaDescription->type()); + if (sender) + mediaDescription->setSource(sender->track()->source()); + } + + bool isInitiator = m_remoteConfigurationType == "answer"; + m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); + + // FIXME: event firing task should update state + m_client->changeSignalingState(targetState); + + resolveCallback(); +} + +RefPtr MediaEndpointPeerConnection::remoteDescription() const +{ + if (!m_remoteConfiguration) + return nullptr; + + String json = MediaEndpointConfigurationConversions::toJSON(m_remoteConfiguration.get()); + return RTCSessionDescription::create(m_remoteConfigurationType, toSDP(json)); +} + +void MediaEndpointPeerConnection::setConfiguration(RTCConfiguration& configuration) +{ + // FIXME: updateIce() might be renamed to setConfiguration(). It's also possible + // that its current behavior with update deltas will change. + m_mediaEndpoint->setConfiguration(createMediaEndpointInit(configuration)); +} + +void MediaEndpointPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) +{ + String json = iceCandidateFromSDP(rtcCandidate->candidate()); + RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(json); + if (!candidate) { + // FIXME: Error type? + RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); + rejectCallback(*error); + return; + } + + unsigned mdescIndex = rtcCandidate->sdpMLineIndex(); + if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { + // FIXME: Error type? + RefPtr error = DOMError::create("InvalidSdpMlineIndex (sdpMLineIndex out of range"); + rejectCallback(*error); + return; + } + + PeerMediaDescription& mdesc = *m_remoteConfiguration->mediaDescriptions()[mdescIndex]; + mdesc.addIceCandidate(candidate.copyRef()); + + m_mediaEndpoint->addRemoteCandidate(*candidate, mdescIndex, mdesc.iceUfrag(), mdesc.icePassword()); + + resolveCallback(); +} + +void MediaEndpointPeerConnection::stop() +{ + m_mediaEndpoint->stop(); +} + +bool MediaEndpointPeerConnection::isLocalConfigurationComplete() const +{ + for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { + if (mdesc->dtlsFingerprint().isEmpty() || mdesc->iceUfrag().isEmpty()) + return false; + // Test: No trickle + if (!mdesc->iceCandidateGatheringDone()) + return false; + if (mdesc->type() == "audio" || mdesc->type() == "video") { + if (!mdesc->ssrcs().size() || mdesc->cname().isEmpty()) + return false; + } + } + + return true; +} + +MediaEndpointPeerConnection::ResolveSetLocalDescriptionResult MediaEndpointPeerConnection::maybeResolveSetLocalDescription() +{ + if (!m_resolveSetLocalDescription) { + ASSERT(isLocalConfigurationComplete()); + return SetLocalDescriptionAlreadyResolved; + } + + if (isLocalConfigurationComplete()) { + m_resolveSetLocalDescription(); + m_resolveSetLocalDescription = nullptr; + return SetLocalDescriptionResolvedSuccessfully; + } + + return LocalConfigurationIncomplete; +} + +void MediaEndpointPeerConnection::maybeDispatchGatheringDone() +{ + if (!isLocalConfigurationComplete()) + return; + + for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { + if (!mdesc->iceCandidateGatheringDone()) + return; + } + + m_client->scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, nullptr)); +} + +void MediaEndpointPeerConnection::gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) +{ + printf("-> gotSendSSRC()\n"); + + m_localConfiguration->mediaDescriptions()[mdescIndex]->addSsrc(ssrc); + m_localConfiguration->mediaDescriptions()[mdescIndex]->setCname(cname); + + maybeResolveSetLocalDescription(); +} + +void MediaEndpointPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& certificate) +{ + Vector certificateRows; + Vector der; + + der.reserveCapacity(certificate.length() * 3/4 + 2); + certificate.split("\n", certificateRows); + + for (auto& row : certificateRows) { + if (row.startsWith("-----")) + continue; + + Vector decodedRow; + if (!base64Decode(row, decodedRow, Base64FailOnInvalidCharacterOrExcessPadding)) { + ASSERT_NOT_REACHED(); + return; + } + der.appendVector(decodedRow); + } + + std::unique_ptr digest = CryptoDigest::create(CryptoAlgorithmIdentifier::SHA_256); + if (!digest) { + ASSERT_NOT_REACHED(); + return; + } + + digest->addBytes(der.data(), der.size()); + Vector fingerprintVector = digest->computeHash(); + + StringBuilder fingerprint; + for (unsigned i = 0; i < fingerprintVector.size(); ++i) + fingerprint.append(String::format(i ? ":%02X" : "%02X", fingerprintVector[i])); + + m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprintHashFunction("sha-256"); + m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprint(fingerprint.toString()); + + if (maybeResolveSetLocalDescription() == SetLocalDescriptionResolvedSuccessfully) + maybeDispatchGatheringDone(); +} + +void MediaEndpointPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate, const String& ufrag, const String& password) +{ + printf("-> gotIceCandidate()\n"); + + ASSERT(scriptExecutionContext()->isContextThread()); + + PeerMediaDescription& mdesc = *m_localConfiguration->mediaDescriptions()[mdescIndex]; + if (mdesc.iceUfrag().isEmpty()) { + mdesc.setIceUfrag(ufrag); + mdesc.setIcePassword(password); + } + + mdesc.addIceCandidate(candidate.copyRef()); + + if (!candidate->address().contains(':')) { // not IPv6 + if (candidate->componentId() == 1) { // RTP + if (mdesc.address().isEmpty() || mdesc.address() == "0.0.0.0") { + mdesc.setAddress(candidate->address()); + mdesc.setPort(candidate->port()); + } + } else { // RTCP + if (mdesc.rtcpAddress().isEmpty() || !mdesc.rtcpPort()) { + mdesc.setRtcpAddress(candidate->address()); + mdesc.setRtcpPort(candidate->port()); + } + } + } + + ResolveSetLocalDescriptionResult result = maybeResolveSetLocalDescription(); + if (result == SetLocalDescriptionResolvedSuccessfully) + maybeDispatchGatheringDone(); + else if (result == SetLocalDescriptionAlreadyResolved) { + String candidateString = MediaEndpointConfigurationConversions::iceCandidateToJSON(candidate.get()); + String sdpFragment = iceCandidateToSDP(candidateString); + RefPtr iceCandidate = RTCIceCandidate::create(sdpFragment, "", mdescIndex); + m_client->scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, WTF::move(iceCandidate))); + } +} + +void MediaEndpointPeerConnection::doneGatheringCandidates(unsigned mdescIndex) +{ + printf("-> doneGatheringCandidates()\n"); + + ASSERT(scriptExecutionContext()->isContextThread()); + + m_localConfiguration->mediaDescriptions()[mdescIndex]->setIceCandidateGatheringDone(true); + // Test: No trickle + maybeResolveSetLocalDescription(); + maybeDispatchGatheringDone(); +} + +void MediaEndpointPeerConnection::gotRemoteSource(unsigned mdescIndex, RefPtr&& source) +{ + if (m_client->internalSignalingState() == SignalingState::Closed) + return; + + if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { + printf("Warning: No remote configuration for incoming source.\n"); + return; + } + + PeerMediaDescription& mediaDescription = *m_remoteConfiguration->mediaDescriptions()[mdescIndex]; + String trackId = mediaDescription.mediaStreamTrackId(); + + if (trackId.isEmpty()) { + // Non WebRTC media description (e.g. legacy) + trackId = createCanonicalUUIDString(); + } + + // FIXME: track should be set to muted (not supported yet) + // FIXME: MediaStream handling not implemented + + RefPtr trackPrivate = MediaStreamTrackPrivate::create(WTF::move(source), trackId); + RefPtr track = MediaStreamTrack::create(*m_client->context(), *trackPrivate); + RefPtr receiver = RTCRtpReceiver::create(track.copyRef()); + + m_client->scheduleDispatchEvent(RTCTrackEvent::create(eventNames().trackEvent, false, false, WTF::move(receiver), WTF::move(track))); +} + +String MediaEndpointPeerConnection::toSDP(const String& json) const +{ + return sdpConversion("toSDP", json); +} + +String MediaEndpointPeerConnection::fromSDP(const String& sdp) const +{ + return sdpConversion("fromSDP", sdp); +} + +String MediaEndpointPeerConnection::iceCandidateToSDP(const String& json) const +{ + return sdpConversion("iceCandidateToSDP", json); +} + +String MediaEndpointPeerConnection::iceCandidateFromSDP(const String& sdpFragment) const +{ + return sdpConversion("iceCandidateFromSDP", sdpFragment); +} + +String MediaEndpointPeerConnection::sdpConversion(const String& functionName, const String& argument) const +{ + Document* document = downcast(m_client->context()); + + if (!m_isolatedWorld) + m_isolatedWorld = DOMWrapperWorld::create(JSDOMWindow::commonVM()); + + ScriptController& scriptController = document->frame()->script(); + JSDOMGlobalObject* globalObject = JSC::jsCast(scriptController.globalObject(*m_isolatedWorld)); + JSC::ExecState* exec = globalObject->globalExec(); + JSC::JSLockHolder lock(exec); + + JSC::JSValue probeFunctionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, "toSDP")); + if (!probeFunctionValue.isFunction()) { + URL scriptURL; + scriptController.evaluateInWorld(ScriptSourceCode(SDPScriptResource::getString(), scriptURL), *m_isolatedWorld); + if (exec->hadException()) { + exec->clearException(); + return emptyString(); + } + } + + JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, functionName)); + if (!functionValue.isFunction()) + return emptyString(); + + JSC::JSObject* function = functionValue.toObject(exec); + JSC::CallData callData; + JSC::CallType callType = function->methodTable()->getCallData(function, callData); + if (callType == JSC::CallTypeNone) + return emptyString(); + + JSC::MarkedArgumentBuffer argList; + argList.append(JSC::jsString(exec, argument)); + + JSC::JSValue result = JSC::call(exec, function, callType, callData, globalObject, argList); + if (exec->hadException()) { + printf("sdpConversion: js function (%s) threw\n", functionName.ascii().data()); + exec->clearException(); + return emptyString(); + } + + return result.isString() ? result.getString(exec) : emptyString(); +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h new file mode 100644 index 0000000000000..c6ceae1d9d262 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef MediaEndpointPeerConnection_h +#define MediaEndpointPeerConnection_h + +#if ENABLE(MEDIA_STREAM) + +#include "MediaEndpoint.h" +#include "MediaEndpointConfiguration.h" +#include "PeerConnectionBackend.h" +#include +#include + +namespace WebCore { + +class DOMWrapperWorld; + +class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEndpointClient { +public: + MediaEndpointPeerConnection(PeerConnectionBackendClient*); + ~MediaEndpointPeerConnection(); + + void createOffer(const RefPtr&, OfferAnswerResolveCallback, RejectCallback) override; + void createAnswer(const RefPtr&, OfferAnswerResolveCallback, RejectCallback) override; + + void setLocalDescription(RTCSessionDescription*, PeerConnectionStates::SignalingState targetState, VoidResolveCallback, RejectCallback) override; + RefPtr localDescription() const override; + + void setRemoteDescription(RTCSessionDescription*, PeerConnectionStates::SignalingState targetState, VoidResolveCallback, RejectCallback) override; + RefPtr remoteDescription() const override; + + void setConfiguration(RTCConfiguration&) override; + void addIceCandidate(RTCIceCandidate*, VoidResolveCallback, RejectCallback) override; + + void stop() override; + +private: + enum ResolveSetLocalDescriptionResult { + LocalConfigurationIncomplete, + SetLocalDescriptionResolvedSuccessfully, + SetLocalDescriptionAlreadyResolved + }; + + bool isLocalConfigurationComplete() const; + ResolveSetLocalDescriptionResult maybeResolveSetLocalDescription(); + void maybeDispatchGatheringDone(); + + // MediaEndpointClient + virtual void gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) override; + virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; + virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) override; + virtual void doneGatheringCandidates(unsigned mdescIndex) override; + virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; + + String toSDP(const String& json) const; + String fromSDP(const String& sdp) const; + String iceCandidateToSDP(const String& json) const; + String iceCandidateFromSDP(const String& sdpFragment) const; + String sdpConversion(const String& functionName, const String& argument) const; + + PeerConnectionBackendClient* m_client; + std::unique_ptr m_mediaEndpoint; + + mutable RefPtr m_isolatedWorld; + + RefPtr m_localConfiguration; + RefPtr m_remoteConfiguration; + + String m_localConfigurationType; + String m_remoteConfigurationType; + + std::function m_resolveSetLocalDescription; + + RefPtr m_configuration; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // MediaEndpointPeerConnection_h diff --git a/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp new file mode 100644 index 0000000000000..8900efc18e206 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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" + +#if ENABLE(MEDIA_STREAM) +#include "PeerConnectionBackend.h" + +namespace WebCore { + +static std::unique_ptr createPeerConnectionBackend(PeerConnectionBackendClient*) +{ + return nullptr; +} + +CreatePeerConnectionBackend PeerConnectionBackend::create = createPeerConnectionBackend; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) diff --git a/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h new file mode 100644 index 0000000000000..cbf714573975a --- /dev/null +++ b/Source/WebCore/Modules/mediastream/PeerConnectionBackend.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef PeerConnectionBackend_h +#define PeerConnectionBackend_h + +#if ENABLE(MEDIA_STREAM) + +#include "PeerConnectionStates.h" + +namespace WebCore { + +class DOMError; +class Event; +class PeerConnectionBackend; +class RTCAnswerOptions; +class RTCConfiguration; +class RTCIceCandidate; +class RTCOfferOptions; +class RTCRtpSender; +class RTCSessionDescription; +class ScriptExecutionContext; + +class PeerConnectionBackendClient { +public: + virtual Vector> getSenders() const = 0; + virtual void scheduleDispatchEvent(PassRefPtr) = 0; + + virtual void changeSignalingState(PeerConnectionStates::SignalingState) = 0; + virtual void changeIceGatheringState(PeerConnectionStates::IceGatheringState) = 0; + virtual void changeIceConnectionState(PeerConnectionStates::IceConnectionState) = 0; + + virtual ScriptExecutionContext* context() const = 0; + virtual PeerConnectionStates::SignalingState internalSignalingState() const = 0; + + virtual ~PeerConnectionBackendClient() { } +}; + +typedef std::unique_ptr (*CreatePeerConnectionBackend)(PeerConnectionBackendClient*); + +class PeerConnectionBackend { +public: + WEBCORE_EXPORT static CreatePeerConnectionBackend create; + virtual ~PeerConnectionBackend() { } + + typedef std::function OfferAnswerResolveCallback; + typedef std::function VoidResolveCallback; + typedef std::function RejectCallback; + + virtual void createOffer(const RefPtr&, OfferAnswerResolveCallback, RejectCallback) = 0; + virtual void createAnswer(const RefPtr&, OfferAnswerResolveCallback, RejectCallback) = 0; + + virtual void setLocalDescription(RTCSessionDescription*, PeerConnectionStates::SignalingState targetState, VoidResolveCallback, RejectCallback) = 0; + virtual RefPtr localDescription() const = 0; + + virtual void setRemoteDescription(RTCSessionDescription*, PeerConnectionStates::SignalingState targetState, VoidResolveCallback, RejectCallback) = 0; + virtual RefPtr remoteDescription() const = 0; + + virtual void setConfiguration(RTCConfiguration&) = 0; + virtual void addIceCandidate(RTCIceCandidate*, VoidResolveCallback, RejectCallback) = 0; + + virtual void stop() = 0; +}; + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // PeerConnectionBackend_h diff --git a/Source/WebCore/Modules/mediastream/PeerConnectionStates.h b/Source/WebCore/Modules/mediastream/PeerConnectionStates.h new file mode 100644 index 0000000000000..df2956d4dd071 --- /dev/null +++ b/Source/WebCore/Modules/mediastream/PeerConnectionStates.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015 Ericsson AB. All rights reserved. + * + * 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. + * 3. Neither the name of Ericsson nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef PeerConnectionStates_h +#define PeerConnectionStates_h + +#if ENABLE(MEDIA_STREAM) + +namespace WebCore { + +namespace PeerConnectionStates { + +enum class SignalingState { + Stable = 1, + HaveLocalOffer = 2, + HaveRemoteOffer = 3, + HaveLocalPrAnswer = 4, + HaveRemotePrAnswer = 5, + Closed = 6, + Invalid = 7 +}; + +enum class IceConnectionState { + New = 1, + Checking = 2, + Connected = 3, + Completed = 4, + Failed = 5, + Disconnected = 6, + Closed = 7 +}; + +enum class IceGatheringState { + New = 1, + Gathering = 2, + Complete = 3 +}; + +} + +} // namespace WebCore + +#endif // ENABLE(MEDIA_STREAM) + +#endif // PeerConnectionStates_h diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp index 2fbb91db84824..3c8efe0ef7fb0 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp @@ -36,18 +36,13 @@ #include "RTCPeerConnection.h" -#include "CryptoDigest.h" #include "DOMError.h" #include "Document.h" #include "Event.h" #include "ExceptionCode.h" #include "Frame.h" -#include "MediaEndpointConfiguration.h" -#include "MediaEndpointConfigurationConversions.h" -#include "MediaEndpointInit.h" #include "MediaStream.h" #include "MediaStreamTrack.h" -#include "PeerMediaDescription.h" #include "RTCConfiguration.h" #include "RTCDataChannel.h" #include "RTCIceCandidate.h" @@ -57,28 +52,12 @@ #include "RTCRtpSender.h" #include "RTCSessionDescription.h" #include "RTCTrackEvent.h" -#include "UUID.h" #include #include -// FIXME: Headers for sdp.js supported SDP conversion is kept on the side for now -#include "JSDOMWindow.h" -#include "ScriptController.h" -#include "ScriptGlobalObject.h" -#include "ScriptSourceCode.h" -#include "SDPScriptResource.h" -#include - namespace WebCore { -static RefPtr createMediaEndpointInit(RTCConfiguration& rtcConfig) -{ - Vector> iceServers; - for (auto& server : rtcConfig.iceServers()) - iceServers.append(IceServerInfo::create(server->urls(), server->credential(), server->username())); - - return MediaEndpointInit::create(iceServers, rtcConfig.iceTransportPolicy(), rtcConfig.bundlePolicy()); -} +using namespace PeerConnectionStates; RefPtr RTCPeerConnection::create(ScriptExecutionContext& context, const Dictionary& rtcConfiguration, ExceptionCode& ec) { @@ -101,10 +80,9 @@ RefPtr RTCPeerConnection::create(ScriptExecutionContext& cont RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr configuration, ExceptionCode& ec) : ActiveDOMObject(&context) - , m_signalingState(SignalingStateStable) - , m_iceGatheringState(IceGatheringStateNew) - , m_iceConnectionState(IceConnectionStateNew) - , m_resolveSetLocalDescription(nullptr) + , m_signalingState(SignalingState::Stable) + , m_iceGatheringState(IceGatheringState::New) + , m_iceConnectionState(IceConnectionState::New) , m_scheduledEventTimer(*this, &RTCPeerConnection::scheduledEventTimerFired) , m_configuration(configuration) , m_stopped(false) @@ -118,13 +96,13 @@ RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext& context, PassRefPtr return; } - m_mediaEndpoint = MediaEndpoint::create(this); - if (!m_mediaEndpoint) { + m_backend = PeerConnectionBackend::create(this); + if (!m_backend) { ec = NOT_SUPPORTED_ERR; return; } - m_mediaEndpoint->setConfiguration(createMediaEndpointInit(*m_configuration)); + m_backend->setConfiguration(*m_configuration); } RTCPeerConnection::~RTCPeerConnection() @@ -152,7 +130,7 @@ Vector> RTCPeerConnection::getReceivers() const RefPtr RTCPeerConnection::addTrack(RefPtr&& track, const MediaStream* stream, ExceptionCode& ec) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { ec = INVALID_STATE_ERR; return nullptr; } @@ -171,7 +149,7 @@ RefPtr RTCPeerConnection::addTrack(RefPtr&& trac void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { ec = INVALID_STATE_ERR; return; } @@ -182,110 +160,9 @@ void RTCPeerConnection::removeTrack(RTCRtpSender* sender, ExceptionCode& ec) // FIXME: Mark connection as needing negotiation. } -static RTCRtpSender* takeFirstSenderOfType(Vector& senders, const String& type) -{ - for (unsigned i = 0; i < senders.size(); ++i) { - if (senders[i]->track()->kind() == type) { - RTCRtpSender* sender = senders[i]; - senders.remove(i); - return sender; - } - } - return nullptr; -} - -static void updateMediaDescriptionsWithSenders(const Vector>& mediaDescriptions, Vector& senders) -{ - // Remove any sender(s) from the senders list that already have their tracks represented by a media - // description. Mark media descriptions that don't have a sender/track (anymore) as "available". - for (auto& mdesc : mediaDescriptions) { - const String& mdescTrackId = mdesc->mediaStreamTrackId(); - bool foundSender = senders.removeFirstMatching([mdescTrackId](const RTCRtpSender* sender) -> bool { - return sender->track()->id() == mdescTrackId; - }); - if (!foundSender) { - mdesc->setMediaStreamId(emptyString()); - mdesc->setMediaStreamTrackId(emptyString()); - } - } - - // Remove any sender(s) from the senders list that can be matched (by track type) to an "available" - // media description. Mark media descriptions that don't get matched with a sender as receive only. - for (auto& mdesc : mediaDescriptions) { - if (mdesc->mediaStreamTrackId() != emptyString()) - continue; - - RTCRtpSender* sender = takeFirstSenderOfType(senders, mdesc->type()); - if (sender) { - mdesc->setMediaStreamId(sender->mediaStreamId()); - mdesc->setMediaStreamTrackId(sender->track()->id()); - mdesc->setMode("sendrecv"); - } else - mdesc->setMode("recvonly"); - } -} - -// FIXME: This information should be fetched from the platform -static Vector> createDefaultPayloads(const String& type) -{ - Vector> payloads; - RefPtr payload; - - if (type == "audio") { - payload = MediaPayload::create(); - payload->setType(111); - payload->setEncodingName("OPUS"); - payload->setClockRate(48000); - payload->setChannels(2); - payloads.append(payload); - - payload = MediaPayload::create(); - payload->setType(8); - payload->setEncodingName("PCMA"); - payload->setClockRate(8000); - payload->setChannels(1); - payloads.append(payload); - - payload = MediaPayload::create(); - payload->setType(0); - payload->setEncodingName("PCMU"); - payload->setClockRate(8000); - payload->setChannels(1); - payloads.append(payload); - } else { - // payload = MediaPayload::create(); - // payload->setType(103); - // payload->setEncodingName("H264"); - // payload->setClockRate(90000); - // payload->setCcmfir(true); - // payload->setNackpli(true); - // payload->addParameter("packetizationMode", 1); - // payloads.append(payload); - - payload = MediaPayload::create(); - payload->setType(100); - payload->setEncodingName("VP8"); - payload->setClockRate(90000); - payload->setCcmfir(true); - payload->setNackpli(true); - payload->setNack(true); - payloads.append(payload); - - payload = MediaPayload::create(); - payload->setType(120); - payload->setEncodingName("RTX"); - payload->setClockRate(90000); - payload->addParameter("apt", 100); - payload->addParameter("rtxTime", 200); - payloads.append(payload); - } - - return payloads; -} - void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { RefPtr error = DOMError::create("InvalidStateError"); rejectCallback(*error); return; @@ -299,53 +176,12 @@ void RTCPeerConnection::createOffer(const Dictionary& offerOptions, OfferAnswerR return; } - RefPtr configurationSnapshot = m_localConfiguration ? - MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); - - Vector senders; - for (auto& sender : m_senderSet.values()) - senders.append(sender.get()); - - updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); - - // Add media descriptions for remaining senders. - for (auto sender : senders) { - RefPtr mediaDescription = PeerMediaDescription::create(); - MediaStreamTrack* track = sender->track(); - - mediaDescription->setMediaStreamId(sender->mediaStreamId()); - mediaDescription->setMediaStreamTrackId(track->id()); - mediaDescription->setType(track->kind()); - mediaDescription->setMode("sendrecv"); - mediaDescription->setPayloads(createDefaultPayloads(track->kind())); - mediaDescription->setRtcpMux(true); - mediaDescription->setDtlsSetup("actpass"); - - configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); - } - - int extraMediaDescriptionCount = options->offerToReceiveAudio() + options->offerToReceiveVideo(); - for (int i = 0; i < extraMediaDescriptionCount; ++i) { - String type = i < options->offerToReceiveAudio() ? "audio" : "video"; - RefPtr mediaDescription = PeerMediaDescription::create(); - - mediaDescription->setType(type); - mediaDescription->setMode("recvonly"); - mediaDescription->setPayloads(createDefaultPayloads(type)); - mediaDescription->setRtcpMux(true); - mediaDescription->setDtlsSetup("actpass"); - - configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); - } - - String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); - RefPtr offer = RTCSessionDescription::create("offer", toSDP(json)); - resolveCallback(*offer); + m_backend->createOffer(options, resolveCallback, rejectCallback); } void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { RefPtr error = DOMError::create("InvalidStateError"); rejectCallback(*error); return; @@ -359,52 +195,19 @@ void RTCPeerConnection::createAnswer(const Dictionary& answerOptions, OfferAnswe return; } - if (!m_remoteConfiguration) { + if (!remoteDescription()) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidStateError (no remote description)"); rejectCallback(*error); return; } - RefPtr configurationSnapshot = m_localConfiguration ? - MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); - - for (unsigned i = 0; i < m_remoteConfiguration->mediaDescriptions().size(); ++i) { - RefPtr remoteMediaDescription = m_remoteConfiguration->mediaDescriptions()[i]; - RefPtr localMediaDescription; - - if (i < configurationSnapshot->mediaDescriptions().size()) - localMediaDescription = configurationSnapshot->mediaDescriptions()[i]; - else { - localMediaDescription = PeerMediaDescription::create(); - localMediaDescription->setType(remoteMediaDescription->type()); - localMediaDescription->setDtlsSetup(remoteMediaDescription->dtlsSetup() == "active" ? "passive" : "active"); - - configurationSnapshot->addMediaDescription(localMediaDescription.copyRef()); - } - - localMediaDescription->setPayloads(remoteMediaDescription->payloads()); - - localMediaDescription->setRtcpMux(remoteMediaDescription->rtcpMux()); - - if (localMediaDescription->dtlsSetup() == "actpass") - localMediaDescription->setDtlsSetup("passive"); - } - - Vector senders; - for (auto& sender : m_senderSet.values()) - senders.append(sender.get()); - - updateMediaDescriptionsWithSenders(configurationSnapshot->mediaDescriptions(), senders); - - String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); - RefPtr answer = RTCSessionDescription::create("answer", toSDP(json)); - resolveCallback(*answer); + m_backend->createAnswer(options, resolveCallback, rejectCallback); } void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { RefPtr error = DOMError::create("InvalidStateError"); rejectCallback(*error); return; @@ -413,80 +216,24 @@ void RTCPeerConnection::setLocalDescription(RTCSessionDescription* description, DescriptionType descriptionType = parseDescriptionType(description->type()); SignalingState targetState = targetSignalingState(SetterTypeLocal, descriptionType); - if (targetState == SignalingStateInvalid) { + if (targetState == SignalingState::Invalid) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError"); rejectCallback(*error); return; } - unsigned previousNumberOfMediaDescriptions = m_localConfiguration ? m_localConfiguration->mediaDescriptions().size() : 0; - - String json = fromSDP(description->sdp()); - m_localConfiguration = MediaEndpointConfigurationConversions::fromJSON(json); - m_localConfigurationType = description->type(); - - if (!m_localConfiguration) { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); - rejectCallback(*error); - return; - } - - bool hasNewMediaDescriptions = m_localConfiguration->mediaDescriptions().size() > previousNumberOfMediaDescriptions; - bool isInitiator = descriptionType == DescriptionTypeOffer; - - RefPtr protectedThis(this); - m_resolveSetLocalDescription = [targetState, resolveCallback, protectedThis]() mutable { - protectedThis->m_signalingState = targetState; - resolveCallback(); - }; - - if (hasNewMediaDescriptions) - m_mediaEndpoint->prepareToReceive(m_localConfiguration.get(), isInitiator); - - if (m_remoteConfiguration) - m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); + m_backend->setLocalDescription(description, targetState, resolveCallback, rejectCallback); } RefPtr RTCPeerConnection::localDescription() const { - if (!m_localConfiguration) - return nullptr; - - String json = MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get()); - return RTCSessionDescription::create(m_localConfigurationType, toSDP(json)); -} - -static Vector> filterPayloads(const Vector>& remotePayloads, const String& type) -{ - Vector> defaultPayloads = createDefaultPayloads(type); - Vector> filteredPayloads; - - for (auto& remotePayload : remotePayloads) { - MediaPayload* defaultPayload = nullptr; - for (auto& p : defaultPayloads) { - if (p->encodingName() == remotePayload->encodingName().upper()) { - defaultPayload = p.get(); - break; - } - } - if (!defaultPayload) - continue; - - if (defaultPayload->parameters().contains("packetizationMode") && remotePayload->parameters().contains("packetizationMode") - && (defaultPayload->parameters().get("packetizationMode") != defaultPayload->parameters().get("packetizationMode"))) - continue; - - filteredPayloads.append(remotePayload); - } - - return filteredPayloads; + return m_backend->localDescription(); } void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { RefPtr error = DOMError::create("InvalidStateError"); rejectCallback(*error); return; @@ -495,60 +242,24 @@ void RTCPeerConnection::setRemoteDescription(RTCSessionDescription* description, DescriptionType descriptionType = parseDescriptionType(description->type()); SignalingState targetState = targetSignalingState(SetterTypeRemote, descriptionType); - if (targetState == SignalingStateInvalid) { + if (targetState == SignalingState::Invalid) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError"); rejectCallback(*error); return; } - String json = fromSDP(description->sdp()); - m_remoteConfiguration = MediaEndpointConfigurationConversions::fromJSON(json); - m_remoteConfigurationType = description->type(); - - if (!m_remoteConfiguration) { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); - rejectCallback(*error); - return; - } - - Vector senders; - for (auto& sender : m_senderSet.values()) - senders.append(sender.get()); - - for (auto& mediaDescription : m_remoteConfiguration->mediaDescriptions()) { - if (mediaDescription->type() != "audio" && mediaDescription->type() != "video") - continue; - - mediaDescription->setPayloads(filterPayloads(mediaDescription->payloads(), mediaDescription->type())); - - RTCRtpSender* sender = takeFirstSenderOfType(senders, mediaDescription->type()); - if (sender) - mediaDescription->setSource(sender->track()->source()); - } - - bool isInitiator = m_remoteConfigurationType == "answer"; - m_mediaEndpoint->prepareToSend(m_remoteConfiguration.get(), isInitiator); - - // FIXME: event firing task should update state - m_signalingState = targetState; - - resolveCallback(); + m_backend->setRemoteDescription(description, targetState, resolveCallback, rejectCallback); } RefPtr RTCPeerConnection::remoteDescription() const { - if (!m_remoteConfiguration) - return nullptr; - - String json = MediaEndpointConfigurationConversions::toJSON(m_remoteConfiguration.get()); - return RTCSessionDescription::create(m_remoteConfigurationType, toSDP(json)); + return m_backend->remoteDescription(); } void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionCode& ec) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { ec = INVALID_STATE_ERR; return; } @@ -557,67 +268,43 @@ void RTCPeerConnection::updateIce(const Dictionary& rtcConfiguration, ExceptionC if (ec) return; - // FIXME: updateIce() might be renamed to setConfiguration(). It's also possible - // that its current behavior with update deltas will change. - m_mediaEndpoint->setConfiguration(createMediaEndpointInit(*m_configuration)); + m_backend->setConfiguration(*m_configuration); } void RTCPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { RefPtr error = DOMError::create("InvalidStateError"); rejectCallback(*error); return; } - if (!m_remoteConfiguration) { + if (!remoteDescription()) { // FIXME: Error type? RefPtr error = DOMError::create("InvalidStateError (no remote description)"); rejectCallback(*error); return; } - String json = iceCandidateFromSDP(rtcCandidate->candidate()); - RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(json); - if (!candidate) { - // FIXME: Error type? - RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); - rejectCallback(*error); - return; - } - - unsigned mdescIndex = rtcCandidate->sdpMLineIndex(); - if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { - // FIXME: Error type? - RefPtr error = DOMError::create("InvalidSdpMlineIndex (sdpMLineIndex out of range"); - rejectCallback(*error); - return; - } - - PeerMediaDescription& mdesc = *m_remoteConfiguration->mediaDescriptions()[mdescIndex]; - mdesc.addIceCandidate(candidate.copyRef()); - - m_mediaEndpoint->addRemoteCandidate(*candidate, mdescIndex, mdesc.iceUfrag(), mdesc.icePassword()); - - resolveCallback(); + m_backend->addIceCandidate(rtcCandidate, resolveCallback, rejectCallback); } String RTCPeerConnection::signalingState() const { switch (m_signalingState) { - case SignalingStateStable: + case SignalingState::Stable: return ASCIILiteral("stable"); - case SignalingStateHaveLocalOffer: + case SignalingState::HaveLocalOffer: return ASCIILiteral("have-local-offer"); - case SignalingStateHaveRemoteOffer: + case SignalingState::HaveRemoteOffer: return ASCIILiteral("have-remote-offer"); - case SignalingStateHaveLocalPrAnswer: + case SignalingState::HaveLocalPrAnswer: return ASCIILiteral("have-local-pranswer"); - case SignalingStateHaveRemotePrAnswer: + case SignalingState::HaveRemotePrAnswer: return ASCIILiteral("have-remote-pranswer"); - case SignalingStateClosed: + case SignalingState::Closed: return ASCIILiteral("closed"); - case SignalingStateInvalid: + case SignalingState::Invalid: break; } @@ -628,11 +315,11 @@ String RTCPeerConnection::signalingState() const String RTCPeerConnection::iceGatheringState() const { switch (m_iceGatheringState) { - case IceGatheringStateNew: + case IceGatheringState::New: return ASCIILiteral("new"); - case IceGatheringStateGathering: + case IceGatheringState::Gathering: return ASCIILiteral("gathering"); - case IceGatheringStateComplete: + case IceGatheringState::Complete: return ASCIILiteral("complete"); } @@ -643,19 +330,19 @@ String RTCPeerConnection::iceGatheringState() const String RTCPeerConnection::iceConnectionState() const { switch (m_iceConnectionState) { - case IceConnectionStateNew: + case IceConnectionState::New: return ASCIILiteral("new"); - case IceConnectionStateChecking: + case IceConnectionState::Checking: return ASCIILiteral("checking"); - case IceConnectionStateConnected: + case IceConnectionState::Connected: return ASCIILiteral("connected"); - case IceConnectionStateCompleted: + case IceConnectionState::Completed: return ASCIILiteral("completed"); - case IceConnectionStateFailed: + case IceConnectionState::Failed: return ASCIILiteral("failed"); - case IceConnectionStateDisconnected: + case IceConnectionState::Disconnected: return ASCIILiteral("disconnected"); - case IceConnectionStateClosed: + case IceConnectionState::Closed: return ASCIILiteral("closed"); } @@ -674,7 +361,7 @@ void RTCPeerConnection::getStats(PassRefPtr, PassRefPtr RTCPeerConnection::createDataChannel(String, const Dictionary&, ExceptionCode& ec) { - if (m_signalingState == SignalingStateClosed) { + if (m_signalingState == SignalingState::Closed) { ec = INVALID_STATE_ERR; return nullptr; } @@ -684,141 +371,10 @@ PassRefPtr RTCPeerConnection::createDataChannel(String, const Di void RTCPeerConnection::close() { - if (m_signalingState == SignalingStateClosed) - return; - - m_mediaEndpoint->stop(); - - m_signalingState = SignalingStateClosed; -} - -void RTCPeerConnection::gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) -{ - printf("-> gotSendSSRC()\n"); - - m_localConfiguration->mediaDescriptions()[mdescIndex]->addSsrc(ssrc); - m_localConfiguration->mediaDescriptions()[mdescIndex]->setCname(cname); - - maybeResolveSetLocalDescription(); -} - -void RTCPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& certificate) -{ - Vector certificateRows; - Vector der; - - der.reserveCapacity(certificate.length() * 3/4 + 2); - certificate.split("\n", certificateRows); - - for (auto& row : certificateRows) { - if (row.startsWith("-----")) - continue; - - Vector decodedRow; - if (!base64Decode(row, decodedRow, Base64FailOnInvalidCharacterOrExcessPadding)) { - ASSERT_NOT_REACHED(); - return; - } - der.appendVector(decodedRow); - } - - std::unique_ptr digest = CryptoDigest::create(CryptoAlgorithmIdentifier::SHA_256); - if (!digest) { - ASSERT_NOT_REACHED(); + if (m_signalingState == SignalingState::Closed) return; - } - - digest->addBytes(der.data(), der.size()); - Vector fingerprintVector = digest->computeHash(); - - StringBuilder fingerprint; - for (unsigned i = 0; i < fingerprintVector.size(); ++i) - fingerprint.append(String::format(i ? ":%02X" : "%02X", fingerprintVector[i])); - - m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprintHashFunction("sha-256"); - m_localConfiguration->mediaDescriptions()[mdescIndex]->setDtlsFingerprint(fingerprint.toString()); - - if (maybeResolveSetLocalDescription() == SetLocalDescriptionResolvedSuccessfully) - maybeDispatchGatheringDone(); -} - -void RTCPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate, const String& ufrag, const String& password) -{ - printf("-> gotIceCandidate()\n"); - ASSERT(scriptExecutionContext()->isContextThread()); - - PeerMediaDescription& mdesc = *m_localConfiguration->mediaDescriptions()[mdescIndex]; - if (mdesc.iceUfrag().isEmpty()) { - mdesc.setIceUfrag(ufrag); - mdesc.setIcePassword(password); - } - - mdesc.addIceCandidate(candidate.copyRef()); - - if (!candidate->address().contains(':')) { // not IPv6 - if (candidate->componentId() == 1) { // RTP - if (mdesc.address().isEmpty() || mdesc.address() == "0.0.0.0") { - mdesc.setAddress(candidate->address()); - mdesc.setPort(candidate->port()); - } - } else { // RTCP - if (mdesc.rtcpAddress().isEmpty() || !mdesc.rtcpPort()) { - mdesc.setRtcpAddress(candidate->address()); - mdesc.setRtcpPort(candidate->port()); - } - } - } - - ResolveSetLocalDescriptionResult result = maybeResolveSetLocalDescription(); - if (result == SetLocalDescriptionResolvedSuccessfully) - maybeDispatchGatheringDone(); - else if (result == SetLocalDescriptionAlreadyResolved) { - String candidateString = MediaEndpointConfigurationConversions::iceCandidateToJSON(candidate.get()); - String sdpFragment = iceCandidateToSDP(candidateString); - RefPtr iceCandidate = RTCIceCandidate::create(sdpFragment, "", mdescIndex); - scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, WTF::move(iceCandidate))); - } -} - -void RTCPeerConnection::doneGatheringCandidates(unsigned mdescIndex) -{ - printf("-> doneGatheringCandidates()\n"); - - ASSERT(scriptExecutionContext()->isContextThread()); - - m_localConfiguration->mediaDescriptions()[mdescIndex]->setIceCandidateGatheringDone(true); - // Test: No trickle - maybeResolveSetLocalDescription(); - maybeDispatchGatheringDone(); -} - -void RTCPeerConnection::gotRemoteSource(unsigned mdescIndex, RefPtr&& source) -{ - if (m_signalingState == SignalingStateClosed) - return; - - if (mdescIndex >= m_remoteConfiguration->mediaDescriptions().size()) { - printf("Warning: No remote configuration for incoming source.\n"); - return; - } - - PeerMediaDescription& mediaDescription = *m_remoteConfiguration->mediaDescriptions()[mdescIndex]; - String trackId = mediaDescription.mediaStreamTrackId(); - - if (trackId.isEmpty()) { - // Non WebRTC media description (e.g. legacy) - trackId = createCanonicalUUIDString(); - } - - // FIXME: track should be set to muted (not supported yet) - // FIXME: MediaStream handling not implemented - - RefPtr trackPrivate = MediaStreamTrackPrivate::create(WTF::move(source), trackId); - RefPtr track = MediaStreamTrack::create(*scriptExecutionContext(), *trackPrivate); - RefPtr receiver = RTCRtpReceiver::create(track.copyRef()); - - scheduleDispatchEvent(RTCTrackEvent::create(eventNames().trackEvent, false, false, WTF::move(receiver), WTF::move(track))); + m_signalingState = SignalingState::Closed; } void RTCPeerConnection::stop() @@ -827,36 +383,36 @@ void RTCPeerConnection::stop() return; m_stopped = true; - m_iceConnectionState = IceConnectionStateClosed; - m_signalingState = SignalingStateClosed; + m_iceConnectionState = IceConnectionState::Closed; + m_signalingState = SignalingState::Closed; } -RTCPeerConnection::SignalingState RTCPeerConnection::targetSignalingState(SetterType setter, DescriptionType description) const +SignalingState RTCPeerConnection::targetSignalingState(SetterType setter, DescriptionType description) const { // "map" describing the valid state transitions switch (m_signalingState) { - case SignalingStateStable: + case SignalingState::Stable: if (setter == SetterTypeLocal && description == DescriptionTypeOffer) - return SignalingStateHaveLocalOffer; + return SignalingState::HaveLocalOffer; if (setter == SetterTypeRemote && description == DescriptionTypeOffer) - return SignalingStateHaveRemoteOffer; + return SignalingState::HaveRemoteOffer; break; - case SignalingStateHaveLocalOffer: + case SignalingState::HaveLocalOffer: if (setter == SetterTypeLocal && description == DescriptionTypeOffer) - return SignalingStateHaveLocalOffer; + return SignalingState::HaveLocalOffer; if (setter == SetterTypeRemote && description == DescriptionTypeAnswer) - return SignalingStateStable; + return SignalingState::Stable; break; - case SignalingStateHaveRemoteOffer: + case SignalingState::HaveRemoteOffer: if (setter == SetterTypeLocal && description == DescriptionTypeAnswer) - return SignalingStateStable; + return SignalingState::Stable; if (setter == SetterTypeRemote && description == DescriptionTypeOffer) - return SignalingStateHaveRemoteOffer; + return SignalingState::HaveRemoteOffer; break; default: break; }; - return SignalingStateInvalid; + return SignalingState::Invalid; } RTCPeerConnection::DescriptionType RTCPeerConnection::parseDescriptionType(const String& typeName) const @@ -870,117 +426,6 @@ RTCPeerConnection::DescriptionType RTCPeerConnection::parseDescriptionType(const return DescriptionTypeAnswer; } -bool RTCPeerConnection::isLocalConfigurationComplete() const -{ - for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { - if (mdesc->dtlsFingerprint().isEmpty() || mdesc->iceUfrag().isEmpty()) - return false; - // Test: No trickle - if (!mdesc->iceCandidateGatheringDone()) - return false; - if (mdesc->type() == "audio" || mdesc->type() == "video") { - if (!mdesc->ssrcs().size() || mdesc->cname().isEmpty()) - return false; - } - } - - return true; -} - -RTCPeerConnection::ResolveSetLocalDescriptionResult RTCPeerConnection::maybeResolveSetLocalDescription() -{ - if (!m_resolveSetLocalDescription) { - ASSERT(isLocalConfigurationComplete()); - return SetLocalDescriptionAlreadyResolved; - } - - if (isLocalConfigurationComplete()) { - m_resolveSetLocalDescription(); - m_resolveSetLocalDescription = nullptr; - return SetLocalDescriptionResolvedSuccessfully; - } - - return LocalConfigurationIncomplete; -} - -void RTCPeerConnection::maybeDispatchGatheringDone() -{ - if (!isLocalConfigurationComplete()) - return; - - for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { - if (!mdesc->iceCandidateGatheringDone()) - return; - } - - scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, nullptr)); -} - -String RTCPeerConnection::toSDP(const String& json) const -{ - return sdpConversion("toSDP", json); -} - -String RTCPeerConnection::fromSDP(const String& sdp) const -{ - return sdpConversion("fromSDP", sdp); -} - -String RTCPeerConnection::iceCandidateToSDP(const String& json) const -{ - return sdpConversion("iceCandidateToSDP", json); -} - -String RTCPeerConnection::iceCandidateFromSDP(const String& sdpFragment) const -{ - return sdpConversion("iceCandidateFromSDP", sdpFragment); -} - -String RTCPeerConnection::sdpConversion(const String& functionName, const String& argument) const -{ - Document* document = downcast(scriptExecutionContext()); - - if (!m_isolatedWorld) - m_isolatedWorld = DOMWrapperWorld::create(JSDOMWindow::commonVM()); - - ScriptController& scriptController = document->frame()->script(); - JSDOMGlobalObject* globalObject = JSC::jsCast(scriptController.globalObject(*m_isolatedWorld)); - JSC::ExecState* exec = globalObject->globalExec(); - JSC::JSLockHolder lock(exec); - - JSC::JSValue probeFunctionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, "toSDP")); - if (!probeFunctionValue.isFunction()) { - URL scriptURL; - scriptController.evaluateInWorld(ScriptSourceCode(SDPScriptResource::getString(), scriptURL), *m_isolatedWorld); - if (exec->hadException()) { - exec->clearException(); - return emptyString(); - } - } - - JSC::JSValue functionValue = globalObject->get(exec, JSC::Identifier::fromString(exec, functionName)); - if (!functionValue.isFunction()) - return emptyString(); - - JSC::JSObject* function = functionValue.toObject(exec); - JSC::CallData callData; - JSC::CallType callType = function->methodTable()->getCallData(function, callData); - if (callType == JSC::CallTypeNone) - return emptyString(); - - JSC::MarkedArgumentBuffer argList; - argList.append(JSC::jsString(exec, argument)); - - JSC::JSValue result = JSC::call(exec, function, callType, callData, globalObject, argList); - if (exec->hadException()) { - printf("sdpConversion: js function (%s) threw\n", functionName.ascii().data()); - exec->clearException(); - return emptyString(); - } - - return result.isString() ? result.getString(exec) : emptyString(); -} - const char* RTCPeerConnection::activeDOMObjectName() const { return "RTCPeerConnection"; @@ -994,7 +439,7 @@ bool RTCPeerConnection::canSuspendForPageCache() const void RTCPeerConnection::changeSignalingState(SignalingState signalingState) { - if (m_signalingState != SignalingStateClosed && m_signalingState != signalingState) { + if (m_signalingState != SignalingState::Closed && m_signalingState != signalingState) { m_signalingState = signalingState; scheduleDispatchEvent(Event::create(eventNames().signalingstatechangeEvent, false, false)); } @@ -1007,7 +452,7 @@ void RTCPeerConnection::changeIceGatheringState(IceGatheringState iceGatheringSt void RTCPeerConnection::changeIceConnectionState(IceConnectionState iceConnectionState) { - if (m_iceConnectionState != IceConnectionStateClosed && m_iceConnectionState != iceConnectionState) { + if (m_iceConnectionState != IceConnectionState::Closed && m_iceConnectionState != iceConnectionState) { m_iceConnectionState = iceConnectionState; scheduleDispatchEvent(Event::create(eventNames().iceconnectionstatechangeEvent, false, false)); } diff --git a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h index 7b7127ea3952f..0129ad57560eb 100644 --- a/Source/WebCore/Modules/mediastream/RTCPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/RTCPeerConnection.h @@ -38,7 +38,7 @@ #include "ActiveDOMObject.h" #include "Dictionary.h" #include "EventTarget.h" -#include "MediaEndpoint.h" +#include "PeerConnectionBackend.h" #include "ScriptWrappable.h" #include "Timer.h" #include @@ -46,9 +46,9 @@ namespace WebCore { -class MediaEndpointConfiguration; class MediaStream; class MediaStreamTrack; +class PeerConnectionBackend; class RTCConfiguration; class RTCDataChannel; class RTCIceCandidate; @@ -58,7 +58,7 @@ class RTCRtpSender; class RTCSessionDescription; class RTCStatsCallback; -class RTCPeerConnection final : public RefCounted, public ScriptWrappable, public MediaEndpointClient, public EventTargetWithInlineData, public ActiveDOMObject { +class RTCPeerConnection final : public RefCounted, public ScriptWrappable, public PeerConnectionBackendClient, public EventTargetWithInlineData, public ActiveDOMObject { public: static RefPtr create(ScriptExecutionContext&, const Dictionary& rtcConfiguration, ExceptionCode&); ~RTCPeerConnection(); @@ -98,13 +98,6 @@ class RTCPeerConnection final : public RefCounted, public Scr void close(); - // MediaEndpointClient - virtual void gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) override; - virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; - virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) override; - virtual void doneGatheringCandidates(unsigned mdescIndex) override; - virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; - // EventTarget virtual EventTargetInterface eventTargetInterface() const override { return RTCPeerConnectionEventTargetInterfaceType; } virtual ScriptExecutionContext* scriptExecutionContext() const override { return ActiveDOMObject::scriptExecutionContext(); } @@ -124,35 +117,9 @@ class RTCPeerConnection final : public RefCounted, public Scr DescriptionTypeAnswer = 3 }; - enum SignalingState { - SignalingStateStable = 1, - SignalingStateHaveLocalOffer = 2, - SignalingStateHaveRemoteOffer = 3, - SignalingStateHaveLocalPrAnswer = 4, - SignalingStateHaveRemotePrAnswer = 5, - SignalingStateClosed = 6, - SignalingStateInvalid = 7 - }; - - enum IceConnectionState { - IceConnectionStateNew = 1, - IceConnectionStateChecking = 2, - IceConnectionStateConnected = 3, - IceConnectionStateCompleted = 4, - IceConnectionStateFailed = 5, - IceConnectionStateDisconnected = 6, - IceConnectionStateClosed = 7 - }; - - enum IceGatheringState { - IceGatheringStateNew = 1, - IceGatheringStateGathering = 2, - IceGatheringStateComplete = 3 - }; - RTCPeerConnection(ScriptExecutionContext&, PassRefPtr, ExceptionCode&); - SignalingState targetSignalingState(SetterType, DescriptionType) const; + PeerConnectionStates::SignalingState targetSignalingState(SetterType, DescriptionType) const; DescriptionType parseDescriptionType(const String& typeName) const; enum ResolveSetLocalDescriptionResult { @@ -161,16 +128,6 @@ class RTCPeerConnection final : public RefCounted, public Scr SetLocalDescriptionAlreadyResolved }; - bool isLocalConfigurationComplete() const; - ResolveSetLocalDescriptionResult maybeResolveSetLocalDescription(); - void maybeDispatchGatheringDone(); - - String toSDP(const String& json) const; - String fromSDP(const String& sdp) const; - String iceCandidateToSDP(const String& json) const; - String iceCandidateFromSDP(const String& sdpFragment) const; - String sdpConversion(const String& functionName, const String& argument) const; - void scheduleDispatchEvent(PassRefPtr); void scheduledEventTimerFired(); @@ -183,30 +140,24 @@ class RTCPeerConnection final : public RefCounted, public Scr const char* activeDOMObjectName() const override; bool canSuspendForPageCache() const override; - void changeSignalingState(SignalingState); - void changeIceGatheringState(IceGatheringState); - void changeIceConnectionState(IceConnectionState); + void changeSignalingState(PeerConnectionStates::SignalingState); + void changeIceGatheringState(PeerConnectionStates::IceGatheringState); + void changeIceConnectionState(PeerConnectionStates::IceConnectionState); - SignalingState m_signalingState; - IceGatheringState m_iceGatheringState; - IceConnectionState m_iceConnectionState; + // PeerConnectionBackendClient + ScriptExecutionContext* context() const override { return scriptExecutionContext(); }; + PeerConnectionStates::SignalingState internalSignalingState() const { return m_signalingState; } + + PeerConnectionStates::SignalingState m_signalingState; + PeerConnectionStates::IceGatheringState m_iceGatheringState; + PeerConnectionStates::IceConnectionState m_iceConnectionState; HashMap> m_senderSet; HashMap> m_receiverSet; - RefPtr m_localConfiguration; - RefPtr m_remoteConfiguration; - - String m_localConfigurationType; - String m_remoteConfigurationType; - - std::function m_resolveSetLocalDescription; - Vector> m_dataChannels; - std::unique_ptr m_mediaEndpoint; - - mutable RefPtr m_isolatedWorld; + std::unique_ptr m_backend; Timer m_scheduledEventTimer; Vector> m_scheduledEvents; From 6561c5f9606de43fc7ce5ff23e60d7a9986e673f Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 21 Aug 2015 10:36:02 +0200 Subject: [PATCH 147/155] jh-build: Bump openwebrtc version (with some deps) --- Tools/gtk/jhbuild.modules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules index 7cff6c05e73d9..678dcf12b15b0 100644 --- a/Tools/gtk/jhbuild.modules +++ b/Tools/gtk/jhbuild.modules @@ -392,14 +392,14 @@ - +
- + - + From 046088d16a853437cb542ecf9d7a2373240f821a Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 21 Aug 2015 11:25:19 +0200 Subject: [PATCH 148/155] MediaEndpointPeerConnection: Generate cname and SSRC in createOffer/Answer() --- .../MediaEndpointPeerConnection.cpp | 32 +++++++++++-------- .../mediastream/MediaEndpointPeerConnection.h | 3 +- .../platform/mediastream/MediaEndpoint.h | 1 - .../mediastream/PeerMediaDescription.h | 1 + .../openwebrtc/MediaEndpointOwr.cpp | 23 +++---------- .../mediastream/openwebrtc/MediaEndpointOwr.h | 1 - 6 files changed, 25 insertions(+), 36 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp index ad14fdc3bd4d0..86afa8d04040c 100644 --- a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp @@ -71,6 +71,14 @@ static std::unique_ptr createMediaEndpointPeerConnection( CreatePeerConnectionBackend PeerConnectionBackend::create = createMediaEndpointPeerConnection; +static String generateCname() +{ + static const size_t size = ceil(16 * 3 / 4); + unsigned char randomValues[size]; + cryptographicallyRandomValues(randomValues, size); + return base64Encode(randomValues, size); +} + static RefPtr createMediaEndpointInit(RTCConfiguration& rtcConfig) { Vector> iceServers; @@ -82,6 +90,7 @@ static RefPtr createMediaEndpointInit(RTCConfiguration& rtcCo MediaEndpointPeerConnection::MediaEndpointPeerConnection(PeerConnectionBackendClient* client) : m_client(client) + , m_cname(generateCname()) { m_mediaEndpoint = MediaEndpoint::create(this); ASSERT(m_mediaEndpoint); @@ -173,6 +182,7 @@ static void updateMediaDescriptionsWithSenders(const VectorsetMediaStreamId(emptyString()); mdesc->setMediaStreamTrackId(emptyString()); + mdesc->clearSsrcs(); } } @@ -184,8 +194,10 @@ static void updateMediaDescriptionsWithSenders(const Vector sender = takeFirstSenderOfType(senders, mdesc->type()); if (sender) { + // FIXME: what else needs to be updated to reuse a media description? mdesc->setMediaStreamId(sender->mediaStreamId()); mdesc->setMediaStreamTrackId(sender->track()->id()); + mdesc->addSsrc(cryptographicallyRandomNumber()); mdesc->setMode("sendrecv"); } else mdesc->setMode("recvonly"); @@ -212,6 +224,8 @@ void MediaEndpointPeerConnection::createOffer(const RefPtr& opt mediaDescription->setPayloads(createDefaultPayloads(track->kind())); mediaDescription->setRtcpMux(true); mediaDescription->setDtlsSetup("actpass"); + mediaDescription->setCname(m_cname); + mediaDescription->addSsrc(cryptographicallyRandomNumber()); configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); } @@ -250,6 +264,7 @@ void MediaEndpointPeerConnection::createAnswer(const RefPtr&, localMediaDescription = PeerMediaDescription::create(); localMediaDescription->setType(remoteMediaDescription->type()); localMediaDescription->setDtlsSetup(remoteMediaDescription->dtlsSetup() == "active" ? "passive" : "active"); + localMediaDescription->setCname(m_cname); configurationSnapshot->addMediaDescription(localMediaDescription.copyRef()); } @@ -258,6 +273,9 @@ void MediaEndpointPeerConnection::createAnswer(const RefPtr&, localMediaDescription->setRtcpMux(remoteMediaDescription->rtcpMux()); + if (!localMediaDescription->ssrcs().size()) + localMediaDescription->addSsrc(cryptographicallyRandomNumber()); + if (localMediaDescription->dtlsSetup() == "actpass") localMediaDescription->setDtlsSetup("passive"); } @@ -426,10 +444,6 @@ bool MediaEndpointPeerConnection::isLocalConfigurationComplete() const // Test: No trickle if (!mdesc->iceCandidateGatheringDone()) return false; - if (mdesc->type() == "audio" || mdesc->type() == "video") { - if (!mdesc->ssrcs().size() || mdesc->cname().isEmpty()) - return false; - } } return true; @@ -464,16 +478,6 @@ void MediaEndpointPeerConnection::maybeDispatchGatheringDone() m_client->scheduleDispatchEvent(RTCIceCandidateEvent::create(false, false, nullptr)); } -void MediaEndpointPeerConnection::gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) -{ - printf("-> gotSendSSRC()\n"); - - m_localConfiguration->mediaDescriptions()[mdescIndex]->addSsrc(ssrc); - m_localConfiguration->mediaDescriptions()[mdescIndex]->setCname(cname); - - maybeResolveSetLocalDescription(); -} - void MediaEndpointPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const String& certificate) { Vector certificateRows; diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h index c6ceae1d9d262..2f3ab1725bc92 100644 --- a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h @@ -74,7 +74,6 @@ class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEn void maybeDispatchGatheringDone(); // MediaEndpointClient - virtual void gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) override; virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) override; virtual void doneGatheringCandidates(unsigned mdescIndex) override; @@ -91,6 +90,8 @@ class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEn mutable RefPtr m_isolatedWorld; + String m_cname; + RefPtr m_localConfiguration; RefPtr m_remoteConfiguration; diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index 773177e70bf84..3609343c19f39 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -46,7 +46,6 @@ class RealtimeMediaSource; class MediaEndpointClient { public: - virtual void gotSendSSRC(unsigned mdescIndex, unsigned ssrc, const String& cname) = 0; virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) = 0; virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) = 0; virtual void doneGatheringCandidates(unsigned mdescIndex) = 0; diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h index 45ccad15105d4..27f5700d785e1 100644 --- a/Source/WebCore/platform/mediastream/PeerMediaDescription.h +++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h @@ -95,6 +95,7 @@ class PeerMediaDescription : public RefCounted { const Vector& ssrcs() const { return m_ssrcs; } void addSsrc(unsigned ssrc) { m_ssrcs.append(ssrc); } + void clearSsrcs() { m_ssrcs.clear(); } const String& iceUfrag() const { return m_iceUfrag; } void setIceUfrag(const String& iceUfrag) { m_iceUfrag = iceUfrag; } diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index f499f704b9026..ece49110b8ced 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -46,7 +46,6 @@ namespace WebCore { static void gotCandidate(OwrSession*, OwrCandidate*, MediaEndpointOwr*); static void candidateGatheringDone(OwrSession*, MediaEndpointOwr*); static void gotDtlsCertificate(OwrSession*, GParamSpec*, MediaEndpointOwr*); -static void gotSendSsrc(OwrMediaSession*, GParamSpec*, MediaEndpointOwr*); static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*); static const Vector candidateTypes = { "host", "srflx", "prflx", "relay" }; @@ -211,11 +210,6 @@ void MediaEndpointOwr::dispatchDtlsCertificate(unsigned sessionIndex, const Stri m_client->gotDtlsCertificate(sessionIndex, certificate); } -void MediaEndpointOwr::dispatchSendSSRC(unsigned sessionIndex, unsigned ssrc, const String& cname) -{ - m_client->gotSendSSRC(sessionIndex, ssrc, cname); -} - void MediaEndpointOwr::dispatchRemoteSource(unsigned sessionIndex, RefPtr&& source) { m_client->gotRemoteSource(sessionIndex, WTF::move(source)); @@ -233,9 +227,11 @@ void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMe prepareSession(OWR_SESSION(mediaSession), mediaDescription); bool useRtpMux = !isInitiator && mediaDescription->rtcpMux(); - g_object_set(mediaSession, "rtcp-mux", useRtpMux, nullptr); + g_object_set(mediaSession, "rtcp-mux", useRtpMux, + "cname", mediaDescription->cname().ascii().data(), + "send-ssrc", mediaDescription->ssrcs()[0], + nullptr); - g_signal_connect(mediaSession, "notify::send-ssrc", G_CALLBACK(gotSendSsrc), this); g_signal_connect(mediaSession, "on-incoming-source", G_CALLBACK(gotIncomingSource), this); for (auto& payload : mediaDescription->payloads()) { @@ -391,17 +387,6 @@ static void gotDtlsCertificate(OwrSession* session, GParamSpec*, MediaEndpointOw mediaEndpoint->dispatchDtlsCertificate(mediaEndpoint->sessionIndex(session), certificate); } -static void gotSendSsrc(OwrMediaSession* mediaSession, GParamSpec*, MediaEndpointOwr* mediaEndpoint) -{ - guint ssrc; - gchar* cname; - g_object_get(mediaSession, "send-ssrc", &ssrc, "cname", &cname, nullptr); - - mediaEndpoint->dispatchSendSSRC(mediaEndpoint->sessionIndex(OWR_SESSION(mediaSession)), ssrc, String(cname)); - - g_free(cname); -} - static void gotIncomingSource(OwrMediaSession* mediaSession, OwrMediaSource* source, MediaEndpointOwr* mediaEndpoint) { String name; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index e8fc786e50f7c..760935b06748e 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -61,7 +61,6 @@ class MediaEndpointOwr : public MediaEndpoint { void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&, const String& ufrag, const String& password); void dispatchGatheringDone(unsigned sessionIndex); void dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate); - void dispatchSendSSRC(unsigned sessionIndex, unsigned ssrc, const String& cname); void dispatchRemoteSource(unsigned sessionIndex, RefPtr&&); private: From 1ec4a3ac80c0f257055fdc63d56263c258ac73d3 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Mon, 24 Aug 2015 12:56:37 +0200 Subject: [PATCH 149/155] MediaEndpointPeerConnection: Generate ICE ufrag and password in createOffer/Answer() --- .../MediaEndpointPeerConnection.cpp | 23 +++++++++++-------- .../mediastream/MediaEndpointPeerConnection.h | 4 +++- .../platform/mediastream/MediaEndpoint.h | 2 +- .../openwebrtc/MediaEndpointOwr.cpp | 21 +++++++++-------- .../mediastream/openwebrtc/MediaEndpointOwr.h | 2 +- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp index 86afa8d04040c..96e4c50314a8b 100644 --- a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp @@ -71,9 +71,9 @@ static std::unique_ptr createMediaEndpointPeerConnection( CreatePeerConnectionBackend PeerConnectionBackend::create = createMediaEndpointPeerConnection; -static String generateCname() +static String randomString(size_t length) { - static const size_t size = ceil(16 * 3 / 4); + const size_t size = ceil(length * 3 / 4); unsigned char randomValues[size]; cryptographicallyRandomValues(randomValues, size); return base64Encode(randomValues, size); @@ -90,7 +90,9 @@ static RefPtr createMediaEndpointInit(RTCConfiguration& rtcCo MediaEndpointPeerConnection::MediaEndpointPeerConnection(PeerConnectionBackendClient* client) : m_client(client) - , m_cname(generateCname()) + , m_cname(randomString(16)) + , m_iceUfrag(randomString(4)) + , m_icePassword(randomString(22)) { m_mediaEndpoint = MediaEndpoint::create(this); ASSERT(m_mediaEndpoint); @@ -226,6 +228,8 @@ void MediaEndpointPeerConnection::createOffer(const RefPtr& opt mediaDescription->setDtlsSetup("actpass"); mediaDescription->setCname(m_cname); mediaDescription->addSsrc(cryptographicallyRandomNumber()); + mediaDescription->setIceUfrag(m_iceUfrag); + mediaDescription->setIcePassword(m_icePassword); configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); } @@ -240,6 +244,8 @@ void MediaEndpointPeerConnection::createOffer(const RefPtr& opt mediaDescription->setPayloads(createDefaultPayloads(type)); mediaDescription->setRtcpMux(true); mediaDescription->setDtlsSetup("actpass"); + mediaDescription->setIceUfrag(m_iceUfrag); + mediaDescription->setIcePassword(m_icePassword); configurationSnapshot->addMediaDescription(WTF::move(mediaDescription)); } @@ -265,6 +271,8 @@ void MediaEndpointPeerConnection::createAnswer(const RefPtr&, localMediaDescription->setType(remoteMediaDescription->type()); localMediaDescription->setDtlsSetup(remoteMediaDescription->dtlsSetup() == "active" ? "passive" : "active"); localMediaDescription->setCname(m_cname); + localMediaDescription->setIceUfrag(m_iceUfrag); + localMediaDescription->setIcePassword(m_icePassword); configurationSnapshot->addMediaDescription(localMediaDescription.copyRef()); } @@ -439,7 +447,7 @@ void MediaEndpointPeerConnection::stop() bool MediaEndpointPeerConnection::isLocalConfigurationComplete() const { for (auto& mdesc : m_localConfiguration->mediaDescriptions()) { - if (mdesc->dtlsFingerprint().isEmpty() || mdesc->iceUfrag().isEmpty()) + if (mdesc->dtlsFingerprint().isEmpty()) return false; // Test: No trickle if (!mdesc->iceCandidateGatheringDone()) @@ -518,18 +526,13 @@ void MediaEndpointPeerConnection::gotDtlsCertificate(unsigned mdescIndex, const maybeDispatchGatheringDone(); } -void MediaEndpointPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate, const String& ufrag, const String& password) +void MediaEndpointPeerConnection::gotIceCandidate(unsigned mdescIndex, RefPtr&& candidate) { printf("-> gotIceCandidate()\n"); ASSERT(scriptExecutionContext()->isContextThread()); PeerMediaDescription& mdesc = *m_localConfiguration->mediaDescriptions()[mdescIndex]; - if (mdesc.iceUfrag().isEmpty()) { - mdesc.setIceUfrag(ufrag); - mdesc.setIcePassword(password); - } - mdesc.addIceCandidate(candidate.copyRef()); if (!candidate->address().contains(':')) { // not IPv6 diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h index 2f3ab1725bc92..cacfe996b582a 100644 --- a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h @@ -75,7 +75,7 @@ class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEn // MediaEndpointClient virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) override; - virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) override; + virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) override; virtual void doneGatheringCandidates(unsigned mdescIndex) override; virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) override; @@ -91,6 +91,8 @@ class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEn mutable RefPtr m_isolatedWorld; String m_cname; + String m_iceUfrag; + String m_icePassword; RefPtr m_localConfiguration; RefPtr m_remoteConfiguration; diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h index 3609343c19f39..377625c3d6322 100644 --- a/Source/WebCore/platform/mediastream/MediaEndpoint.h +++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h @@ -47,7 +47,7 @@ class RealtimeMediaSource; class MediaEndpointClient { public: virtual void gotDtlsCertificate(unsigned mdescIndex, const String& certificate) = 0; - virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&, const String& ufrag, const String& password) = 0; + virtual void gotIceCandidate(unsigned mdescIndex, RefPtr&&) = 0; virtual void doneGatheringCandidates(unsigned mdescIndex) = 0; virtual void gotRemoteSource(unsigned mdescIndex, RefPtr&&) = 0; diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp index ece49110b8ced..4f041d4989eeb 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp @@ -195,9 +195,9 @@ unsigned MediaEndpointOwr::sessionIndex(OwrSession* session) const return index; } -void MediaEndpointOwr::dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&& iceCandidate, const String& ufrag, const String& password) +void MediaEndpointOwr::dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&& iceCandidate) { - m_client->gotIceCandidate(sessionIndex, WTF::move(iceCandidate), ufrag, password); + m_client->gotIceCandidate(sessionIndex, WTF::move(iceCandidate)); } void MediaEndpointOwr::dispatchGatheringDone(unsigned sessionIndex) @@ -215,8 +215,11 @@ void MediaEndpointOwr::dispatchRemoteSource(unsigned sessionIndex, RefPtrgotRemoteSource(sessionIndex, WTF::move(source)); } -void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription*) +void MediaEndpointOwr::prepareSession(OwrSession* session, PeerMediaDescription* mediaDescription) { + g_object_set_data_full(G_OBJECT(session), "ice-ufrag", g_strdup(mediaDescription->iceUfrag().ascii().data()), g_free); + g_object_set_data_full(G_OBJECT(session), "ice-password", g_strdup(mediaDescription->icePassword().ascii().data()), g_free); + g_signal_connect(session, "on-new-candidate", G_CALLBACK(gotCandidate), this); g_signal_connect(session, "on-candidate-gathering-done", G_CALLBACK(candidateGatheringDone), this); g_signal_connect(session, "notify::dtls-certificate", G_CALLBACK(gotDtlsCertificate), this); @@ -323,8 +326,6 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp guint port; gchar* relatedAddress; guint relatedPort; - gchar* ufrag; - gchar* password; g_object_get(candidate, "type", &candidateType, "foundation", &foundation, @@ -335,8 +336,6 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp "port", &port, "base-address", &relatedAddress, "base-port", &relatedPort, - "ufrag", &ufrag, - "password", &password, nullptr); ASSERT(candidateType >= 0 && candidateType < candidateTypes.size()); @@ -362,13 +361,15 @@ static void gotCandidate(OwrSession* session, OwrCandidate* candidate, MediaEndp iceCandidate->setRelatedPort(relatedPort ? relatedPort : 9); } - mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->sessionIndex(session), WTF::move(iceCandidate), String(ufrag), String(password)); + g_object_set(G_OBJECT(candidate), "ufrag", g_object_get_data(G_OBJECT(session), "ice-ufrag"), + "password", g_object_get_data(G_OBJECT(session), "ice-password"), + nullptr); + + mediaEndpoint->dispatchNewIceCandidate(mediaEndpoint->sessionIndex(session), WTF::move(iceCandidate)); g_free(foundation); g_free(address); g_free(relatedAddress); - g_free(ufrag); - g_free(password); } static void candidateGatheringDone(OwrSession* session, MediaEndpointOwr* mediaEndpoint) diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h index 760935b06748e..de226431faa73 100644 --- a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h +++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h @@ -58,7 +58,7 @@ class MediaEndpointOwr : public MediaEndpoint { unsigned sessionIndex(OwrSession*) const; - void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&, const String& ufrag, const String& password); + void dispatchNewIceCandidate(unsigned sessionIndex, RefPtr&&); void dispatchGatheringDone(unsigned sessionIndex); void dispatchDtlsCertificate(unsigned sessionIndex, const String& certificate); void dispatchRemoteSource(unsigned sessionIndex, RefPtr&&); From e0493ed99e2bca8113eac8cbad3a88e02a663295 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Thu, 27 Aug 2015 15:06:29 +0200 Subject: [PATCH 150/155] fix \merge fault --- Source/WebCore/CMakeLists.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 317b3f73a0762..42931c922285d 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -247,7 +247,6 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/MediaSourceStates.idl Modules/mediastream/MediaStream.idl Modules/mediastream/MediaStreamCapabilities.idl - Modules/mediastream/MediaStreamEvent.idl Modules/mediastream/MediaStreamTrack.idl Modules/mediastream/MediaStreamTrackEvent.idl Modules/mediastream/MediaStreamTrackSourcesCallback.idl @@ -274,6 +273,7 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/RTCStatsCallback.idl Modules/mediastream/RTCStatsReport.idl Modules/mediastream/RTCStatsResponse.idl + Modules/mediastream/RTCTrackEvent.idl Modules/mediastream/SourceInfo.idl Modules/navigatorcontentutils/NavigatorContentUtils.idl @@ -907,7 +907,6 @@ set(WebCore_SOURCES Modules/mediastream/MediaSourceStates.cpp Modules/mediastream/MediaStream.cpp Modules/mediastream/MediaStreamCapabilities.cpp - Modules/mediastream/MediaStreamEvent.cpp Modules/mediastream/MediaStreamRegistry.cpp Modules/mediastream/MediaStreamTrack.cpp Modules/mediastream/MediaStreamTrackEvent.cpp @@ -930,6 +929,7 @@ set(WebCore_SOURCES Modules/mediastream/RTCStatsReport.cpp Modules/mediastream/RTCStatsRequestImpl.cpp Modules/mediastream/RTCStatsResponse.cpp + Modules/mediastream/RTCTrackEvent.cpp Modules/mediastream/RTCVoidRequestImpl.cpp Modules/mediastream/SourceInfo.cpp Modules/mediastream/UserMediaController.cpp @@ -1007,8 +1007,6 @@ set(WebCore_SOURCES Modules/webdatabase/DOMWindowWebDatabase.cpp Modules/webdatabase/Database.cpp Modules/webdatabase/DatabaseAuthorizer.cpp - Modules/webdatabase/DatabaseBackend.cpp - Modules/webdatabase/DatabaseBackendBase.cpp Modules/webdatabase/DatabaseContext.cpp Modules/webdatabase/DatabaseManager.cpp Modules/webdatabase/DatabaseServer.cpp @@ -1020,7 +1018,6 @@ set(WebCore_SOURCES Modules/webdatabase/SQLResultSet.cpp Modules/webdatabase/SQLResultSetRowList.cpp Modules/webdatabase/SQLStatement.cpp - Modules/webdatabase/SQLStatementBackend.cpp Modules/webdatabase/SQLTransaction.cpp Modules/webdatabase/SQLTransactionBackend.cpp Modules/webdatabase/SQLTransactionClient.cpp From 2343d54a9cc874c4c955203618c0729c1f96d2b3 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Fri, 28 Aug 2015 15:28:50 +0200 Subject: [PATCH 151/155] Updated MediaStream to fix merge. --- Source/WebCore/CMakeLists.txt | 13 ++++++- .../mediastream/RTCSessionDescription.cpp | 29 ++++++++++------ .../mediastream/RTCSessionDescription.h | 9 +++-- Source/WebCore/PlatformWPE.cmake | 2 +- .../UserMediaPermissionRequestManager.cpp | 2 +- .../UserMediaPermissionRequestManagerWPE.cpp | 34 ++++++++++++++----- 6 files changed, 64 insertions(+), 25 deletions(-) diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt index 42931c922285d..4ec071222b319 100644 --- a/Source/WebCore/CMakeLists.txt +++ b/Source/WebCore/CMakeLists.txt @@ -268,6 +268,8 @@ set(WebCore_NON_SVG_IDL_FILES Modules/mediastream/RTCIceServer.idl Modules/mediastream/RTCPeerConnection.idl Modules/mediastream/RTCPeerConnectionErrorCallback.idl + Modules/mediastream/RTCRtpReceiver.idl + Modules/mediastream/RTCRtpSender.idl Modules/mediastream/RTCSessionDescription.idl Modules/mediastream/RTCSessionDescriptionCallback.idl Modules/mediastream/RTCStatsCallback.idl @@ -916,6 +918,7 @@ set(WebCore_SOURCES Modules/mediastream/MediaTrackConstraints.cpp Modules/mediastream/NavigatorMediaDevices.cpp Modules/mediastream/NavigatorUserMediaError.cpp + Modules/mediastream/RTCConfiguration.cpp Modules/mediastream/RTCDTMFSender.cpp Modules/mediastream/RTCDTMFToneChangeEvent.cpp Modules/mediastream/RTCDataChannel.cpp @@ -924,8 +927,11 @@ set(WebCore_SOURCES Modules/mediastream/RTCIceCandidateEvent.cpp Modules/mediastream/RTCOfferAnswerOptions.cpp Modules/mediastream/RTCPeerConnection.cpp + Modules/mediastream/RTCRtpReceiver.cpp + Modules/mediastream/RTCRtpSender.cpp + Modules/mediastream/RTCRtpSenderReceiverBase.cpp Modules/mediastream/RTCSessionDescription.cpp - Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp + # Modules/mediastream/RTCSessionDescriptionRequestImpl.cpp Modules/mediastream/RTCStatsReport.cpp Modules/mediastream/RTCStatsRequestImpl.cpp Modules/mediastream/RTCStatsResponse.cpp @@ -935,6 +941,9 @@ set(WebCore_SOURCES Modules/mediastream/UserMediaController.cpp Modules/mediastream/UserMediaRequest.cpp + + + Modules/navigatorcontentutils/NavigatorContentUtils.cpp Modules/notifications/DOMWindowNotifications.cpp @@ -2243,6 +2252,8 @@ set(WebCore_SOURCES platform/graphics/transforms/TranslateTransformOperation.cpp platform/mediastream/MediaDevicesPrivate.cpp + platform/mediastream/MediaEndpointConfigurationConversions.cpp + platform/mediastream/MediaEndpointInit.cpp platform/mediastream/MediaStreamPrivate.cpp platform/mediastream/MediaStreamTrackPrivate.cpp platform/mediastream/RTCIceCandidateDescriptor.cpp diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp index dbe240671eef8..7f38bf578999a 100644 --- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp +++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.cpp @@ -32,10 +32,12 @@ #include "config.h" #if ENABLE(MEDIA_STREAM) + #include "RTCSessionDescription.h" #include "Dictionary.h" #include "ExceptionCode.h" +#include "RTCSessionDescriptionDescriptor.h" namespace WebCore { @@ -60,22 +62,22 @@ RefPtr RTCSessionDescription::create(const Dictionary& di return nullptr; } - return adoptRef(new RTCSessionDescription(type, sdp)); + return adoptRef(*new RTCSessionDescription(RTCSessionDescriptionDescriptor::create(type, sdp))); } -Ref RTCSessionDescription::create(const RTCSessionDescription* description) +RefPtr RTCSessionDescription::create(RefPtr descriptor) { - return adoptRef(*new RTCSessionDescription(description->type(), description->sdp())); + ASSERT(descriptor); + return adoptRef(*new RTCSessionDescription(descriptor)); } Ref RTCSessionDescription::create(const String& type, const String& sdp) { - return adoptRef(*new RTCSessionDescription(type, sdp)); + return adoptRef(*new RTCSessionDescription(RTCSessionDescriptionDescriptor::create(type, sdp))); } -RTCSessionDescription::RTCSessionDescription(const String& type, const String& sdp) - : m_type(type) - , m_sdp(sdp) +RTCSessionDescription::RTCSessionDescription(RefPtr descriptor) + : m_descriptor(descriptor) { } @@ -85,25 +87,30 @@ RTCSessionDescription::~RTCSessionDescription() const String& RTCSessionDescription::type() const { - return m_type; + return m_descriptor->type(); } void RTCSessionDescription::setType(const String& type, ExceptionCode& ec) { if (verifyType(type)) - m_type = type; + m_descriptor->setType(type); else ec = TYPE_MISMATCH_ERR; } const String& RTCSessionDescription::sdp() const { - return m_sdp; + return m_descriptor->sdp(); } void RTCSessionDescription::setSdp(const String& sdp) { - m_sdp = sdp; + m_descriptor->setSdp(sdp); +} + +RTCSessionDescriptionDescriptor* RTCSessionDescription::descriptor() +{ + return m_descriptor.get(); } } // namespace WebCore diff --git a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h index 60908607fbaa1..31c44062ae8df 100644 --- a/Source/WebCore/Modules/mediastream/RTCSessionDescription.h +++ b/Source/WebCore/Modules/mediastream/RTCSessionDescription.h @@ -42,11 +42,12 @@ namespace WebCore { class Dictionary; +class RTCSessionDescriptionDescriptor; class RTCSessionDescription : public RefCounted, public ScriptWrappable { public: static RefPtr create(const Dictionary&, ExceptionCode&); - static Ref create(const RTCSessionDescription*); + static RefPtr create(RefPtr); static Ref create(const String& type, const String& sdp); virtual ~RTCSessionDescription(); @@ -56,11 +57,13 @@ class RTCSessionDescription : public RefCounted, public S const String& sdp() const; void setSdp(const String&); + RTCSessionDescriptionDescriptor* descriptor(); + private: + explicit RTCSessionDescription(RefPtr); explicit RTCSessionDescription(const String& type, const String& sdp); - String m_type; - String m_sdp; + RefPtr m_descriptor; }; } // namespace WebCore diff --git a/Source/WebCore/PlatformWPE.cmake b/Source/WebCore/PlatformWPE.cmake index ef0d18d321392..6c5437249dd15 100644 --- a/Source/WebCore/PlatformWPE.cmake +++ b/Source/WebCore/PlatformWPE.cmake @@ -372,5 +372,5 @@ if (ENABLE_MEDIA_STREAM) platform/mediastream/openwebrtc/MediaEndpointOwr.cpp platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp - ) + ) endif () diff --git a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp index cae310c04a53a..1355d63b9b507 100644 --- a/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/UserMediaPermissionRequestManager.cpp @@ -74,7 +74,7 @@ void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest& request) m_idToRequestMap.remove(requestID); } -void UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed) +void UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(uint64_t requestID, bool allowed, const String& deviceUIDVideo, const String& deviceUIDAudio) { RefPtr request = m_idToRequestMap.take(requestID); if (!request) diff --git a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp index 00d7f91c4d8d8..450f8282eeb97 100644 --- a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp @@ -50,14 +50,32 @@ UserMediaPermissionRequestManager::UserMediaPermissionRequestManager(WebPage& pa void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) { - // The user permission request dialog is not supported by WPE, so - // there for check a environment variable to contol the grant - if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")) - { - request.userMediaAccessGranted(); + /* + * FIX_ME: + * The user permission request dialog is not supported by WPE, so + * there for check some environment variables to contol the grant + * process. + */ + String deviceUIDAudio = emptyString(); + String deviceUIDVideo = emptyString(); + + if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")){ + /* + * FIX_ME: Temporary solution to hint about preferred device names. + */ + char* deviceUID = getenv("WPE_AUDIO_SOURCE_NAME"); + if (deviceUID) { + deviceUIDAudio = String(deviceUID); + } + + deviceUID = getenv("WPE_VIDEO_SOURCE_NAME"); + if (deviceUID) { + deviceUIDVideo = String(deviceUID); + } + + request.userMediaAccessGranted(deviceUIDVideo, deviceUIDAudio); } - else - { + else { request.userMediaAccessDenied(); } } @@ -68,7 +86,7 @@ void UserMediaPermissionRequestManager::cancelRequest(UserMediaRequest& request) if (!requestID) return; m_idToRequestMap.remove(requestID); -} +} void UserMediaPermissionRequestManager::didReceiveUserMediaPermissionDecision(uint64_t userMediaID, bool allowed, const String& deviceUIDVideo, const String& deviceUIDAudio) { From 6ac12fdd2243cf5e52e243742fc28eda6d797702 Mon Sep 17 00:00:00 2001 From: Adam Bergkvist Date: Fri, 28 Aug 2015 16:15:45 +0200 Subject: [PATCH 152/155] MediaEndpointPeerConnection: Implement queued operations --- .../MediaEndpointPeerConnection.cpp | 69 ++++++++++++++++++- .../mediastream/MediaEndpointPeerConnection.h | 13 ++++ 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp index 96e4c50314a8b..a40709221c870 100644 --- a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.cpp @@ -206,7 +206,29 @@ static void updateMediaDescriptionsWithSenders(const Vector& options, OfferAnswerResolveCallback resolveCallback, RejectCallback) +void MediaEndpointPeerConnection::enqueueOperation(std::function operation) +{ + m_operationsQueue.append(operation); + if (m_operationsQueue.size() == 1) + callOnMainThread(m_operationsQueue[0]); +} + +void MediaEndpointPeerConnection::completeQueuedOperation() +{ + m_operationsQueue.remove(0); + if (!m_operationsQueue.isEmpty()) + callOnMainThread(m_operationsQueue[0]); +} + +void MediaEndpointPeerConnection::createOffer(const RefPtr& options, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback) +{ + RefPtr protectedOptions = options; + enqueueOperation([this, protectedOptions, resolveCallback, rejectCallback]() { + queuedCreateOffer(protectedOptions, resolveCallback, rejectCallback); + }); +} + +void MediaEndpointPeerConnection::queuedCreateOffer(const RefPtr& options, OfferAnswerResolveCallback resolveCallback, RejectCallback) { RefPtr configurationSnapshot = m_localConfiguration ? MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); @@ -252,10 +274,20 @@ void MediaEndpointPeerConnection::createOffer(const RefPtr& opt String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); RefPtr offer = RTCSessionDescription::create("offer", toSDP(json)); + resolveCallback(*offer); + completeQueuedOperation(); } -void MediaEndpointPeerConnection::createAnswer(const RefPtr&, OfferAnswerResolveCallback resolveCallback, RejectCallback) +void MediaEndpointPeerConnection::createAnswer(const RefPtr& options, OfferAnswerResolveCallback resolveCallback, RejectCallback rejectCallback) +{ + RefPtr protectedOptions = options; + enqueueOperation([this, protectedOptions, resolveCallback, rejectCallback]() { + queuedCreateAnswer(protectedOptions, resolveCallback, rejectCallback); + }); +} + +void MediaEndpointPeerConnection::queuedCreateAnswer(const RefPtr&, OfferAnswerResolveCallback resolveCallback, RejectCallback) { RefPtr configurationSnapshot = m_localConfiguration ? MediaEndpointConfigurationConversions::fromJSON(MediaEndpointConfigurationConversions::toJSON(m_localConfiguration.get())) : MediaEndpointConfiguration::create(); @@ -293,10 +325,20 @@ void MediaEndpointPeerConnection::createAnswer(const RefPtr&, String json = MediaEndpointConfigurationConversions::toJSON(configurationSnapshot.get()); RefPtr answer = RTCSessionDescription::create("answer", toSDP(json)); + resolveCallback(*answer); + completeQueuedOperation(); } void MediaEndpointPeerConnection::setLocalDescription(RTCSessionDescription* description, PeerConnectionStates::SignalingState targetState, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) +{ + RefPtr protectedDescription = description; + enqueueOperation([this, protectedDescription, targetState, resolveCallback, rejectCallback]() { + queuedSetLocalDescription(protectedDescription.get(), targetState, resolveCallback, rejectCallback); + }); +} + +void MediaEndpointPeerConnection::queuedSetLocalDescription(RTCSessionDescription* description, PeerConnectionStates::SignalingState targetState, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { unsigned previousNumberOfMediaDescriptions = m_localConfiguration ? m_localConfiguration->mediaDescriptions().size() : 0; @@ -308,6 +350,7 @@ void MediaEndpointPeerConnection::setLocalDescription(RTCSessionDescription* des // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); rejectCallback(*error); + completeQueuedOperation(); return; } @@ -317,6 +360,7 @@ void MediaEndpointPeerConnection::setLocalDescription(RTCSessionDescription* des m_resolveSetLocalDescription = [this, targetState, resolveCallback]() mutable { m_client->changeSignalingState(targetState); resolveCallback(); + completeQueuedOperation(); }; if (hasNewMediaDescriptions) @@ -362,6 +406,14 @@ static Vector> filterPayloads(const Vector protectedDescription = description; + enqueueOperation([this, protectedDescription, targetState, resolveCallback, rejectCallback]() { + queuedSetRemoteDescription(protectedDescription.get(), targetState, resolveCallback, rejectCallback); + }); +} + +void MediaEndpointPeerConnection::queuedSetRemoteDescription(RTCSessionDescription* description, PeerConnectionStates::SignalingState targetState, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { String json = fromSDP(description->sdp()); m_remoteConfiguration = MediaEndpointConfigurationConversions::fromJSON(json); @@ -371,6 +423,7 @@ void MediaEndpointPeerConnection::setRemoteDescription(RTCSessionDescription* de // FIXME: Error type? RefPtr error = DOMError::create("InvalidSessionDescriptionError (unable to parse description)"); rejectCallback(*error); + completeQueuedOperation(); return; } @@ -394,6 +447,7 @@ void MediaEndpointPeerConnection::setRemoteDescription(RTCSessionDescription* de m_client->changeSignalingState(targetState); resolveCallback(); + completeQueuedOperation(); } RefPtr MediaEndpointPeerConnection::remoteDescription() const @@ -413,6 +467,14 @@ void MediaEndpointPeerConnection::setConfiguration(RTCConfiguration& configurati } void MediaEndpointPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) +{ + RefPtr protectedCandidate = rtcCandidate; + enqueueOperation([this, protectedCandidate, resolveCallback, rejectCallback]() { + queuedAddIceCandidate(protectedCandidate.get(), resolveCallback, rejectCallback); + }); +} + +void MediaEndpointPeerConnection::queuedAddIceCandidate(RTCIceCandidate* rtcCandidate, VoidResolveCallback resolveCallback, RejectCallback rejectCallback) { String json = iceCandidateFromSDP(rtcCandidate->candidate()); RefPtr candidate = MediaEndpointConfigurationConversions::iceCandidateFromJSON(json); @@ -420,6 +482,7 @@ void MediaEndpointPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, // FIXME: Error type? RefPtr error = DOMError::create("SyntaxError (malformed candidate)"); rejectCallback(*error); + completeQueuedOperation(); return; } @@ -428,6 +491,7 @@ void MediaEndpointPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, // FIXME: Error type? RefPtr error = DOMError::create("InvalidSdpMlineIndex (sdpMLineIndex out of range"); rejectCallback(*error); + completeQueuedOperation(); return; } @@ -437,6 +501,7 @@ void MediaEndpointPeerConnection::addIceCandidate(RTCIceCandidate* rtcCandidate, m_mediaEndpoint->addRemoteCandidate(*candidate, mdescIndex, mdesc.iceUfrag(), mdesc.icePassword()); resolveCallback(); + completeQueuedOperation(); } void MediaEndpointPeerConnection::stop() diff --git a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h index cacfe996b582a..eccce661f0a66 100644 --- a/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h +++ b/Source/WebCore/Modules/mediastream/MediaEndpointPeerConnection.h @@ -69,6 +69,17 @@ class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEn SetLocalDescriptionAlreadyResolved }; + void enqueueOperation(std::function); + void completeQueuedOperation(); + + void queuedCreateOffer(const RefPtr&, OfferAnswerResolveCallback, RejectCallback); + void queuedCreateAnswer(const RefPtr&, OfferAnswerResolveCallback, RejectCallback); + + void queuedSetLocalDescription(RTCSessionDescription*, PeerConnectionStates::SignalingState targetState, VoidResolveCallback, RejectCallback); + void queuedSetRemoteDescription(RTCSessionDescription*, PeerConnectionStates::SignalingState targetState, VoidResolveCallback, RejectCallback); + + void queuedAddIceCandidate(RTCIceCandidate*, VoidResolveCallback, RejectCallback); + bool isLocalConfigurationComplete() const; ResolveSetLocalDescriptionResult maybeResolveSetLocalDescription(); void maybeDispatchGatheringDone(); @@ -88,6 +99,8 @@ class MediaEndpointPeerConnection : public PeerConnectionBackend, public MediaEn PeerConnectionBackendClient* m_client; std::unique_ptr m_mediaEndpoint; + Vector> m_operationsQueue; + mutable RefPtr m_isolatedWorld; String m_cname; From 7814ec142f68d4dc12b89312e6ebccdc9266eafb Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Mon, 31 Aug 2015 22:45:42 +0200 Subject: [PATCH 153/155] update permission manager after merge. --- .../wpe/UserMediaPermissionRequestManagerWPE.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp index 450f8282eeb97..3130489457cc4 100644 --- a/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp +++ b/Source/WebKit2/WebProcess/MediaStream/wpe/UserMediaPermissionRequestManagerWPE.cpp @@ -61,18 +61,18 @@ void UserMediaPermissionRequestManager::startRequest(UserMediaRequest& request) if (g_getenv("WPE_WEBRTC_GRANT_PERMISSION")){ /* - * FIX_ME: Temporary solution to hint about preferred device names. + * FIX_ME: Temporary solution. */ - char* deviceUID = getenv("WPE_AUDIO_SOURCE_NAME"); + char* deviceUID = getenv("WEBKIT_AUDIO_SOURCE_NAME"); if (deviceUID) { deviceUIDAudio = String(deviceUID); } - deviceUID = getenv("WPE_VIDEO_SOURCE_NAME"); + deviceUID = getenv("WEBKIT_VIDEO_SOURCE_NAME"); if (deviceUID) { deviceUIDVideo = String(deviceUID); } - + request.userMediaAccessGranted(deviceUIDVideo, deviceUIDAudio); } else { From f98e4df2dc71622437889b234ed970afb8440543 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Mon, 31 Aug 2015 22:46:53 +0200 Subject: [PATCH 154/155] update interface name. --- Source/WebCore/Modules/mediastream/MediaStream.idl | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/WebCore/Modules/mediastream/MediaStream.idl b/Source/WebCore/Modules/mediastream/MediaStream.idl index 72b471db99b9b..1e2172393a1a4 100644 --- a/Source/WebCore/Modules/mediastream/MediaStream.idl +++ b/Source/WebCore/Modules/mediastream/MediaStream.idl @@ -29,6 +29,7 @@ Constructor(MediaStream stream), Constructor(MediaStreamTrack[] tracks), ConstructorCallWith=ScriptExecutionContext, + InterfaceName=webkitMediaStream, ] interface MediaStream { readonly attribute DOMString id; From f5caa348ed459f61a32c9c9a2afa171596926ac4 Mon Sep 17 00:00:00 2001 From: bramoosterhuis Date: Fri, 4 Sep 2015 03:05:17 +0200 Subject: [PATCH 155/155] set fixed video resolution. --- .../graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp index 0bf26b990b273..ffb01e5510071 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerOwr.cpp @@ -197,7 +197,11 @@ bool MediaPlayerPrivateGStreamerOwr::internalLoad() } else if (track->type() == RealtimeMediaSource::Video) { if (m_videoSource && (m_videoSource.get() == source)) g_object_set(m_videoRenderer, "disabled", FALSE, nullptr); - + // + // FIXME: Fixate video resolution to HD for now. + // + g_object_set(m_videoRenderer, "width", 1280, "height", 720, "max-framerate", 30.0, NULL); + owr_media_renderer_set_source(OWR_MEDIA_RENDERER(m_videoRenderer), mediaSource); m_videoSource = source; source->addObserver(this);