summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/mediastream
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/mediastream
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/platform/mediastream')
-rw-r--r--Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.h74
-rw-r--r--Source/WebCore/platform/mediastream/CaptureDevice.h72
-rw-r--r--Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp124
-rw-r--r--Source/WebCore/platform/mediastream/CaptureDeviceManager.h (renamed from Source/WebCore/platform/mediastream/MediaStreamCreationClient.h)33
-rw-r--r--Source/WebCore/platform/mediastream/IceCandidate.h (renamed from Source/WebCore/platform/mediastream/MediaStreamCenter.h)59
-rw-r--r--Source/WebCore/platform/mediastream/MediaConstraints.cpp345
-rw-r--r--Source/WebCore/platform/mediastream/MediaConstraints.h790
-rw-r--r--Source/WebCore/platform/mediastream/MediaEndpoint.cpp86
-rw-r--r--Source/WebCore/platform/mediastream/MediaEndpoint.h108
-rw-r--r--Source/WebCore/platform/mediastream/MediaEndpointConfiguration.cpp54
-rw-r--r--Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h (renamed from Source/WebCore/platform/mediastream/gstreamer/MediaStreamCenterGStreamer.h)44
-rw-r--r--Source/WebCore/platform/mediastream/MediaEndpointSessionConfiguration.h86
-rw-r--r--Source/WebCore/platform/mediastream/MediaPayload.h61
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamConstraintsValidationClient.h7
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp339
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamPrivate.h120
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamSource.cpp160
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamSource.h129
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamSourceCapabilities.h149
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp250
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h117
-rw-r--r--Source/WebCore/platform/mediastream/MediaStreamTrackSourcesRequestClient.h76
-rw-r--r--Source/WebCore/platform/mediastream/PeerConnectionStates.h89
-rw-r--r--Source/WebCore/platform/mediastream/PeerMediaDescription.h77
-rw-r--r--Source/WebCore/platform/mediastream/RTCConfiguration.h88
-rw-r--r--Source/WebCore/platform/mediastream/RTCDTMFSenderHandler.h4
-rw-r--r--Source/WebCore/platform/mediastream/RTCDTMFSenderHandlerClient.h4
-rw-r--r--Source/WebCore/platform/mediastream/RTCDataChannelHandler.h29
-rw-r--r--Source/WebCore/platform/mediastream/RTCDataChannelHandlerClient.h13
-rw-r--r--Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.cpp4
-rw-r--r--Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.h4
-rw-r--r--Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp76
-rw-r--r--Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h105
-rw-r--r--Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h4
-rw-r--r--Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.cpp4
-rw-r--r--Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.h4
-rw-r--r--Source/WebCore/platform/mediastream/RTCSessionDescriptionRequest.h4
-rw-r--r--Source/WebCore/platform/mediastream/RTCVoidRequest.h6
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp783
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSource.h229
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h192
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp (renamed from Source/WebCore/platform/mediastream/MediaStreamCenter.cpp)19
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h79
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp (renamed from Source/WebCore/platform/mediastream/MediaStreamSourceStates.cpp)72
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h118
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp139
-rw-r--r--Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h117
-rw-r--r--Source/WebCore/platform/mediastream/SDPProcessorScriptResource.cpp53
-rw-r--r--Source/WebCore/platform/mediastream/SDPProcessorScriptResource.h (renamed from Source/WebCore/platform/mediastream/RTCStatsRequest.h)32
-rw-r--r--Source/WebCore/platform/mediastream/VideoTrackPrivateMediaStream.h74
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h46
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp101
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h162
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h44
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp160
-rw-r--r--Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h68
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp750
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h149
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp57
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.h40
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h70
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp191
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h (renamed from Source/WebCore/platform/mediastream/gstreamer/MediaStreamCenterGStreamer.cpp)69
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.cpp60
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.h99
-rw-r--r--Source/WebCore/platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h82
66 files changed, 6466 insertions, 1387 deletions
diff --git a/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.h b/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.h
new file mode 100644
index 000000000..f3e1c3dc0
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015-2017 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM)
+
+#include "AudioTrackPrivate.h"
+#include "MediaStreamTrackPrivate.h"
+
+namespace WebCore {
+
+class AudioTrackPrivateMediaStream : public AudioTrackPrivate {
+ WTF_MAKE_NONCOPYABLE(AudioTrackPrivateMediaStream)
+public:
+ static RefPtr<AudioTrackPrivateMediaStream> create(MediaStreamTrackPrivate& streamTrack)
+ {
+ return adoptRef(*new AudioTrackPrivateMediaStream(streamTrack));
+ }
+
+ Kind kind() const override { return Kind::Main; }
+ AtomicString id() const override { return m_id; }
+ AtomicString label() const override { return m_label; }
+ AtomicString language() const override { return emptyAtom; }
+ int trackIndex() const override { return m_index; }
+
+ void setTrackIndex(int index) { m_index = index; }
+
+ MediaStreamTrackPrivate& streamTrack() { return m_streamTrack.get(); }
+
+ MediaTime timelineOffset() const { return m_timelineOffset; }
+ void setTimelineOffset(const MediaTime& offset) { m_timelineOffset = offset; }
+
+protected:
+ AudioTrackPrivateMediaStream(MediaStreamTrackPrivate& track)
+ : m_streamTrack(track)
+ , m_id(track.id())
+ , m_label(track.label())
+ , m_timelineOffset(MediaTime::invalidTime())
+ {
+ }
+
+ Ref<MediaStreamTrackPrivate> m_streamTrack;
+ AtomicString m_id;
+ AtomicString m_label;
+ int m_index { 0 };
+ MediaTime m_timelineOffset;
+};
+
+}
+
+#endif // ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/CaptureDevice.h b/Source/WebCore/platform/mediastream/CaptureDevice.h
new file mode 100644
index 000000000..86152bf7e
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/CaptureDevice.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class CaptureDevice {
+public:
+ enum class DeviceType { Unknown, Audio, Video };
+
+ CaptureDevice(const String& persistentId, DeviceType type, const String& label, const String& groupId = emptyString())
+ : m_persistentId(persistentId)
+ , m_type(type)
+ , m_label(label)
+ , m_groupId(groupId)
+ {
+ }
+
+ CaptureDevice() = default;
+
+ const String& persistentId() const { return m_persistentId; }
+ void setPersistentId(const String& id) { m_persistentId = id; }
+
+ const String& label() const { return m_label; }
+ void setLabel(const String& label) { m_label = label; }
+
+ const String& groupId() const { return m_groupId; }
+ void setGroupId(const String& id) { m_groupId = id; }
+
+ DeviceType type() const { return m_type; }
+ void setType(DeviceType type) { m_type = type; }
+
+ bool enabled() const { return m_enabled; }
+ void setEnabled(bool enabled) { m_enabled = enabled; }
+private:
+ String m_persistentId;
+ DeviceType m_type { DeviceType::Unknown };
+ String m_label;
+ String m_groupId;
+ bool m_enabled { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp b/Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp
new file mode 100644
index 000000000..19fe3a02f
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/CaptureDeviceManager.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2015-2016 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.
+ */
+
+#import "config.h"
+#import "CaptureDeviceManager.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#import "Logging.h"
+#import "MediaConstraints.h"
+#import "RealtimeMediaSource.h"
+#import "RealtimeMediaSourceCenter.h"
+#import "RealtimeMediaSourceSettings.h"
+#import "UUID.h"
+#import <wtf/MainThread.h>
+#import <wtf/NeverDestroyed.h>
+#import <wtf/text/StringHash.h>
+
+using namespace WebCore;
+
+CaptureDeviceManager::~CaptureDeviceManager()
+{
+}
+
+Vector<CaptureDevice> CaptureDeviceManager::getSourcesInfo()
+{
+ Vector<CaptureDevice> sourcesInfo;
+ for (auto captureDevice : captureDevices()) {
+ if (!captureDevice.enabled() || captureDevice.type() == CaptureDevice::DeviceType::Unknown)
+ continue;
+
+ sourcesInfo.append(captureDevice);
+ }
+ LOG(Media, "CaptureDeviceManager::getSourcesInfo(%p), found %zu active devices", this, sourcesInfo.size());
+ return sourcesInfo;
+}
+
+bool CaptureDeviceManager::captureDeviceFromDeviceID(const String& captureDeviceID, CaptureDevice& foundDevice)
+{
+ for (auto& device : captureDevices()) {
+ if (device.persistentId() == captureDeviceID) {
+ foundDevice = device;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+Vector<String> CaptureDeviceManager::bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type type, const MediaConstraints& constraints, String& invalidConstraint)
+{
+ Vector<RefPtr<RealtimeMediaSource>> bestSources;
+
+ struct {
+ bool operator()(RefPtr<RealtimeMediaSource> a, RefPtr<RealtimeMediaSource> b)
+ {
+ return a->fitnessScore() < b->fitnessScore();
+ }
+ } sortBasedOnFitnessScore;
+
+ CaptureDevice::DeviceType deviceType = type == RealtimeMediaSource::Video ? CaptureDevice::DeviceType::Video : CaptureDevice::DeviceType::Audio;
+ for (auto& captureDevice : captureDevices()) {
+ if (!captureDevice.enabled() || captureDevice.type() != deviceType)
+ continue;
+
+ if (auto captureSource = createMediaSourceForCaptureDeviceWithConstraints(captureDevice, &constraints, invalidConstraint))
+ bestSources.append(captureSource.leakRef());
+ }
+
+ Vector<String> sourceUIDs;
+ if (bestSources.isEmpty())
+ return sourceUIDs;
+
+ sourceUIDs.reserveInitialCapacity(bestSources.size());
+ std::sort(bestSources.begin(), bestSources.end(), sortBasedOnFitnessScore);
+ for (auto& device : bestSources)
+ sourceUIDs.uncheckedAppend(device->persistentID());
+
+ return sourceUIDs;
+}
+
+RefPtr<RealtimeMediaSource> CaptureDeviceManager::sourceWithUID(const String& deviceUID, RealtimeMediaSource::Type type, const MediaConstraints* constraints, String& invalidConstraint)
+{
+ for (auto& captureDevice : captureDevices()) {
+ if (type == RealtimeMediaSource::None)
+ continue;
+
+ CaptureDevice::DeviceType deviceType = type == RealtimeMediaSource::Video ? CaptureDevice::DeviceType::Video : CaptureDevice::DeviceType::Audio;
+ if (captureDevice.persistentId() != deviceUID || captureDevice.type() != deviceType)
+ continue;
+
+ if (!captureDevice.enabled())
+ continue;
+
+ if (auto mediaSource = createMediaSourceForCaptureDeviceWithConstraints(captureDevice, constraints, invalidConstraint))
+ return mediaSource;
+ }
+
+ return nullptr;
+}
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/MediaStreamCreationClient.h b/Source/WebCore/platform/mediastream/CaptureDeviceManager.h
index 22aa49714..5d40099f3 100644
--- a/Source/WebCore/platform/mediastream/MediaStreamCreationClient.h
+++ b/Source/WebCore/platform/mediastream/CaptureDeviceManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -23,31 +23,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamCreationClient_h
-#define MediaStreamCreationClient_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include "MediaStreamSource.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include "CaptureDevice.h"
+#include "RealtimeMediaSource.h"
namespace WebCore {
-class MediaStreamCreationClient : public RefCounted<MediaStreamCreationClient> {
+class CaptureDeviceManager {
public:
- virtual ~MediaStreamCreationClient() { }
+ virtual Vector<CaptureDevice>& captureDevices() = 0;
+ virtual void refreshCaptureDevices() { }
+ virtual Vector<CaptureDevice> getSourcesInfo();
+ virtual Vector<String> bestSourcesForTypeAndConstraints(RealtimeMediaSource::Type, const MediaConstraints&, String&);
+ virtual RefPtr<RealtimeMediaSource> sourceWithUID(const String&, RealtimeMediaSource::Type, const MediaConstraints*, String&);
- virtual void constraintsValidated() = 0;
- virtual void constraintsInvalid(const String& constraintName) = 0;
+protected:
+ virtual ~CaptureDeviceManager();
+ virtual RefPtr<RealtimeMediaSource> createMediaSourceForCaptureDeviceWithConstraints(const CaptureDevice&, const MediaConstraints*, String&) = 0;
- virtual void didCreateStream(PassRefPtr<MediaStreamPrivate>) = 0;
- virtual void failedToCreateStreamWithConstraintsError(const String& constraintName) = 0;
- virtual void failedToCreateStreamWithPermissionError() = 0;
+ bool captureDeviceFromDeviceID(const String& captureDeviceID, CaptureDevice& source);
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamCreationClient_h
diff --git a/Source/WebCore/platform/mediastream/MediaStreamCenter.h b/Source/WebCore/platform/mediastream/IceCandidate.h
index 7d540b94d..2b28c375b 100644
--- a/Source/WebCore/platform/mediastream/MediaStreamCenter.h
+++ b/Source/WebCore/platform/mediastream/IceCandidate.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2012 Google 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
@@ -29,43 +28,41 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamCenter_h
-#define MediaStreamCenter_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include "MediaStreamSource.h"
-#include <wtf/PassRefPtr.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
-class MediaConstraints;
-class MediaStreamCreationClient;
-class MediaStreamSourceStates;
-class MediaStreamTrackSourcesRequestClient;
+struct IceCandidate {
+ String type;
+ String foundation;
+ unsigned componentId { 0 };
+ String transport;
+ unsigned long priority { 0 };
+ String address;
+ unsigned port { 0 };
+ String tcpType;
+ String relatedAddress;
+ unsigned relatedPort { 0 };
-class MediaStreamCenter {
-public:
- virtual ~MediaStreamCenter();
-
- static MediaStreamCenter& shared();
- static void setSharedStreamCenter(MediaStreamCenter*);
-
- virtual void validateRequestConstraints(PassRefPtr<MediaStreamCreationClient>, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints) = 0;
-
- virtual void createMediaStream(PassRefPtr<MediaStreamCreationClient>, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints) = 0;
-
- virtual bool getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequestClient>) = 0;
-
-protected:
- MediaStreamCenter();
-
- static MediaStreamCenter& platformCenter();
+ IceCandidate() = default;
+ IceCandidate(String&& type, String&& foundation, unsigned componentId, String&& transport, unsigned long priority, String&& address, unsigned port, String&& tcpType, String&& relatedAddress, unsigned relatedPort)
+ : type(WTFMove(type))
+ , foundation(WTFMove(foundation))
+ , componentId(componentId)
+ , transport(WTFMove(transport))
+ , priority(priority)
+ , address(WTFMove(address))
+ , port(port)
+ , tcpType(WTFMove(tcpType))
+ , relatedAddress(WTFMove(relatedAddress))
+ , relatedPort(relatedPort)
+ { }
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamCenter_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/MediaConstraints.cpp b/Source/WebCore/platform/mediastream/MediaConstraints.cpp
new file mode 100644
index 000000000..2805dce99
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/MediaConstraints.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2016 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.
+ * 3. Neither the name of Google Inc. 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 "MediaConstraints.h"
+
+#if ENABLE(MEDIA_STREAM)
+#include "RealtimeMediaSourceCenter.h"
+#include "RealtimeMediaSourceSupportedConstraints.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+const String& StringConstraint::find(std::function<bool(const String&)> filter) const
+{
+ for (auto& constraint : m_exact) {
+ if (filter(constraint))
+ return constraint;
+ }
+
+ for (auto& constraint : m_ideal) {
+ if (filter(constraint))
+ return constraint;
+ }
+
+ return emptyString();
+}
+
+double StringConstraint::fitnessDistance(const String& value) const
+{
+ // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
+
+ // 1. If the constraint is not supported by the browser, the fitness distance is 0.
+ if (isEmpty())
+ return 0;
+
+ // 2. If the constraint is required ('min', 'max', or 'exact'), and the settings
+ // dictionary's value for the constraint does not satisfy the constraint, the
+ // fitness distance is positive infinity.
+ if (!m_exact.isEmpty() && m_exact.find(value) == notFound)
+ return std::numeric_limits<double>::infinity();
+
+ // 3. If no ideal value is specified, the fitness distance is 0.
+ if (m_exact.isEmpty())
+ return 0;
+
+ // 5. For all string and enum non-required constraints (deviceId, groupId, facingMode,
+ // echoCancellation), the fitness distance is the result of the formula
+ // (actual == ideal) ? 0 : 1
+ return m_ideal.find(value) != notFound ? 0 : 1;
+}
+
+double StringConstraint::fitnessDistance(const Vector<String>& values) const
+{
+ if (isEmpty())
+ return 0;
+
+ double minimumDistance = std::numeric_limits<double>::infinity();
+ for (auto& value : values)
+ minimumDistance = std::min(minimumDistance, fitnessDistance(value));
+
+ return minimumDistance;
+}
+
+void StringConstraint::merge(const MediaConstraint& other)
+{
+ ASSERT(other.isString());
+ const StringConstraint& typedOther = downcast<StringConstraint>(other);
+
+ if (typedOther.isEmpty())
+ return;
+
+ Vector<String> values;
+ if (typedOther.getExact(values)) {
+ if (m_exact.isEmpty())
+ m_exact = values;
+ else {
+ for (auto& value : values) {
+ if (m_exact.find(value) == notFound)
+ m_exact.append(value);
+ }
+ }
+ }
+
+ if (typedOther.getIdeal(values)) {
+ if (m_ideal.isEmpty())
+ m_ideal = values;
+ else {
+ for (auto& value : values) {
+ if (m_ideal.find(value) == notFound)
+ m_ideal.append(value);
+ }
+ }
+ }
+}
+
+void FlattenedConstraint::set(const MediaConstraint& constraint)
+{
+ for (auto& variant : m_variants) {
+ if (variant.constraintType() == constraint.constraintType())
+ return;
+ }
+
+ append(constraint);
+}
+
+void FlattenedConstraint::merge(const MediaConstraint& constraint)
+{
+ for (auto& variant : *this) {
+ if (variant.constraintType() != constraint.constraintType())
+ continue;
+
+ switch (variant.dataType()) {
+ case MediaConstraint::DataType::Integer:
+ ASSERT(constraint.isInt());
+ downcast<const IntConstraint>(variant).merge(downcast<const IntConstraint>(constraint));
+ return;
+ case MediaConstraint::DataType::Double:
+ ASSERT(constraint.isDouble());
+ downcast<const DoubleConstraint>(variant).merge(downcast<const DoubleConstraint>(constraint));
+ return;
+ case MediaConstraint::DataType::Boolean:
+ ASSERT(constraint.isBoolean());
+ downcast<const BooleanConstraint>(variant).merge(downcast<const BooleanConstraint>(constraint));
+ return;
+ case MediaConstraint::DataType::String:
+ ASSERT(constraint.isString());
+ downcast<const StringConstraint>(variant).merge(downcast<const StringConstraint>(constraint));
+ return;
+ case MediaConstraint::DataType::None:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ }
+
+ append(constraint);
+}
+
+void FlattenedConstraint::append(const MediaConstraint& constraint)
+{
+#ifndef NDEBUG
+ ++m_generation;
+#endif
+
+ m_variants.append(ConstraintHolder::create(constraint));
+}
+
+const MediaConstraint* FlattenedConstraint::find(MediaConstraintType type) const
+{
+ for (auto& variant : m_variants) {
+ if (variant.constraintType() == type)
+ return &variant.constraint();
+ }
+
+ return nullptr;
+}
+
+void MediaTrackConstraintSetMap::forEach(std::function<void(const MediaConstraint&)> callback) const
+{
+ filter([callback] (const MediaConstraint& constraint) mutable {
+ callback(constraint);
+ return false;
+ });
+}
+
+void MediaTrackConstraintSetMap::filter(std::function<bool(const MediaConstraint&)> callback) const
+{
+ if (m_width && !m_width->isEmpty() && callback(*m_width))
+ return;
+ if (m_height && !m_height->isEmpty() && callback(*m_height))
+ return;
+ if (m_sampleRate && !m_sampleRate->isEmpty() && callback(*m_sampleRate))
+ return;
+ if (m_sampleSize && !m_sampleSize->isEmpty() && callback(*m_sampleSize))
+ return;
+
+ if (m_aspectRatio && !m_aspectRatio->isEmpty() && callback(*m_aspectRatio))
+ return;
+ if (m_frameRate && !m_frameRate->isEmpty() && callback(*m_frameRate))
+ return;
+ if (m_volume && !m_volume->isEmpty() && callback(*m_volume))
+ return;
+
+ if (m_echoCancellation && !m_echoCancellation->isEmpty() && callback(*m_echoCancellation))
+ return;
+
+ if (m_facingMode && !m_facingMode->isEmpty() && callback(*m_facingMode))
+ return;
+ if (m_deviceId && !m_deviceId->isEmpty() && callback(*m_deviceId))
+ return;
+ if (m_groupId && !m_groupId->isEmpty() && callback(*m_groupId))
+ return;
+}
+
+void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<IntConstraint>&& constraint)
+{
+ switch (constraintType) {
+ case MediaConstraintType::Width:
+ m_width = WTFMove(constraint);
+ break;
+ case MediaConstraintType::Height:
+ m_height = WTFMove(constraint);
+ break;
+ case MediaConstraintType::SampleRate:
+ m_sampleRate = WTFMove(constraint);
+ break;
+ case MediaConstraintType::SampleSize:
+ m_sampleSize = WTFMove(constraint);
+ break;
+
+ case MediaConstraintType::AspectRatio:
+ case MediaConstraintType::FrameRate:
+ case MediaConstraintType::Volume:
+ case MediaConstraintType::EchoCancellation:
+ case MediaConstraintType::FacingMode:
+ case MediaConstraintType::DeviceId:
+ case MediaConstraintType::GroupId:
+ case MediaConstraintType::Unknown:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<DoubleConstraint>&& constraint)
+{
+ switch (constraintType) {
+ case MediaConstraintType::AspectRatio:
+ m_aspectRatio = WTFMove(constraint);
+ break;
+ case MediaConstraintType::FrameRate:
+ m_frameRate = WTFMove(constraint);
+ break;
+ case MediaConstraintType::Volume:
+ m_volume = WTFMove(constraint);
+ break;
+
+ case MediaConstraintType::Width:
+ case MediaConstraintType::Height:
+ case MediaConstraintType::SampleRate:
+ case MediaConstraintType::SampleSize:
+ case MediaConstraintType::EchoCancellation:
+ case MediaConstraintType::FacingMode:
+ case MediaConstraintType::DeviceId:
+ case MediaConstraintType::GroupId:
+ case MediaConstraintType::Unknown:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<BooleanConstraint>&& constraint)
+{
+ switch (constraintType) {
+ case MediaConstraintType::EchoCancellation:
+ m_echoCancellation = WTFMove(constraint);
+ break;
+
+ case MediaConstraintType::Width:
+ case MediaConstraintType::Height:
+ case MediaConstraintType::SampleRate:
+ case MediaConstraintType::SampleSize:
+ case MediaConstraintType::AspectRatio:
+ case MediaConstraintType::FrameRate:
+ case MediaConstraintType::Volume:
+ case MediaConstraintType::FacingMode:
+ case MediaConstraintType::DeviceId:
+ case MediaConstraintType::GroupId:
+ case MediaConstraintType::Unknown:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void MediaTrackConstraintSetMap::set(MediaConstraintType constraintType, std::optional<StringConstraint>&& constraint)
+{
+ switch (constraintType) {
+ case MediaConstraintType::FacingMode:
+ m_facingMode = WTFMove(constraint);
+ break;
+ case MediaConstraintType::DeviceId:
+ m_deviceId = WTFMove(constraint);
+ break;
+ case MediaConstraintType::GroupId:
+ m_groupId = WTFMove(constraint);
+ break;
+
+ case MediaConstraintType::Width:
+ case MediaConstraintType::Height:
+ case MediaConstraintType::SampleRate:
+ case MediaConstraintType::SampleSize:
+ case MediaConstraintType::AspectRatio:
+ case MediaConstraintType::FrameRate:
+ case MediaConstraintType::Volume:
+ case MediaConstraintType::EchoCancellation:
+ case MediaConstraintType::Unknown:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+size_t MediaTrackConstraintSetMap::size() const
+{
+ size_t count = 0;
+ forEach([&count] (const MediaConstraint&) mutable {
+ ++count;
+ });
+
+ return count;
+}
+
+bool MediaTrackConstraintSetMap::isEmpty() const
+{
+ return !size();
+}
+
+}
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/MediaConstraints.h b/Source/WebCore/platform/mediastream/MediaConstraints.h
index 5141c228d..899837457 100644
--- a/Source/WebCore/platform/mediastream/MediaConstraints.h
+++ b/Source/WebCore/platform/mediastream/MediaConstraints.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,36 +29,787 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaConstraints_h
-#define MediaConstraints_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include <wtf/RefCounted.h>
-#include <wtf/text/WTFString.h>
+#include "RealtimeMediaSourceSupportedConstraints.h"
+#include <cstdlib>
namespace WebCore {
-struct MediaConstraint {
- MediaConstraint(String name, String value)
+class MediaConstraint {
+public:
+ enum class DataType { None, Integer, Double, Boolean, String };
+
+ bool isInt() const { return m_dataType == DataType::Integer; }
+ bool isDouble() const { return m_dataType == DataType::Double; }
+ bool isBoolean() const { return m_dataType == DataType::Boolean; }
+ bool isString() const { return m_dataType == DataType::String; }
+
+ DataType dataType() const { return m_dataType; }
+ MediaConstraintType constraintType() const { return m_constraintType; }
+ const String& name() const { return m_name; }
+
+ template <class Encoder> void encode(Encoder& encoder) const
+ {
+ encoder.encodeEnum(m_constraintType);
+ encoder << m_name;
+ encoder.encodeEnum(m_dataType);
+ }
+
+ template <class Decoder> static bool decode(Decoder& decoder, MediaConstraint& constraint)
+ {
+ if (!decoder.decodeEnum(constraint.m_constraintType))
+ return false;
+
+ if (!decoder.decode(constraint.m_name))
+ return false;
+
+ if (!decoder.decodeEnum(constraint.m_dataType))
+ return false;
+
+ return true;
+ }
+
+protected:
+ MediaConstraint(const String& name, MediaConstraintType constraintType, DataType dataType)
: m_name(name)
- , m_value(value)
+ , m_constraintType(constraintType)
+ , m_dataType(dataType)
{
}
+ MediaConstraint() = default;
+ ~MediaConstraint() = default;
+
+private:
String m_name;
- String m_value;
+ MediaConstraintType m_constraintType { MediaConstraintType::Unknown };
+ DataType m_dataType { DataType::None };
+};
+
+template<class ValueType>
+class NumericConstraint : public MediaConstraint {
+public:
+ void setMin(ValueType value) { m_min = value; }
+ void setMax(ValueType value) { m_max = value; }
+ void setExact(ValueType value) { m_exact = value; }
+ void setIdeal(ValueType value) { m_ideal = value; }
+
+ bool getMin(ValueType& min) const
+ {
+ if (!m_min)
+ return false;
+
+ min = m_min.value();
+ return true;
+ }
+
+ bool getMax(ValueType& max) const
+ {
+ if (!m_max)
+ return false;
+
+ max = m_max.value();
+ return true;
+ }
+
+ bool getExact(ValueType& exact) const
+ {
+ if (!m_exact)
+ return false;
+
+ exact = m_exact.value();
+ return true;
+ }
+
+ bool getIdeal(ValueType& ideal) const
+ {
+ if (!m_ideal)
+ return false;
+
+ ideal = m_ideal.value();
+ return true;
+ }
+
+ bool nearlyEqual(double a, double b) const
+ {
+ // Don't require strict equality when comparing constraints, or many floating point constraint values,
+ // e.g. "aspectRatio: 1.333", will never match.
+ const double epsilon = 0.00001;
+ return std::abs(a - b) <= epsilon;
+ }
+
+ double fitnessDistance(ValueType rangeMin, ValueType rangeMax) const
+ {
+ // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
+ // 1. If the constraint is not supported by the browser, the fitness distance is 0.
+ if (isEmpty())
+ return 0;
+
+ // 2. If the constraint is required ('min', 'max', or 'exact'), and the settings
+ // dictionary's value for the constraint does not satisfy the constraint, the
+ // fitness distance is positive infinity.
+ bool valid = validForRange(rangeMin, rangeMax);
+ if (m_exact) {
+ if (valid && m_min && m_exact.value() < m_min.value())
+ valid = false;
+ if (valid && m_max && m_exact.value() > m_max.value())
+ valid = false;
+ if (!valid)
+ return std::numeric_limits<double>::infinity();
+ }
+
+ if (m_min) {
+ if (valid && m_max && m_min.value() > m_max.value())
+ valid = false;
+ if (!valid)
+ return std::numeric_limits<double>::infinity();
+ }
+
+ if (m_max) {
+ if (valid && m_min && m_max.value() < m_min.value())
+ valid = false;
+ if (!valid)
+ return std::numeric_limits<double>::infinity();
+ }
+
+ // 3. If no ideal value is specified, the fitness distance is 0.
+ if (!m_ideal)
+ return 0;
+
+ // 4. For all positive numeric non-required constraints (such as height, width, frameRate,
+ // aspectRatio, sampleRate and sampleSize), the fitness distance is the result of the formula
+ //
+ // (actual == ideal) ? 0 : |actual - ideal| / max(|actual|,|ideal|)
+ ValueType ideal = m_ideal.value();
+ if (ideal >= rangeMin && ideal <= rangeMax)
+ return 0;
+
+ ideal = ideal > std::max(rangeMin, rangeMax) ? rangeMax : rangeMin;
+ return static_cast<double>(std::abs(ideal - m_ideal.value())) / std::max(std::abs(ideal), std::abs(m_ideal.value()));
+ }
+
+ bool validForRange(ValueType rangeMin, ValueType rangeMax) const
+ {
+ if (isEmpty())
+ return false;
+
+ if (m_exact) {
+ const ValueType exact = m_exact.value();
+ if (exact < rangeMin && !nearlyEqual(exact, rangeMin))
+ return false;
+ if (exact > rangeMax && !nearlyEqual(exact, rangeMax))
+ return false;
+ }
+
+ if (m_min) {
+ const ValueType constraintMin = m_min.value();
+ if (constraintMin > rangeMax && !nearlyEqual(constraintMin, rangeMax))
+ return false;
+ }
+
+ if (m_max) {
+ const ValueType constraintMax = m_max.value();
+ if (constraintMax < rangeMin && !nearlyEqual(constraintMax, rangeMin))
+ return false;
+ }
+
+ return true;
+ }
+
+ ValueType find(std::function<bool(ValueType)> function) const
+ {
+ if (m_min && function(m_min.value()))
+ return m_min.value();
+
+ if (m_max && function(m_max.value()))
+ return m_max.value();
+
+ if (m_exact && function(m_exact.value()))
+ return m_exact.value();
+
+ if (m_ideal && function(m_ideal.value()))
+ return m_ideal.value();
+
+ return 0;
+ }
+
+ ValueType valueForCapabilityRange(ValueType current, ValueType capabilityMin, ValueType capabilityMax) const
+ {
+ ValueType value;
+ ValueType min = capabilityMin;
+ ValueType max = capabilityMax;
+
+ if (m_exact) {
+ ASSERT(validForRange(capabilityMin, capabilityMax));
+ return m_exact.value();
+ }
+
+ if (m_min) {
+ value = m_min.value();
+ ASSERT(validForRange(value, capabilityMax));
+ if (value > min)
+ min = value;
+
+ // If there is no ideal, don't change if minimum is smaller than current.
+ if (!m_ideal && value < current)
+ value = current;
+ }
+
+ if (m_max) {
+ value = m_max.value();
+ ASSERT(validForRange(capabilityMin, value));
+ if (value < max)
+ max = value;
+ }
+
+ if (m_ideal)
+ value = std::max(min, std::min(max, m_ideal.value()));
+
+ return value;
+ }
+
+ bool isEmpty() const { return !m_min && !m_max && !m_exact && !m_ideal; }
+ bool isMandatory() const { return m_min || m_max || m_exact; }
+
+ template <class Encoder> void encode(Encoder& encoder) const
+ {
+ MediaConstraint::encode(encoder);
+
+ encoder << m_min;
+ encoder << m_max;
+ encoder << m_exact;
+ encoder << m_ideal;
+ }
+
+ template <class Decoder> static bool decode(Decoder& decoder, NumericConstraint& constraint)
+ {
+ if (!MediaConstraint::decode(decoder, constraint))
+ return false;
+
+ if (!decoder.decode(constraint.m_min))
+ return false;
+ if (!decoder.decode(constraint.m_max))
+ return false;
+ if (!decoder.decode(constraint.m_exact))
+ return false;
+ if (!decoder.decode(constraint.m_ideal))
+ return false;
+
+ return true;
+ }
+
+protected:
+ NumericConstraint(const String& name, MediaConstraintType type, DataType dataType)
+ : MediaConstraint(name, type, dataType)
+ {
+ }
+
+ NumericConstraint() = default;
+
+ void innerMerge(const NumericConstraint& other)
+ {
+ if (other.isEmpty())
+ return;
+
+ ValueType value;
+ if (other.getExact(value))
+ m_exact = value;
+
+ if (other.getMin(value))
+ m_min = value;
+
+ if (other.getMax(value))
+ m_max = value;
+
+ // https://w3c.github.io/mediacapture-main/#constrainable-interface
+ // When processing advanced constraints:
+ // ... the User Agent must attempt to apply, individually, any 'ideal' constraints or
+ // a constraint given as a bare value for the property. Of these properties, it must
+ // satisfy the largest number that it can, in any order.
+ if (other.getIdeal(value)) {
+ if (!m_ideal || value > m_ideal.value())
+ m_ideal = value;
+ }
+ }
+
+ std::optional<ValueType> m_min;
+ std::optional<ValueType> m_max;
+ std::optional<ValueType> m_exact;
+ std::optional<ValueType> m_ideal;
+};
+
+class IntConstraint final : public NumericConstraint<int> {
+public:
+ IntConstraint(const String& name, MediaConstraintType type)
+ : NumericConstraint<int>(name, type, DataType::Integer)
+ {
+ }
+
+ IntConstraint() = default;
+
+ void merge(const MediaConstraint& other)
+ {
+ ASSERT(other.isInt());
+ NumericConstraint::innerMerge(downcast<const IntConstraint>(other));
+ }
+};
+
+class DoubleConstraint final : public NumericConstraint<double> {
+public:
+ DoubleConstraint(const String& name, MediaConstraintType type)
+ : NumericConstraint<double>(name, type, DataType::Double)
+ {
+ }
+
+ DoubleConstraint() = default;
+
+ void merge(const MediaConstraint& other)
+ {
+ ASSERT(other.isDouble());
+ NumericConstraint::innerMerge(downcast<DoubleConstraint>(other));
+ }
+};
+
+class BooleanConstraint final : public MediaConstraint {
+public:
+ BooleanConstraint(const String& name, MediaConstraintType type)
+ : MediaConstraint(name, type, DataType::Boolean)
+ {
+ }
+
+ BooleanConstraint() = default;
+
+ void setExact(bool value) { m_exact = value; }
+ void setIdeal(bool value) { m_ideal = value; }
+
+ bool getExact(bool& exact) const
+ {
+ if (!m_exact)
+ return false;
+
+ exact = m_exact.value();
+ return true;
+ }
+
+ bool getIdeal(bool& ideal) const
+ {
+ if (!m_ideal)
+ return false;
+
+ ideal = m_ideal.value();
+ return true;
+ }
+
+ double fitnessDistance(bool value) const
+ {
+ // https://w3c.github.io/mediacapture-main/#dfn-applyconstraints
+ // 1. If the constraint is not supported by the browser, the fitness distance is 0.
+ if (isEmpty())
+ return 0;
+
+ // 2. If the constraint is required ('min', 'max', or 'exact'), and the settings
+ // dictionary's value for the constraint does not satisfy the constraint, the
+ // fitness distance is positive infinity.
+ if (m_exact && value != m_exact.value())
+ return std::numeric_limits<double>::infinity();
+
+ // 3. If no ideal value is specified, the fitness distance is 0.
+ if (!m_ideal || m_ideal.value() == value)
+ return 0;
+
+ // 5. For all string and enum non-required constraints (deviceId, groupId, facingMode,
+ // echoCancellation), the fitness distance is the result of the formula
+ // (actual == ideal) ? 0 : 1
+ return 1;
+ }
+
+ void merge(const MediaConstraint& other)
+ {
+ ASSERT(other.isBoolean());
+ const BooleanConstraint& typedOther = downcast<BooleanConstraint>(other);
+
+ if (typedOther.isEmpty())
+ return;
+
+ bool value;
+ if (typedOther.getExact(value))
+ m_exact = value;
+
+ if (typedOther.getIdeal(value)) {
+ if (!m_ideal || (value && !m_ideal.value()))
+ m_ideal = value;
+ }
+ }
+
+ bool isEmpty() const { return !m_exact && !m_ideal; };
+ bool isMandatory() const { return bool(m_exact); }
+
+ template <class Encoder> void encode(Encoder& encoder) const
+ {
+ MediaConstraint::encode(encoder);
+ encoder << m_exact;
+ encoder << m_ideal;
+ }
+
+ template <class Decoder> static bool decode(Decoder& decoder, BooleanConstraint& constraint)
+ {
+ if (!MediaConstraint::decode(decoder, constraint))
+ return false;
+
+ if (!decoder.decode(constraint.m_exact))
+ return false;
+ if (!decoder.decode(constraint.m_ideal))
+ return false;
+
+ return true;
+ }
+
+private:
+ std::optional<bool> m_exact;
+ std::optional<bool> m_ideal;
+};
+
+class StringConstraint : public MediaConstraint {
+public:
+ StringConstraint(const String& name, MediaConstraintType type)
+ : MediaConstraint(name, type, DataType::String)
+ {
+ }
+
+ StringConstraint() = default;
+
+ void setExact(const String& value)
+ {
+ m_exact.clear();
+ m_exact.append(value);
+ }
+
+ void appendExact(const String& value)
+ {
+ m_exact.append(value);
+ }
+
+ void setIdeal(const String& value)
+ {
+ m_ideal.clear();
+ m_ideal.append(value);
+ }
+
+ void appendIdeal(const String& value)
+ {
+ m_ideal.append(value);
+ }
+
+ bool getExact(Vector<String>& exact) const
+ {
+ if (!m_exact.isEmpty())
+ return false;
+
+ exact = m_exact;
+ return true;
+ }
+
+ bool getIdeal(Vector<String>& ideal) const
+ {
+ if (!m_ideal.isEmpty())
+ return false;
+
+ ideal = m_ideal;
+ return true;
+ }
+
+ double fitnessDistance(const String&) const;
+ double fitnessDistance(const Vector<String>&) const;
+
+ const String& find(std::function<bool(const String&)>) const;
+
+ bool isEmpty() const { return m_exact.isEmpty() && m_ideal.isEmpty(); }
+ bool isMandatory() const { return !m_exact.isEmpty(); }
+ WEBCORE_EXPORT void merge(const MediaConstraint&);
+
+ template <class Encoder> void encode(Encoder& encoder) const
+ {
+ MediaConstraint::encode(encoder);
+
+ encoder << m_exact;
+ encoder << m_ideal;
+ }
+
+ template <class Decoder> static bool decode(Decoder& decoder, StringConstraint& constraint)
+ {
+ if (!MediaConstraint::decode(decoder, constraint))
+ return false;
+
+ if (!decoder.decode(constraint.m_exact))
+ return false;
+ if (!decoder.decode(constraint.m_ideal))
+ return false;
+
+ return true;
+ }
+
+private:
+ Vector<String> m_exact;
+ Vector<String> m_ideal;
+};
+
+class UnknownConstraint final : public MediaConstraint {
+public:
+ UnknownConstraint(const String& name, MediaConstraintType type)
+ : MediaConstraint(name, type, DataType::None)
+ {
+ }
+
+private:
+ bool isEmpty() const { return true; }
+ bool isMandatory() const { return false; }
+ void merge(const MediaConstraint&) { }
+};
+
+class MediaTrackConstraintSetMap {
+public:
+ WEBCORE_EXPORT void forEach(std::function<void(const MediaConstraint&)>) const;
+ void filter(std::function<bool(const MediaConstraint&)>) const;
+ bool isEmpty() const;
+ WEBCORE_EXPORT size_t size() const;
+
+ WEBCORE_EXPORT void set(MediaConstraintType, std::optional<IntConstraint>&&);
+ WEBCORE_EXPORT void set(MediaConstraintType, std::optional<DoubleConstraint>&&);
+ WEBCORE_EXPORT void set(MediaConstraintType, std::optional<BooleanConstraint>&&);
+ WEBCORE_EXPORT void set(MediaConstraintType, std::optional<StringConstraint>&&);
+
+ std::optional<IntConstraint> width() const { return m_width; }
+ std::optional<IntConstraint> height() const { return m_height; }
+ std::optional<IntConstraint> sampleRate() const { return m_sampleRate; }
+ std::optional<IntConstraint> sampleSize() const { return m_sampleSize; }
+
+ std::optional<DoubleConstraint> aspectRatio() const { return m_aspectRatio; }
+ std::optional<DoubleConstraint> frameRate() const { return m_frameRate; }
+ std::optional<DoubleConstraint> volume() const { return m_volume; }
+
+ std::optional<BooleanConstraint> echoCancellation() const { return m_echoCancellation; }
+
+ std::optional<StringConstraint> facingMode() const { return m_facingMode; }
+ std::optional<StringConstraint> deviceId() const { return m_deviceId; }
+ std::optional<StringConstraint> groupId() const { return m_groupId; }
+
+ template <class Encoder> void encode(Encoder& encoder) const
+ {
+ encoder << m_width;
+ encoder << m_height;
+ encoder << m_sampleRate;
+ encoder << m_sampleSize;
+
+ encoder << m_aspectRatio;
+ encoder << m_frameRate;
+ encoder << m_volume;
+
+ encoder << m_echoCancellation;
+
+ encoder << m_facingMode;
+ encoder << m_deviceId;
+ encoder << m_groupId;
+ }
+
+ template <class Decoder> static bool decode(Decoder& decoder, MediaTrackConstraintSetMap& map)
+ {
+ if (!decoder.decode(map.m_width))
+ return false;
+ if (!decoder.decode(map.m_height))
+ return false;
+ if (!decoder.decode(map.m_sampleRate))
+ return false;
+ if (!decoder.decode(map.m_sampleSize))
+ return false;
+
+ if (!decoder.decode(map.m_aspectRatio))
+ return false;
+ if (!decoder.decode(map.m_frameRate))
+ return false;
+ if (!decoder.decode(map.m_volume))
+ return false;
+
+ if (!decoder.decode(map.m_echoCancellation))
+ return false;
+
+ if (!decoder.decode(map.m_facingMode))
+ return false;
+ if (!decoder.decode(map.m_deviceId))
+ return false;
+ if (!decoder.decode(map.m_groupId))
+ return false;
+
+ return true;
+ }
+
+private:
+ std::optional<IntConstraint> m_width;
+ std::optional<IntConstraint> m_height;
+ std::optional<IntConstraint> m_sampleRate;
+ std::optional<IntConstraint> m_sampleSize;
+
+ std::optional<DoubleConstraint> m_aspectRatio;
+ std::optional<DoubleConstraint> m_frameRate;
+ std::optional<DoubleConstraint> m_volume;
+
+ std::optional<BooleanConstraint> m_echoCancellation;
+
+ std::optional<StringConstraint> m_facingMode;
+ std::optional<StringConstraint> m_deviceId;
+ std::optional<StringConstraint> m_groupId;
+};
+
+class FlattenedConstraint {
+public:
+
+ void set(const MediaConstraint&);
+ void merge(const MediaConstraint&);
+ void append(const MediaConstraint&);
+ const MediaConstraint* find(MediaConstraintType) const;
+ bool isEmpty() const { return m_variants.isEmpty(); }
+
+ class iterator {
+ public:
+ iterator(const FlattenedConstraint* constraint, size_t index)
+ : m_constraint(constraint)
+ , m_index(index)
+#ifndef NDEBUG
+ , m_generation(constraint->m_generation)
+#endif
+ {
+ }
+
+ MediaConstraint& operator*() const
+ {
+ return m_constraint->m_variants.at(m_index).constraint();
+ }
+
+ iterator& operator++()
+ {
+#ifndef NDEBUG
+ ASSERT(m_generation == m_constraint->m_generation);
+#endif
+ m_index++;
+ return *this;
+ }
+
+ bool operator==(const iterator& other) const { return m_index == other.m_index; }
+ bool operator!=(const iterator& other) const { return !(*this == other); }
+
+ private:
+ const FlattenedConstraint* m_constraint { nullptr };
+ size_t m_index { 0 };
+#ifndef NDEBUG
+ int m_generation { 0 };
+#endif
+ };
+
+ const iterator begin() const { return iterator(this, 0); }
+ const iterator end() const { return iterator(this, m_variants.size()); }
+
+private:
+ class ConstraintHolder {
+ public:
+ static ConstraintHolder create(const MediaConstraint& value) { return ConstraintHolder(value); }
+
+ ~ConstraintHolder()
+ {
+ if (m_value.asRaw) {
+ switch (dataType()) {
+ case MediaConstraint::DataType::Integer:
+ delete m_value.asInteger;
+ break;
+ case MediaConstraint::DataType::Double:
+ delete m_value.asDouble;
+ break;
+ case MediaConstraint::DataType::Boolean:
+ delete m_value.asBoolean;
+ break;
+ case MediaConstraint::DataType::String:
+ delete m_value.asString;
+ break;
+ case MediaConstraint::DataType::None:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+#ifndef NDEBUG
+ m_value.asRaw = reinterpret_cast<MediaConstraint*>(0xbbadbeef);
+#endif
+ }
+
+ ConstraintHolder(ConstraintHolder&& other)
+ {
+ switch (other.dataType()) {
+ case MediaConstraint::DataType::Integer:
+ m_value.asInteger = std::exchange(other.m_value.asInteger, nullptr);
+ break;
+ case MediaConstraint::DataType::Double:
+ m_value.asDouble = std::exchange(other.m_value.asDouble, nullptr);
+ break;
+ case MediaConstraint::DataType::Boolean:
+ m_value.asBoolean = std::exchange(other.m_value.asBoolean, nullptr);
+ break;
+ case MediaConstraint::DataType::String:
+ m_value.asString = std::exchange(other.m_value.asString, nullptr);
+ break;
+ case MediaConstraint::DataType::None:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ MediaConstraint& constraint() const { return *m_value.asRaw; }
+ MediaConstraint::DataType dataType() const { return constraint().dataType(); }
+ MediaConstraintType constraintType() const { return constraint().constraintType(); }
+
+ private:
+ explicit ConstraintHolder(const MediaConstraint& value)
+ {
+ switch (value.dataType()) {
+ case MediaConstraint::DataType::Integer:
+ m_value.asInteger = new IntConstraint(downcast<const IntConstraint>(value));
+ break;
+ case MediaConstraint::DataType::Double:
+ m_value.asDouble = new DoubleConstraint(downcast<DoubleConstraint>(value));
+ break;
+ case MediaConstraint::DataType::Boolean:
+ m_value.asBoolean = new BooleanConstraint(downcast<BooleanConstraint>(value));
+ break;
+ case MediaConstraint::DataType::String:
+ m_value.asString = new StringConstraint(downcast<StringConstraint>(value));
+ break;
+ case MediaConstraint::DataType::None:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ union {
+ MediaConstraint* asRaw;
+ IntConstraint* asInteger;
+ DoubleConstraint* asDouble;
+ BooleanConstraint* asBoolean;
+ StringConstraint* asString;
+ } m_value;
+ };
+
+ Vector<ConstraintHolder> m_variants;
+#ifndef NDEBUG
+ int m_generation { 0 };
+#endif
};
class MediaConstraints : public RefCounted<MediaConstraints> {
public:
virtual ~MediaConstraints() { }
- virtual void getMandatoryConstraints(Vector<MediaConstraint>&) const = 0;
- virtual void getOptionalConstraints(Vector<MediaConstraint>&) const = 0;
-
- virtual bool getMandatoryConstraintValue(const String& name, String& value) const = 0;
- virtual bool getOptionalConstraintValue(const String& name, String& value) const = 0;
+ virtual const MediaTrackConstraintSetMap& mandatoryConstraints() const = 0;
+ virtual const Vector<MediaTrackConstraintSetMap>& advancedConstraints() const = 0;
+ virtual bool isValid() const = 0;
protected:
MediaConstraints() { }
@@ -65,6 +817,14 @@ protected:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#define SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(ConstraintType, predicate) \
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ConstraintType) \
+static bool isType(const WebCore::MediaConstraint& constraint) { return constraint.predicate; } \
+SPECIALIZE_TYPE_TRAITS_END()
+
+SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(IntConstraint, isInt())
+SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(DoubleConstraint, isDouble())
+SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(StringConstraint, isString())
+SPECIALIZE_TYPE_TRAITS_MEDIACONSTRAINT(BooleanConstraint, isBoolean())
-#endif // MediaConstraints_h
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.cpp b/Source/WebCore/platform/mediastream/MediaEndpoint.cpp
new file mode 100644
index 000000000..02dfddb62
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/MediaEndpoint.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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(WEB_RTC)
+#include "MediaEndpoint.h"
+
+#include "MediaPayload.h"
+#include "RTCDataChannelHandler.h"
+#include "RealtimeMediaSource.h"
+
+namespace WebCore {
+
+class EmptyRealtimeMediaSource final : public RealtimeMediaSource {
+public:
+ static Ref<EmptyRealtimeMediaSource> create() { return adoptRef(*new EmptyRealtimeMediaSource()); }
+
+private:
+ EmptyRealtimeMediaSource() : RealtimeMediaSource(emptyString(), RealtimeMediaSource::None, emptyString()) { }
+
+ RefPtr<RealtimeMediaSourceCapabilities> capabilities() const final { return nullptr; }
+ const RealtimeMediaSourceSettings& settings() const final { return m_sourceSettings; }
+
+ RealtimeMediaSourceSettings m_sourceSettings;
+};
+
+class EmptyMediaEndpoint final : public MediaEndpoint {
+private:
+ void setConfiguration(MediaEndpointConfiguration&&) final { }
+
+ void generateDtlsInfo() final { }
+ MediaPayloadVector getDefaultAudioPayloads() final { return MediaPayloadVector(); }
+ MediaPayloadVector getDefaultVideoPayloads() final { return MediaPayloadVector(); }
+ MediaPayloadVector filterPayloads(const MediaPayloadVector&, const MediaPayloadVector&) final { return MediaPayloadVector(); }
+
+ UpdateResult updateReceiveConfiguration(MediaEndpointSessionConfiguration*, bool) final { return UpdateResult::Failed; }
+ UpdateResult updateSendConfiguration(MediaEndpointSessionConfiguration*, const RealtimeMediaSourceMap&, bool) final { return UpdateResult::Failed; }
+
+ void addRemoteCandidate(const IceCandidate&, const String&, const String&, const String&) final { }
+
+ Ref<RealtimeMediaSource> createMutedRemoteSource(const String&, RealtimeMediaSource::Type) final { return EmptyRealtimeMediaSource::create(); }
+ void replaceSendSource(RealtimeMediaSource&, const String&) final { }
+ void replaceMutedRemoteSourceMid(const String&, const String&) final { };
+
+ std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) final { return nullptr; }
+ void stop() final { }
+};
+
+static std::unique_ptr<MediaEndpoint> createMediaEndpoint(MediaEndpointClient&)
+{
+ return std::make_unique<EmptyMediaEndpoint>();
+}
+
+CreateMediaEndpoint MediaEndpoint::create = createMediaEndpoint;
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/MediaEndpoint.h b/Source/WebCore/platform/mediastream/MediaEndpoint.h
new file mode 100644
index 000000000..94bbe1036
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/MediaEndpoint.h
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "MediaEndpointConfiguration.h"
+#include "PeerConnectionBackend.h"
+#include "RealtimeMediaSource.h"
+#include <wtf/HashMap.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class MediaEndpoint;
+class MediaEndpointClient;
+class MediaEndpointSessionConfiguration;
+class MediaStreamTrack;
+class RTCDataChannelHandler;
+class RealtimeMediaSource;
+
+struct IceCandidate;
+struct MediaPayload;
+struct RTCDataChannelInit;
+
+typedef std::unique_ptr<MediaEndpoint> (*CreateMediaEndpoint)(MediaEndpointClient&);
+typedef Vector<MediaPayload> MediaPayloadVector;
+typedef HashMap<String, RealtimeMediaSource*> RealtimeMediaSourceMap;
+
+class MediaEndpoint {
+public:
+ WEBCORE_EXPORT static CreateMediaEndpoint create;
+ virtual ~MediaEndpoint() { }
+
+ enum class UpdateResult {
+ Success,
+ SuccessWithIceRestart,
+ Failed
+ };
+
+ using IceTransportState = PeerConnectionStates::IceTransportState;
+
+ virtual void setConfiguration(MediaEndpointConfiguration&&) = 0;
+
+ virtual void generateDtlsInfo() = 0;
+ virtual MediaPayloadVector getDefaultAudioPayloads() = 0;
+ virtual MediaPayloadVector getDefaultVideoPayloads() = 0;
+ virtual MediaPayloadVector filterPayloads(const MediaPayloadVector& remotePayloads, const MediaPayloadVector& defaultPayloads) = 0;
+
+ virtual UpdateResult updateReceiveConfiguration(MediaEndpointSessionConfiguration*, bool isInitiator) = 0;
+ virtual UpdateResult updateSendConfiguration(MediaEndpointSessionConfiguration*, const RealtimeMediaSourceMap&, bool isInitiator) = 0;
+
+ virtual void addRemoteCandidate(const IceCandidate&, const String& mid, const String& ufrag, const String& password) = 0;
+
+ virtual Ref<RealtimeMediaSource> createMutedRemoteSource(const String& mid, RealtimeMediaSource::Type) = 0;
+ virtual void replaceSendSource(RealtimeMediaSource&, const String& mid) = 0;
+ virtual void replaceMutedRemoteSourceMid(const String& oldMid, const String& newMid) = 0;
+
+ virtual std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) = 0;
+
+ virtual void stop() = 0;
+
+ virtual void emulatePlatformEvent(const String&) { };
+
+ virtual void getStats(MediaStreamTrack*, PeerConnection::StatsPromise&& promise) { promise.reject(NOT_SUPPORTED_ERR); }
+};
+
+class MediaEndpointClient {
+public:
+ virtual void gotDtlsFingerprint(const String& fingerprint, const String& fingerprintFunction) = 0;
+ virtual void gotIceCandidate(const String& mid, IceCandidate&&) = 0;
+ virtual void doneGatheringCandidates(const String& mid) = 0;
+ virtual void iceTransportStateChanged(const String& mid, MediaEndpoint::IceTransportState) = 0;
+
+ virtual ~MediaEndpointClient() { }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.cpp b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.cpp
new file mode 100644
index 000000000..c2da344aa
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.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 "MediaEndpointConfiguration.h"
+
+#if ENABLE(WEB_RTC)
+
+namespace WebCore {
+
+MediaEndpointConfiguration::MediaEndpointConfiguration(Vector<IceServerInfo>&& iceServers, IceTransportPolicy iceTransportPolicy, BundlePolicy bundlePolicy)
+ : iceServers(WTFMove(iceServers))
+ , iceTransportPolicy(iceTransportPolicy)
+ , bundlePolicy(bundlePolicy)
+{
+}
+
+MediaEndpointConfiguration::IceServerInfo::IceServerInfo(Vector<URL>&& urls, const String& credential, const String& username)
+ : urls(WTFMove(urls))
+ , credential(credential)
+ , username(username)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/gstreamer/MediaStreamCenterGStreamer.h b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h
index a70e0019e..5b74a26a3 100644
--- a/Source/WebCore/platform/mediastream/gstreamer/MediaStreamCenterGStreamer.h
+++ b/Source/WebCore/platform/mediastream/MediaEndpointConfiguration.h
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2012 Google 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
@@ -29,34 +28,37 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamCenterGStreamer_h
-#define MediaStreamCenterGStreamer_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include "MediaStreamCenter.h"
-
-#include <wtf/PassRefPtr.h>
+#include "PeerConnectionStates.h"
+#include "URL.h"
+#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
-class MediaStreamPrivate;
-class MediaStreamSource;
-class MediaStreamSourcesQueryClient;
+struct MediaEndpointConfiguration {
+ // FIXME: We might be able to remove these constructors once all compilers can handle without it (see https://bugs.webkit.org/show_bug.cgi?id=163255#c15)
+ struct IceServerInfo {
+ Vector<URL> urls;
+ String credential;
+ String username;
+
+ IceServerInfo(Vector<URL>&&, const String&, const String&);
+ };
-class MediaStreamCenterGStreamer : public MediaStreamCenter {
-public:
- MediaStreamCenterGStreamer();
- ~MediaStreamCenterGStreamer();
+ using IceTransportPolicy = PeerConnectionStates::IceTransportPolicy;
+ using BundlePolicy = PeerConnectionStates::BundlePolicy;
- virtual void validateRequestConstraints(PassRefPtr<MediaStreamCreationClient>, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints);
- virtual void createMediaStream(PassRefPtr<MediaStreamCreationClient>, PassRefPtr<MediaConstraints> audioConstraints, PassRefPtr<MediaConstraints> videoConstraints);
- virtual bool getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequestClient>) override;
+ MediaEndpointConfiguration(Vector<IceServerInfo>&&, IceTransportPolicy, BundlePolicy);
+
+ Vector<IceServerInfo> iceServers;
+ IceTransportPolicy iceTransportPolicy;
+ BundlePolicy bundlePolicy;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamCenterGStreamer_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/MediaEndpointSessionConfiguration.h b/Source/WebCore/platform/mediastream/MediaEndpointSessionConfiguration.h
new file mode 100644
index 000000000..293cc82ee
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/MediaEndpointSessionConfiguration.h
@@ -0,0 +1,86 @@
+/*
+ * 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 MediaEndpointSessionConfiguration_h
+#define MediaEndpointSessionConfiguration_h
+
+#if ENABLE(WEB_RTC)
+
+#include "PeerMediaDescription.h"
+#include <wtf/CryptographicallyRandomNumber.h>
+
+namespace WebCore {
+
+class MediaEndpointSessionConfiguration : public RefCounted<MediaEndpointSessionConfiguration> {
+public:
+ static RefPtr<MediaEndpointSessionConfiguration> create()
+ {
+ return adoptRef(new MediaEndpointSessionConfiguration());
+ }
+ virtual ~MediaEndpointSessionConfiguration() { }
+
+ 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; }
+
+ Vector<PeerMediaDescription>& mediaDescriptions() { return m_mediaDescriptions; }
+ const Vector<PeerMediaDescription>& mediaDescriptions() const { return m_mediaDescriptions; }
+ void addMediaDescription(PeerMediaDescription&& description) { m_mediaDescriptions.append(WTFMove(description)); }
+
+ RefPtr<MediaEndpointSessionConfiguration> clone() const
+ {
+ RefPtr<MediaEndpointSessionConfiguration> copy = create();
+ copy->m_sessionId = m_sessionId;
+ copy->m_sessionVersion = m_sessionVersion;
+ copy->m_mediaDescriptions = m_mediaDescriptions;
+
+ return copy;
+ }
+
+private:
+ MediaEndpointSessionConfiguration()
+ {
+ m_sessionId = cryptographicallyRandomNumber();
+ m_sessionId = m_sessionId << 32 | cryptographicallyRandomNumber();
+ }
+
+ uint64_t m_sessionId;
+ unsigned m_sessionVersion { 0 };
+
+ Vector<PeerMediaDescription> m_mediaDescriptions;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
+
+#endif // MediaEndpointSessionConfiguration_h
diff --git a/Source/WebCore/platform/mediastream/MediaPayload.h b/Source/WebCore/platform/mediastream/MediaPayload.h
new file mode 100644
index 000000000..1229e108e
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/MediaPayload.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.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+struct MediaPayload {
+public:
+ void addParameter(const String& name, unsigned value) { parameters.set(name, value); }
+
+ unsigned type { 0 };
+ String encodingName;
+ unsigned clockRate { 0 };
+
+ // audio
+ unsigned channels { 0 };
+
+ // video
+ bool ccmfir { false };
+ bool nackpli { false };
+ bool nack { false };
+
+ HashMap<String, unsigned> parameters;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/MediaStreamConstraintsValidationClient.h b/Source/WebCore/platform/mediastream/MediaStreamConstraintsValidationClient.h
index 578705867..973c9eee1 100644
--- a/Source/WebCore/platform/mediastream/MediaStreamConstraintsValidationClient.h
+++ b/Source/WebCore/platform/mediastream/MediaStreamConstraintsValidationClient.h
@@ -10,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * 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 COMPUTER, INC. OR
+ * 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
@@ -28,8 +28,7 @@
#if ENABLE(MEDIA_STREAM)
-#include "MediaStreamSource.h"
-#include <wtf/PassRefPtr.h>
+#include "RealtimeMediaSource.h"
#include <wtf/RefCounted.h>
namespace WebCore {
diff --git a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp
index e7140ad23..21c0769a6 100644
--- a/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp
+++ b/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp
@@ -1,7 +1,8 @@
/*
- * 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).
+ * Copyright (C) 2015 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
@@ -31,174 +32,292 @@
*/
#include "config.h"
+#include "MediaStreamPrivate.h"
#if ENABLE(MEDIA_STREAM)
-#include "MediaStreamPrivate.h"
-
-#include "MediaStreamCenter.h"
+#include "GraphicsContext.h"
+#include "IntRect.h"
#include "UUID.h"
+#include <wtf/MainThread.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
namespace WebCore {
-PassRefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<MediaStreamSource>>& audioSources, const Vector<RefPtr<MediaStreamSource>>& videoSources)
+Ref<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<Ref<RealtimeMediaSource>>& audioSources, const Vector<Ref<RealtimeMediaSource>>& videoSources)
{
- return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), audioSources, videoSources));
+ MediaStreamTrackPrivateVector tracks;
+ tracks.reserveInitialCapacity(audioSources.size() + videoSources.size());
+
+ for (auto& source : audioSources)
+ tracks.uncheckedAppend(MediaStreamTrackPrivate::create(source.copyRef()));
+
+ for (auto& source : videoSources)
+ tracks.uncheckedAppend(MediaStreamTrackPrivate::create(source.copyRef()));
+
+ return MediaStreamPrivate::create(tracks);
}
-PassRefPtr<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks)
+Ref<MediaStreamPrivate> MediaStreamPrivate::create(const MediaStreamTrackPrivateVector& tracks)
{
- return adoptRef(new MediaStreamPrivate(createCanonicalUUIDString(), audioPrivateTracks, videoPrivateTracks));
+ return adoptRef(*new MediaStreamPrivate(createCanonicalUUIDString(), tracks));
}
-void MediaStreamPrivate::addSource(PassRefPtr<MediaStreamSource> prpSource)
+MediaStreamPrivate::MediaStreamPrivate(const String& id, const MediaStreamTrackPrivateVector& tracks)
+ : m_weakPtrFactory(this)
+ , m_id(id)
{
- RefPtr<MediaStreamSource> source = prpSource;
- switch (source->type()) {
- case MediaStreamSource::Audio:
- if (m_audioStreamSources.find(source) == notFound)
- m_audioStreamSources.append(source);
- break;
- case MediaStreamSource::Video:
- if (m_videoStreamSources.find(source) == notFound)
- m_videoStreamSources.append(source);
- break;
- case MediaStreamSource::None:
- ASSERT_NOT_REACHED();
- break;
+ ASSERT(!m_id.isEmpty());
+
+ for (auto& track : tracks) {
+ track->addObserver(*this);
+ m_trackSet.add(track->id(), track);
}
+
+ updateActiveState(NotifyClientOption::DontNotify);
}
-void MediaStreamPrivate::removeSource(PassRefPtr<MediaStreamSource> source)
+MediaStreamPrivate::~MediaStreamPrivate()
{
- size_t pos = notFound;
- switch (source->type()) {
- case MediaStreamSource::Audio:
- pos = m_audioStreamSources.find(source);
- if (pos == notFound)
- return;
- m_audioStreamSources.remove(pos);
- break;
- case MediaStreamSource::Video:
- pos = m_videoStreamSources.find(source);
- if (pos == notFound)
- return;
- m_videoStreamSources.remove(pos);
- break;
- case MediaStreamSource::None:
- ASSERT_NOT_REACHED();
- break;
+ for (auto& track : m_trackSet.values())
+ track->removeObserver(*this);
+}
+
+void MediaStreamPrivate::addObserver(MediaStreamPrivate::Observer& observer)
+{
+ m_observers.append(&observer);
+}
+
+void MediaStreamPrivate::removeObserver(MediaStreamPrivate::Observer& observer)
+{
+ size_t pos = m_observers.find(&observer);
+ if (pos != notFound)
+ m_observers.remove(pos);
+}
+
+MediaStreamTrackPrivateVector MediaStreamPrivate::tracks() const
+{
+ MediaStreamTrackPrivateVector tracks;
+ tracks.reserveCapacity(m_trackSet.size());
+ copyValuesToVector(m_trackSet, tracks);
+
+ return tracks;
+}
+
+void MediaStreamPrivate::updateActiveState(NotifyClientOption notifyClientOption)
+{
+ bool newActiveState = false;
+ for (auto& track : m_trackSet.values()) {
+ if (!track->ended()) {
+ newActiveState = true;
+ break;
+ }
+ }
+
+ updateActiveVideoTrack();
+
+ // A stream is active if it has at least one un-ended track.
+ if (newActiveState == m_isActive)
+ return;
+
+ m_isActive = newActiveState;
+
+ if (notifyClientOption == NotifyClientOption::Notify) {
+ for (auto& observer : m_observers)
+ observer->activeStatusChanged();
}
}
-void MediaStreamPrivate::addRemoteSource(MediaStreamSource* source)
+void MediaStreamPrivate::addTrack(RefPtr<MediaStreamTrackPrivate>&& track, NotifyClientOption notifyClientOption)
{
- if (m_client)
- m_client->addRemoteSource(source);
- else
- addSource(source);
+ if (m_trackSet.contains(track->id()))
+ return;
+
+ track->addObserver(*this);
+ m_trackSet.add(track->id(), track);
+
+ if (notifyClientOption == NotifyClientOption::Notify) {
+ for (auto& observer : m_observers)
+ observer->didAddTrack(*track.get());
+ }
+
+ updateActiveState(notifyClientOption);
}
-void MediaStreamPrivate::removeRemoteSource(MediaStreamSource* source)
+void MediaStreamPrivate::removeTrack(MediaStreamTrackPrivate& track, NotifyClientOption notifyClientOption)
{
- if (m_client)
- m_client->removeRemoteSource(source);
- else
- removeSource(source);
+ if (!m_trackSet.remove(track.id()))
+ return;
+
+ track.removeObserver(*this);
+
+ if (notifyClientOption == NotifyClientOption::Notify) {
+ for (auto& observer : m_observers)
+ observer->didRemoveTrack(track);
+ }
+
+ updateActiveState(NotifyClientOption::Notify);
}
-void MediaStreamPrivate::addRemoteTrack(MediaStreamTrackPrivate* track)
+void MediaStreamPrivate::startProducingData()
{
- if (m_client)
- m_client->addRemoteTrack(track);
- else
- addTrack(track);
+ for (auto& track : m_trackSet.values())
+ track->startProducingData();
}
-void MediaStreamPrivate::removeRemoteTrack(MediaStreamTrackPrivate* track)
+void MediaStreamPrivate::stopProducingData()
{
- if (m_client)
- m_client->removeRemoteTrack(track);
- else
- removeTrack(track);
+ for (auto& track : m_trackSet.values())
+ track->stopProducingData();
}
-MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamSource>>& audioSources, const Vector<RefPtr<MediaStreamSource>>& videoSources)
- : m_client(0)
- , m_id(id)
- , m_ended(false)
+bool MediaStreamPrivate::isProducingData() const
{
- ASSERT(m_id.length());
- for (size_t i = 0; i < audioSources.size(); i++)
- addTrack(MediaStreamTrackPrivate::create(audioSources[i]));
+ for (auto& track : m_trackSet.values()) {
+ if (track->isProducingData())
+ return true;
+ }
+ return false;
+}
- for (size_t i = 0; i < videoSources.size(); i++)
- addTrack(MediaStreamTrackPrivate::create(videoSources[i]));
+bool MediaStreamPrivate::hasVideo() const
+{
+ for (auto& track : m_trackSet.values()) {
+ if (track->type() == RealtimeMediaSource::Type::Video && track->enabled() && !track->ended())
+ return true;
+ }
+ return false;
+}
- unsigned providedSourcesSize = audioSources.size() + videoSources.size();
- unsigned tracksSize = m_audioPrivateTracks.size() + m_videoPrivateTracks.size();
- // If sources were provided and no track was added to the MediaStreamPrivate's tracks, this means
- // that the tracks were all ended
- if (providedSourcesSize > 0 && !tracksSize)
- m_ended = true;
+bool MediaStreamPrivate::hasAudio() const
+{
+ for (auto& track : m_trackSet.values()) {
+ if (track->type() == RealtimeMediaSource::Type::Audio && track->enabled() && !track->ended())
+ return true;
+ }
+ return false;
}
-MediaStreamPrivate::MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks)
- : m_client(0)
- , m_id(id)
- , m_ended(false)
+bool MediaStreamPrivate::hasLocalVideoSource() const
{
- ASSERT(m_id.length());
- for (size_t i = 0; i < audioPrivateTracks.size(); i++)
- addTrack(audioPrivateTracks[i]);
+ for (auto& track : m_trackSet.values()) {
+ if (track->type() == RealtimeMediaSource::Type::Video && !track->remote())
+ return true;
+ }
+ return false;
+}
- for (size_t i = 0; i < videoPrivateTracks.size(); i++)
- addTrack(videoPrivateTracks[i]);
+bool MediaStreamPrivate::hasLocalAudioSource() const
+{
+ for (auto& track : m_trackSet.values()) {
+ if (track->type() == RealtimeMediaSource::Type::Audio && !track->remote())
+ return true;
+ }
+ return false;
+}
- unsigned providedTracksSize = audioPrivateTracks.size() + videoPrivateTracks.size();
- unsigned tracksSize = m_audioPrivateTracks.size() + m_videoPrivateTracks.size();
- // If tracks were provided and no one was added to the MediaStreamPrivate's tracks, this means
- // that the tracks were all ended
- if (providedTracksSize > 0 && !tracksSize)
- m_ended = true;
+bool MediaStreamPrivate::muted() const
+{
+ for (auto& track : m_trackSet.values()) {
+ if (!track->muted())
+ return false;
+ }
+ return true;
}
-void MediaStreamPrivate::setEnded()
+FloatSize MediaStreamPrivate::intrinsicSize() const
{
- if (m_client)
- m_client->streamDidEnd();
+ FloatSize size;
+
+ if (m_activeVideoTrack) {
+ const RealtimeMediaSourceSettings& setting = m_activeVideoTrack->settings();
+ size.setWidth(setting.width());
+ size.setHeight(setting.height());
+ }
- m_ended = true;
+ return size;
}
-void MediaStreamPrivate::addTrack(PassRefPtr<MediaStreamTrackPrivate> prpTrack)
+void MediaStreamPrivate::paintCurrentFrameInContext(GraphicsContext& context, const FloatRect& rect)
{
- RefPtr<MediaStreamTrackPrivate> track = prpTrack;
- if (track->ended())
+ if (context.paintingDisabled())
return;
- Vector<RefPtr<MediaStreamTrackPrivate>>& tracks = track->type() == MediaStreamSource::Audio ? m_audioPrivateTracks : m_videoPrivateTracks;
+ if (active() && m_activeVideoTrack)
+ m_activeVideoTrack->paintCurrentFrameInContext(context, rect);
+ else {
+ GraphicsContextStateSaver stateSaver(context);
+ context.translate(rect.x(), rect.y() + rect.height());
+ context.scale(FloatSize(1, -1));
+ IntRect paintRect(IntPoint(0, 0), IntSize(rect.width(), rect.height()));
+ context.fillRect(paintRect, Color::black);
+ }
+}
- size_t pos = tracks.find(track);
- if (pos != notFound)
- return;
+RefPtr<Image> MediaStreamPrivate::currentFrameImage()
+{
+ if (!active() || !m_activeVideoTrack)
+ return nullptr;
- tracks.append(track);
- if (track->source())
- addSource(track->source());
+ return m_activeVideoTrack->source().currentFrameImage();
}
-void MediaStreamPrivate::removeTrack(PassRefPtr<MediaStreamTrackPrivate> track)
+void MediaStreamPrivate::updateActiveVideoTrack()
{
- Vector<RefPtr<MediaStreamTrackPrivate>>& tracks = track->type() == MediaStreamSource::Audio ? m_audioPrivateTracks : m_videoPrivateTracks;
+ m_activeVideoTrack = nullptr;
+ for (auto& track : m_trackSet.values()) {
+ if (!track->ended() && track->type() == RealtimeMediaSource::Type::Video) {
+ m_activeVideoTrack = track.get();
+ break;
+ }
+ }
+}
- size_t pos = tracks.find(track);
- if (pos == notFound)
- return;
+void MediaStreamPrivate::characteristicsChanged()
+{
+ for (auto& observer : m_observers)
+ observer->characteristicsChanged();
+}
+
+void MediaStreamPrivate::trackMutedChanged(MediaStreamTrackPrivate&)
+{
+ scheduleDeferredTask([this] {
+ characteristicsChanged();
+ });
+}
+
+void MediaStreamPrivate::trackSettingsChanged(MediaStreamTrackPrivate&)
+{
+ characteristicsChanged();
+}
+
+void MediaStreamPrivate::trackEnabledChanged(MediaStreamTrackPrivate&)
+{
+ updateActiveVideoTrack();
+
+ scheduleDeferredTask([this] {
+ characteristicsChanged();
+ });
+}
+
+void MediaStreamPrivate::trackEnded(MediaStreamTrackPrivate&)
+{
+ scheduleDeferredTask([this] {
+ updateActiveState(NotifyClientOption::Notify);
+ characteristicsChanged();
+ });
+}
+
+void MediaStreamPrivate::scheduleDeferredTask(Function<void ()>&& function)
+{
+ ASSERT(function);
+ callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
+ if (!weakThis)
+ return;
- tracks.remove(pos);
+ function();
+ });
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/mediastream/MediaStreamPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamPrivate.h
index f1617aa4c..a4596ff59 100644
--- a/Source/WebCore/platform/mediastream/MediaStreamPrivate.h
+++ b/Source/WebCore/platform/mediastream/MediaStreamPrivate.h
@@ -1,7 +1,8 @@
/*
- * 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).
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,78 +36,107 @@
#if ENABLE(MEDIA_STREAM)
-#include "MediaStreamSource.h"
+#include "FloatSize.h"
#include "MediaStreamTrack.h"
#include "MediaStreamTrackPrivate.h"
+#include <wtf/Function.h>
+#include <wtf/HashMap.h>
+#include <wtf/MediaTime.h>
#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
+
+#if USE(GSTREAMER)
+#include "GRefPtrGStreamer.h"
+#include <owr/owr_gst_video_renderer.h>
+#endif
namespace WebCore {
-class MediaStreamTrackPrivate;
+class MediaStream;
-class MediaStreamPrivateClient : public MediaStreamTrack::Observer {
+class MediaStreamPrivate : public MediaStreamTrackPrivate::Observer, public RefCounted<MediaStreamPrivate> {
public:
- virtual ~MediaStreamPrivateClient() { }
+ class Observer {
+ public:
+ virtual ~Observer() { }
- virtual void streamDidEnd() = 0;
- virtual void addRemoteSource(MediaStreamSource*) = 0;
- virtual void removeRemoteSource(MediaStreamSource*) = 0;
- virtual void addRemoteTrack(MediaStreamTrackPrivate*) = 0;
- virtual void removeRemoteTrack(MediaStreamTrackPrivate*) = 0;
-};
+ virtual void characteristicsChanged() { }
+ virtual void activeStatusChanged() { }
+ virtual void didAddTrack(MediaStreamTrackPrivate&) { }
+ virtual void didRemoveTrack(MediaStreamTrackPrivate&) { }
+ };
-class MediaStreamPrivate : public RefCounted<MediaStreamPrivate> {
-public:
- static PassRefPtr<MediaStreamPrivate> create(const Vector<RefPtr<MediaStreamSource>>& audioSources, const Vector<RefPtr<MediaStreamSource>>& videoSources);
- static PassRefPtr<MediaStreamPrivate> create(const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks);
+ static Ref<MediaStreamPrivate> create(const Vector<Ref<RealtimeMediaSource>>& audioSources, const Vector<Ref<RealtimeMediaSource>>& videoSources);
+ static Ref<MediaStreamPrivate> create(const MediaStreamTrackPrivateVector&);
- virtual ~MediaStreamPrivate() { }
+ virtual ~MediaStreamPrivate();
- MediaStreamPrivateClient* client() const { return m_client; }
- void setClient(MediaStreamPrivateClient* client) { m_client = client; }
+ enum class NotifyClientOption { Notify, DontNotify };
+
+ void addObserver(Observer&);
+ void removeObserver(Observer&);
String id() const { return m_id; }
- unsigned numberOfAudioSources() const { return m_audioStreamSources.size(); }
- MediaStreamSource* audioSources(unsigned index) const { return m_audioStreamSources[index].get(); }
+ MediaStreamTrackPrivateVector tracks() const;
+ MediaStreamTrackPrivate* activeVideoTrack() { return m_activeVideoTrack; }
+
+ bool active() const { return m_isActive; }
+ void updateActiveState(NotifyClientOption);
- unsigned numberOfVideoSources() const { return m_videoStreamSources.size(); }
- MediaStreamSource* videoSources(unsigned index) const { return m_videoStreamSources[index].get(); }
+ void addTrack(RefPtr<MediaStreamTrackPrivate>&&, NotifyClientOption = NotifyClientOption::Notify);
+ void removeTrack(MediaStreamTrackPrivate&, NotifyClientOption = NotifyClientOption::Notify);
- unsigned numberOfAudioTracks() const { return m_audioPrivateTracks.size(); }
- MediaStreamTrackPrivate* audioTracks(unsigned index) const { return m_audioPrivateTracks[index].get(); }
+ void startProducingData();
+ void stopProducingData();
+ bool isProducingData() const;
- unsigned numberOfVideoTracks() const { return m_videoPrivateTracks.size(); }
- MediaStreamTrackPrivate* videoTracks(unsigned index) const { return m_videoPrivateTracks[index].get(); }
+ RefPtr<Image> currentFrameImage();
+ void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&);
- void addSource(PassRefPtr<MediaStreamSource>);
- void removeSource(PassRefPtr<MediaStreamSource>);
+ bool hasVideo() const;
+ bool hasAudio() const;
+ bool muted() const;
- void addRemoteSource(MediaStreamSource*);
- void removeRemoteSource(MediaStreamSource*);
+ bool hasLocalVideoSource() const;
+ bool hasLocalAudioSource() const;
- bool ended() const { return m_ended; }
- void setEnded();
+ FloatSize intrinsicSize() const;
- void addTrack(PassRefPtr<MediaStreamTrackPrivate>);
- void removeTrack(PassRefPtr<MediaStreamTrackPrivate>);
+ WeakPtr<MediaStreamPrivate> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
- void addRemoteTrack(MediaStreamTrackPrivate*);
- void removeRemoteTrack(MediaStreamTrackPrivate*);
+#if USE(GSTREAMER)
+ void setVideoRenderer(OwrGstVideoRenderer* renderer, GstElement* sink) { m_gstVideoRenderer = renderer; m_gstVideoSinkElement = sink; }
+ GRefPtr<GstElement> getVideoSinkElement() const { return m_gstVideoSinkElement; }
+ GRefPtr<OwrGstVideoRenderer> getVideoRenderer() const { return m_gstVideoRenderer; }
private:
- MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamSource>>& audioSources, const Vector<RefPtr<MediaStreamSource>>& videoSources);
- MediaStreamPrivate(const String& id, const Vector<RefPtr<MediaStreamTrackPrivate>>& audioPrivateTracks, const Vector<RefPtr<MediaStreamTrackPrivate>>& videoPrivateTracks);
+ GRefPtr<GstElement> m_gstVideoSinkElement;
+ GRefPtr<OwrGstVideoRenderer> m_gstVideoRenderer;
+#endif
- MediaStreamPrivateClient* m_client;
- String m_id;
- Vector<RefPtr<MediaStreamSource>> m_audioStreamSources;
- Vector<RefPtr<MediaStreamSource>> m_videoStreamSources;
+private:
+ MediaStreamPrivate(const String&, const MediaStreamTrackPrivateVector&);
+
+ // MediaStreamTrackPrivate::Observer
+ void trackEnded(MediaStreamTrackPrivate&) override;
+ void trackMutedChanged(MediaStreamTrackPrivate&) override;
+ void trackSettingsChanged(MediaStreamTrackPrivate&) override;
+ void trackEnabledChanged(MediaStreamTrackPrivate&) override;
+
+ void characteristicsChanged();
+ void updateActiveVideoTrack();
- Vector<RefPtr<MediaStreamTrackPrivate>> m_audioPrivateTracks;
- Vector<RefPtr<MediaStreamTrackPrivate>> m_videoPrivateTracks;
- bool m_ended;
+ void scheduleDeferredTask(Function<void ()>&&);
+
+ WeakPtrFactory<MediaStreamPrivate> m_weakPtrFactory;
+ Vector<Observer*> m_observers;
+ String m_id;
+ MediaStreamTrackPrivate* m_activeVideoTrack { nullptr };
+ HashMap<String, RefPtr<MediaStreamTrackPrivate>> m_trackSet;
+ bool m_isActive { false };
};
typedef Vector<RefPtr<MediaStreamPrivate>> MediaStreamPrivateVector;
diff --git a/Source/WebCore/platform/mediastream/MediaStreamSource.cpp b/Source/WebCore/platform/mediastream/MediaStreamSource.cpp
deleted file mode 100644
index ce089e623..000000000
--- a/Source/WebCore/platform/mediastream/MediaStreamSource.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * 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).
- *
- * 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 Google Inc. 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 "MediaStreamSource.h"
-
-#include "MediaStreamCenter.h"
-#include "MediaStreamSourceCapabilities.h"
-#include "UUID.h"
-
-namespace WebCore {
-
-MediaStreamSource::MediaStreamSource(const String& id, Type type, const String& name)
- : m_id(id)
- , m_type(type)
- , m_name(name)
- , m_readyState(New)
- , m_enabled(true)
- , m_muted(false)
- , m_readonly(false)
- , m_remote(false)
-{
- if (!m_id.isEmpty())
- return;
-
- m_id = createCanonicalUUIDString();
-}
-
-void MediaStreamSource::reset()
-{
- m_readyState = New;
- m_enabled = true;
- m_muted = false;
- m_readonly = false;
- m_remote = false;
-}
-
-void MediaStreamSource::setReadyState(ReadyState readyState)
-{
- if (m_readyState == Ended || m_readyState == readyState)
- return;
-
- m_readyState = readyState;
- 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();
-}
-
-void MediaStreamSource::addObserver(MediaStreamSource::Observer* observer)
-{
- m_observers.append(observer);
-}
-
-void MediaStreamSource::removeObserver(MediaStreamSource::Observer* observer)
-{
- size_t pos = m_observers.find(observer);
- if (pos != notFound)
- m_observers.remove(pos);
-
- if (!m_observers.size())
- stop();
-}
-
-void MediaStreamSource::setMuted(bool muted)
-{
- if (m_muted == muted)
- return;
-
- m_muted = muted;
-
- if (m_readyState == Ended)
- return;
-
- for (auto observer = m_observers.begin(); observer != m_observers.end(); ++observer)
- (*observer)->sourceMutedChanged();
-}
-
-void MediaStreamSource::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 MediaStreamSource::readonly() const
-{
- return m_readonly;
-}
-
-void MediaStreamSource::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);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/MediaStreamSource.h b/Source/WebCore/platform/mediastream/MediaStreamSource.h
deleted file mode 100644
index d6655725c..000000000
--- a/Source/WebCore/platform/mediastream/MediaStreamSource.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * 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).
- *
- * 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 MediaStreamSource_h
-#define MediaStreamSource_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaConstraints.h"
-#include "MediaStreamSourceCapabilities.h"
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class AudioBus;
-class MediaConstraints;
-class MediaStreamPrivate;
-class MediaStreamSourceStates;
-
-class MediaStreamSource : public RefCounted<MediaStreamSource> {
-public:
- class Observer {
- public:
- virtual ~Observer() { }
-
- // Source state changes.
- virtual void sourceReadyStateChanged() = 0;
- virtual void sourceMutedChanged() = 0;
- virtual void sourceEnabledChanged() = 0;
-
- // Observer state queries.
- virtual bool observerIsEnabled() = 0;
- };
-
- virtual ~MediaStreamSource() { }
-
- bool isAudioStreamSource() const { return type() == Audio; }
- virtual bool useIDForTrackID() const { return false; }
-
- const String& id() const { return m_id; }
-
- enum Type { None, Audio, Video };
- Type type() const { return m_type; }
-
- virtual const String& name() const { return m_name; }
- virtual void setName(const String& name) { m_name = name; }
-
- virtual RefPtr<MediaStreamSourceCapabilities> capabilities() const = 0;
- virtual const MediaStreamSourceStates& states() = 0;
-
- enum ReadyState { New = 0, Live = 1, Ended = 2 };
- 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);
-
- virtual bool readonly() const;
- virtual void setReadonly(bool readonly) { m_readonly = readonly; }
-
- virtual bool remote() const { return m_remote; }
- virtual void setRemote(bool remote) { m_remote = remote; }
-
- void addObserver(Observer*);
- void removeObserver(Observer*);
-
- virtual void startProducingData() { }
- virtual void stopProducingData() { }
-
- void stop();
-
- void reset();
-
-protected:
- MediaStreamSource(const String& id, Type, const String& name);
-
-private:
- String m_id;
- Type m_type;
- String m_name;
- ReadyState m_readyState;
- Vector<Observer*> m_observers;
-
- bool m_enabled;
- bool m_muted;
- bool m_readonly;
- bool m_remote;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamSource_h
diff --git a/Source/WebCore/platform/mediastream/MediaStreamSourceCapabilities.h b/Source/WebCore/platform/mediastream/MediaStreamSourceCapabilities.h
deleted file mode 100644
index 64b0c4f0c..000000000
--- a/Source/WebCore/platform/mediastream/MediaStreamSourceCapabilities.h
+++ /dev/null
@@ -1,149 +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 COMPUTER, 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 COMPUTER, 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 MediaStreamSourceCapabilities_h
-#define MediaStreamSourceCapabilities_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamSourceStates.h"
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/AtomicString.h>
-
-namespace WebCore {
-
-class MediaStreamSourceCapabilityRange {
-public:
-
- MediaStreamSourceCapabilityRange(float min, float max, bool supported = true)
- : m_type(Float)
- {
- m_min.asFloat = min;
- m_max.asFloat = max;
- m_supported = supported;
- }
-
- MediaStreamSourceCapabilityRange(unsigned long min, unsigned long max, bool supported = true)
- : m_type(ULong)
- {
- m_min.asULong = min;
- m_max.asULong = max;
- m_supported = supported;
- }
-
- MediaStreamSourceCapabilityRange()
- {
- m_type = Undefined;
- m_min.asULong = 0;
- m_max.asULong = 0;
- m_supported = false;
- }
-
- enum Type { Undefined, Float, ULong };
-
- union ValueUnion {
- unsigned long asULong;
- float asFloat;
- };
-
- const ValueUnion& min() const { return m_min; }
- const ValueUnion& max() const { return m_max; }
- Type type() const { return m_type; }
- bool supported() const { return m_supported; }
-
-private:
- ValueUnion m_min;
- ValueUnion m_max;
- Type m_type;
- bool m_supported;
-};
-
-class MediaStreamSourceCapabilities : public RefCounted<MediaStreamSourceCapabilities> {
-public:
- static PassRefPtr<MediaStreamSourceCapabilities> create()
- {
- return adoptRef(new MediaStreamSourceCapabilities());
- }
-
- ~MediaStreamSourceCapabilities() { }
-
- const Vector<MediaStreamSourceStates::SourceType>& sourceTypes() { return m_sourceType; }
- void setSourceType(MediaStreamSourceStates::SourceType sourceType) { m_sourceType.resizeToFit(1); addSourceType(sourceType); }
- void addSourceType(MediaStreamSourceStates::SourceType sourceType)
- {
- if (sourceType == MediaStreamSourceStates::Camera)
- m_videoSource = true;
- m_sourceType.append(sourceType);
- }
-
- const Vector<AtomicString>& sourceId() { return m_sourceId; }
- void setSourceId(const AtomicString& id) { m_sourceId.reserveCapacity(1); m_sourceId.insert(0, id); }
-
- const Vector<MediaStreamSourceStates::VideoFacingMode>& facingModes() { return m_facingMode; }
- void addFacingMode(MediaStreamSourceStates::VideoFacingMode mode) { m_facingMode.append(mode); }
-
- const MediaStreamSourceCapabilityRange& width() { return m_width; }
- void setWidthRange(const MediaStreamSourceCapabilityRange& width) { m_width = width; }
-
- const MediaStreamSourceCapabilityRange& height() { return m_height; }
- void setHeightRange(const MediaStreamSourceCapabilityRange& height) { m_height = height; }
-
- const MediaStreamSourceCapabilityRange& frameRate() { return m_frameRate; }
- void setFrameRateRange(const MediaStreamSourceCapabilityRange& frameRate) { m_frameRate = frameRate; }
-
- const MediaStreamSourceCapabilityRange& aspectRatio() { return m_aspectRatio; }
- void setAspectRatioRange(const MediaStreamSourceCapabilityRange& aspectRatio) { m_aspectRatio = aspectRatio; }
-
- const MediaStreamSourceCapabilityRange& volume() { return m_volume; }
- void setVolumeRange(const MediaStreamSourceCapabilityRange& volume) { m_volume = volume; }
-
- bool hasVideoSource() { return m_videoSource; }
- void setHasVideoSource(bool isVideo) { m_videoSource = isVideo;; }
-
-private:
- MediaStreamSourceCapabilities()
- : m_videoSource(false)
- {
- }
-
- Vector<AtomicString> m_sourceId;
- Vector<MediaStreamSourceStates::SourceType> m_sourceType;
- Vector<MediaStreamSourceStates::VideoFacingMode> m_facingMode;
-
- MediaStreamSourceCapabilityRange m_width;
- MediaStreamSourceCapabilityRange m_height;
- MediaStreamSourceCapabilityRange m_frameRate;
- MediaStreamSourceCapabilityRange m_aspectRatio;
- MediaStreamSourceCapabilityRange m_volume;
-
- bool m_videoSource;
-};
-
-} // namespace WebCore
-
-#endif // MediaStreamSourceCapabilities_h
-
-#endif
diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp
index 6a86181b8..736c6f4c5 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
@@ -24,263 +25,192 @@
*/
#include "config.h"
+#include "MediaStreamTrackPrivate.h"
#if ENABLE(MEDIA_STREAM)
-#include "MediaStreamTrackPrivate.h"
-
-#include "MediaSourceStates.h"
-#include "MediaStreamCapabilities.h"
-#include "NotImplemented.h"
+#include "AudioSourceProvider.h"
+#include "GraphicsContext.h"
+#include "IntRect.h"
#include "UUID.h"
-#include <wtf/NeverDestroyed.h>
namespace WebCore {
-PassRefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(PassRefPtr<MediaStreamSource> source)
+Ref<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(Ref<RealtimeMediaSource>&& source)
{
- return adoptRef(new MediaStreamTrackPrivate(source));
+ return adoptRef(*new MediaStreamTrackPrivate(WTFMove(source), createCanonicalUUIDString()));
}
-MediaStreamTrackPrivate::MediaStreamTrackPrivate(const MediaStreamTrackPrivate& other)
- : RefCounted()
- , m_client(nullptr)
+Ref<MediaStreamTrackPrivate> MediaStreamTrackPrivate::create(Ref<RealtimeMediaSource>&& source, String&& id)
{
- m_ignoreMutations = true;
- m_id = createCanonicalUUIDString();
- setSource(other.source());
- m_readyState = other.readyState();
- m_muted = other.muted();
- m_enabled = other.enabled();
- m_stopped = other.stopped();
- m_ignoreMutations = false;
+ return adoptRef(*new MediaStreamTrackPrivate(WTFMove(source), WTFMove(id)));
}
-MediaStreamTrackPrivate::MediaStreamTrackPrivate(PassRefPtr<MediaStreamSource> source)
- : m_source(nullptr)
- , m_client(nullptr)
- , m_readyState(MediaStreamSource::New)
- , m_muted(false)
- , m_enabled(true)
- , m_stopped(false)
+MediaStreamTrackPrivate::MediaStreamTrackPrivate(Ref<RealtimeMediaSource>&& source, String&& id)
+ : m_source(WTFMove(source))
+ , m_id(WTFMove(id))
+ , m_isEnabled(true)
+ , m_isEnded(false)
{
- m_ignoreMutations = true;
- setSource(source);
- m_ignoreMutations = false;
+ m_source->addObserver(*this);
}
MediaStreamTrackPrivate::~MediaStreamTrackPrivate()
{
- if (m_source)
- m_source->removeObserver(this);
+ m_source->removeObserver(*this);
}
-void MediaStreamTrackPrivate::setSource(PassRefPtr<MediaStreamSource> source)
+void MediaStreamTrackPrivate::addObserver(MediaStreamTrackPrivate::Observer& observer)
{
- if (m_source)
- m_source->removeObserver(this);
-
- m_source = source;
-
- if (!m_source)
- return;
-
- setMuted(m_source->muted());
- setReadyState(m_source->readyState());
- if (m_source)
- m_source->addObserver(this);
+ m_observers.append(&observer);
}
-const String& MediaStreamTrackPrivate::id() const
+void MediaStreamTrackPrivate::removeObserver(MediaStreamTrackPrivate::Observer& observer)
{
- 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;
+ size_t pos = m_observers.find(&observer);
+ if (pos != notFound)
+ m_observers.remove(pos);
}
const String& MediaStreamTrackPrivate::label() const
{
- if (m_source)
- return m_source->name();
-
- return emptyString();
-}
-
-bool MediaStreamTrackPrivate::ended() const
-{
- return m_stopped || (m_source && m_source->readyState() == MediaStreamSource::Ended);
+ return m_source->name();
}
bool MediaStreamTrackPrivate::muted() const
{
- if (m_stopped || !m_source)
- return false;
-
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_stopped || !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_stopped || m_enabled == enabled)
+ if (m_isEnabled == 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.
- m_enabled = enabled;
-
- if (m_source)
- m_source->setEnabled(enabled);
+ // Always update the enabled state regardless of the track being ended.
+ m_isEnabled = enabled;
- if (!m_client || m_ignoreMutations)
- return;
+ m_source->setEnabled(enabled);
- m_client->trackEnabledChanged();
+ for (auto& observer : m_observers)
+ observer->trackEnabledChanged(*this);
}
-void MediaStreamTrackPrivate::stop(StopBehavior stopSource)
+void MediaStreamTrackPrivate::endTrack()
{
- if (m_stopped)
+ if (m_isEnded)
return;
- if (stopSource == StopTrackAndStopSource && m_source)
- m_source->stop();
+ // Set m_isEnded to true before telling the source it can stop, so if this is the
+ // only track using the source and it does stop, we will only call each observer's
+ // trackEnded method once.
+ m_isEnded = true;
- setReadyState(MediaStreamSource::Ended);
- m_stopped = true;
+ m_source->requestStop(this);
+
+ for (auto& observer : m_observers)
+ observer->trackEnded(*this);
}
-MediaStreamSource::ReadyState MediaStreamTrackPrivate::readyState() const
+Ref<MediaStreamTrackPrivate> MediaStreamTrackPrivate::clone()
{
- if (m_stopped)
- return MediaStreamSource::Ended;
+ auto clonedMediaStreamTrackPrivate = create(m_source.copyRef());
+ clonedMediaStreamTrackPrivate->m_isEnabled = this->m_isEnabled;
+ clonedMediaStreamTrackPrivate->m_isEnded = this->m_isEnded;
- return m_readyState;
+ return clonedMediaStreamTrackPrivate;
}
-void MediaStreamTrackPrivate::setReadyState(MediaStreamSource::ReadyState state)
+RealtimeMediaSource::Type MediaStreamTrackPrivate::type() const
{
- if (m_readyState == MediaStreamSource::Ended || m_readyState == state)
- return;
-
- MediaStreamSource::ReadyState oldState = m_readyState;
- m_readyState = state;
-
- if (!m_client || m_ignoreMutations)
- return;
-
- if ((m_readyState == MediaStreamSource::Live && oldState == MediaStreamSource::New) || m_readyState == MediaStreamSource::Ended)
- m_client->trackReadyStateChanged();
+ return m_source->type();
}
-RefPtr<MediaStreamTrackPrivate> MediaStreamTrackPrivate::clone()
+const RealtimeMediaSourceSettings& MediaStreamTrackPrivate::settings() const
{
- return adoptRef(new MediaStreamTrackPrivate(*this));
+ return m_source->settings();
}
-
-RefPtr<MediaConstraints> MediaStreamTrackPrivate::constraints() const
+RefPtr<RealtimeMediaSourceCapabilities> MediaStreamTrackPrivate::capabilities() const
{
- return m_constraints;
+ return m_source->capabilities();
}
-const MediaStreamSourceStates& MediaStreamTrackPrivate::states() const
+void MediaStreamTrackPrivate::paintCurrentFrameInContext(GraphicsContext& context, const FloatRect& rect)
{
- if (!m_source) {
- DEFINE_STATIC_LOCAL(const MediaStreamSourceStates, noState, ());
- return noState;
+ if (context.paintingDisabled() || m_source->type() != RealtimeMediaSource::Type::Video || ended())
+ return;
+
+ if (!m_source->muted())
+ m_source->paintCurrentFrameInContext(context, rect);
+ else {
+ GraphicsContextStateSaver stateSaver(context);
+ context.translate(rect.x(), rect.y() + rect.height());
+ IntRect paintRect(IntPoint(0, 0), IntSize(rect.width(), rect.height()));
+ context.fillRect(paintRect, Color::black);
}
-
- return m_source->states();
}
-MediaStreamSource::Type MediaStreamTrackPrivate::type() const
+void MediaStreamTrackPrivate::applyConstraints(const MediaConstraints& constraints, RealtimeMediaSource::SuccessHandler successHandler, RealtimeMediaSource::FailureHandler failureHandler)
{
- if (!m_source)
- return MediaStreamSource::None;
+ m_source->applyConstraints(constraints, successHandler, failureHandler);
+}
- return m_source->type();
+AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider()
+{
+ return m_source->audioSourceProvider();
}
-RefPtr<MediaStreamSourceCapabilities> MediaStreamTrackPrivate::capabilities() const
+void MediaStreamTrackPrivate::sourceStopped()
{
- if (!m_source)
- return 0;
+ if (m_isEnded)
+ return;
- return m_source->capabilities();
+ m_isEnded = true;
+
+ for (auto& observer : m_observers)
+ observer->trackEnded(*this);
}
-void MediaStreamTrackPrivate::applyConstraints(PassRefPtr<MediaConstraints>)
+void MediaStreamTrackPrivate::sourceMutedChanged()
{
- // FIXME: apply the new constraints to the track
- // https://bugs.webkit.org/show_bug.cgi?id=122428
+ for (auto& observer : m_observers)
+ observer->trackMutedChanged(*this);
}
-void MediaStreamTrackPrivate::sourceReadyStateChanged()
+void MediaStreamTrackPrivate::sourceEnabledChanged()
{
- if (stopped())
- return;
-
- setReadyState(m_source->readyState());
+ for (auto& observer : m_observers)
+ observer->trackEnabledChanged(*this);
}
-void MediaStreamTrackPrivate::sourceMutedChanged()
+void MediaStreamTrackPrivate::sourceSettingsChanged()
{
- if (stopped())
- return;
-
- setMuted(m_source->muted());
+ for (auto& observer : m_observers)
+ observer->trackSettingsChanged(*this);
}
-void MediaStreamTrackPrivate::sourceEnabledChanged()
+bool MediaStreamTrackPrivate::preventSourceFromStopping()
{
- if (stopped())
- return;
-
- setEnabled(m_source->enabled());
+ // Do not allow the source to stop if we are still using it.
+ return !m_isEnded;
}
-bool MediaStreamTrackPrivate::observerIsEnabled()
+void MediaStreamTrackPrivate::videoSampleAvailable(MediaSample& mediaSample)
{
- return enabled();
+ mediaSample.setTrackID(id());
+ for (auto& observer : m_observers)
+ observer->sampleBufferUpdated(*this, mediaSample);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h b/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h
index 5ea7a10b3..ca0d7c17d 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
@@ -23,101 +24,95 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef MediaStreamTrackPrivate_h
-#define MediaStreamTrackPrivate_h
+#pragma once
#if ENABLE(MEDIA_STREAM)
-#include "MediaStreamSource.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/AtomicString.h>
+#include "RealtimeMediaSource.h"
namespace WebCore {
-class MediaSourceStates;
-class MediaStreamSourceCapabilities;
+class AudioSourceProvider;
+class GraphicsContext;
+class MediaSample;
+class RealtimeMediaSourceCapabilities;
-class MediaStreamTrackPrivateClient {
+class MediaStreamTrackPrivate : public RefCounted<MediaStreamTrackPrivate>, public RealtimeMediaSource::Observer {
public:
- virtual ~MediaStreamTrackPrivateClient() { }
+ class Observer {
+ public:
+ virtual ~Observer() { }
- virtual void trackReadyStateChanged() = 0;
- virtual void trackMutedChanged() = 0;
- virtual void trackEnabledChanged() = 0;
-};
+ virtual void trackEnded(MediaStreamTrackPrivate&) = 0;
+ virtual void trackMutedChanged(MediaStreamTrackPrivate&) = 0;
+ virtual void trackSettingsChanged(MediaStreamTrackPrivate&) = 0;
+ virtual void trackEnabledChanged(MediaStreamTrackPrivate&) = 0;
+ virtual void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) { };
+ };
-class MediaStreamTrackPrivate : public RefCounted<MediaStreamTrackPrivate>, public MediaStreamSource::Observer {
-public:
- static PassRefPtr<MediaStreamTrackPrivate> create(PassRefPtr<MediaStreamSource>);
+ static Ref<MediaStreamTrackPrivate> create(Ref<RealtimeMediaSource>&&);
+ static Ref<MediaStreamTrackPrivate> create(Ref<RealtimeMediaSource>&&, String&& id);
virtual ~MediaStreamTrackPrivate();
- const String& id() const;
+ const String& id() const { return m_id; }
const String& label() const;
- bool ended() const;
+ bool ended() const { return m_isEnded; }
+
+ void startProducingData() { m_source->startProducingData(); }
+ void stopProducingData() { m_source->stopProducingData(); }
+ bool isProducingData() { return m_source->isProducingData(); }
bool muted() const;
- void setMuted(bool);
+ void setMuted(bool muted) { m_source->setMuted(muted); }
bool readonly() const;
bool remote() const;
- bool enabled() const { return m_enabled; }
+ bool enabled() const { return m_isEnabled; }
void setEnabled(bool);
- void setReadyState(MediaStreamSource::ReadyState);
- MediaStreamSource::ReadyState readyState() const;
+ Ref<MediaStreamTrackPrivate> clone();
- RefPtr<MediaStreamTrackPrivate> clone();
+ RealtimeMediaSource& source() { return m_source.get(); }
+ RealtimeMediaSource::Type type() const;
- MediaStreamSource* source() const { return m_source.get(); }
- void setSource(PassRefPtr<MediaStreamSource>);
+ void endTrack();
- enum StopBehavior { StopTrackAndStopSource, StopTrackOnly };
- void stop(StopBehavior);
- bool stopped() const { return m_stopped; }
-
- void setClient(MediaStreamTrackPrivateClient* client) { m_client = client; }
+ void addObserver(Observer&);
+ void removeObserver(Observer&);
- MediaStreamSource::Type type() const;
+ const RealtimeMediaSourceSettings& settings() const;
+ RefPtr<RealtimeMediaSourceCapabilities> capabilities() const;
- const MediaStreamSourceStates& states() const;
- RefPtr<MediaStreamSourceCapabilities> capabilities() const;
+ void applyConstraints(const MediaConstraints&, RealtimeMediaSource::SuccessHandler, RealtimeMediaSource::FailureHandler);
- RefPtr<MediaConstraints> constraints() const;
- void applyConstraints(PassRefPtr<MediaConstraints>);
+ AudioSourceProvider* audioSourceProvider();
- void configureTrackRendering();
-
-protected:
- explicit MediaStreamTrackPrivate(const MediaStreamTrackPrivate&);
- MediaStreamTrackPrivate(PassRefPtr<MediaStreamSource>);
+ void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&);
private:
- MediaStreamTrackPrivateClient* client() const { return m_client; }
-
- // MediaStreamSourceObserver
- virtual void sourceReadyStateChanged() override final;
- virtual void sourceMutedChanged() override final;
- virtual void sourceEnabledChanged() override final;
- virtual bool observerIsEnabled() override final;
-
- RefPtr<MediaStreamSource> m_source;
- MediaStreamTrackPrivateClient* m_client;
- RefPtr<MediaConstraints> m_constraints;
- MediaStreamSource::ReadyState m_readyState;
- mutable String m_id;
-
- bool m_muted;
- bool m_enabled;
- bool m_stopped;
- bool m_ignoreMutations;
+ MediaStreamTrackPrivate(Ref<RealtimeMediaSource>&&, String&& id);
+
+ // RealtimeMediaSourceObserver
+ void sourceStopped() final;
+ void sourceMutedChanged() final;
+ void sourceEnabledChanged() final;
+ void sourceSettingsChanged() final;
+ bool preventSourceFromStopping() final;
+ void videoSampleAvailable(MediaSample&) final;
+
+ Vector<Observer*> m_observers;
+ Ref<RealtimeMediaSource> m_source;
+
+ String m_id;
+ bool m_isEnabled;
+ bool m_isEnded;
};
+typedef Vector<RefPtr<MediaStreamTrackPrivate>> MediaStreamTrackPrivateVector;
+
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamTrackPrivate_h
diff --git a/Source/WebCore/platform/mediastream/MediaStreamTrackSourcesRequestClient.h b/Source/WebCore/platform/mediastream/MediaStreamTrackSourcesRequestClient.h
deleted file mode 100644
index a006df46d..000000000
--- a/Source/WebCore/platform/mediastream/MediaStreamTrackSourcesRequestClient.h
+++ /dev/null
@@ -1,76 +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 COMPUTER, 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 COMPUTER, 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 MediaStreamTrackSourcesRequestClient_h
-#define MediaStreamTrackSourcesRequestClient_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/text/AtomicString.h>
-
-namespace WebCore {
-
-class TrackSourceInfo : public RefCounted<TrackSourceInfo> {
-public:
- enum SourceKind { Audio, Video };
-
- static PassRefPtr<TrackSourceInfo> create(const AtomicString& id, SourceKind kind, const AtomicString& label)
- {
- return adoptRef(new TrackSourceInfo(id, kind, label));
- }
-
- const AtomicString& id() const { return m_id; }
- const AtomicString& label() const { return m_label; }
- SourceKind kind() const { return m_kind; }
-
-private:
- TrackSourceInfo(const AtomicString& id, SourceKind kind, const AtomicString& label)
- : m_id(id)
- , m_kind(kind)
- , m_label(label)
- {
- }
-
- AtomicString m_id;
- SourceKind m_kind;
- AtomicString m_label;
-};
-
-class MediaStreamTrackSourcesRequestClient : public RefCounted<MediaStreamTrackSourcesRequestClient> {
-public:
- virtual ~MediaStreamTrackSourcesRequestClient() { }
-
- virtual const String& requestOrigin() const = 0;
- virtual void didCompleteRequest(const Vector<RefPtr<TrackSourceInfo>>&) = 0;
-
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // MediaStreamTrackSourcesRequestClient_h
diff --git a/Source/WebCore/platform/mediastream/PeerConnectionStates.h b/Source/WebCore/platform/mediastream/PeerConnectionStates.h
new file mode 100644
index 000000000..8a7124070
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/PeerConnectionStates.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015, 2016 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+namespace WebCore {
+
+namespace PeerConnectionStates {
+
+enum class SignalingState {
+ Stable = 1,
+ HaveLocalOffer = 2,
+ HaveRemoteOffer = 3,
+ HaveLocalPrAnswer = 4,
+ HaveRemotePrAnswer = 5,
+ Closed = 6
+};
+
+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
+};
+
+enum class IceTransportState {
+ New = 1,
+ Checking = 2,
+ Connected = 3,
+ Completed = 4,
+ Failed = 5,
+ Disconnected = 6,
+ Closed = 7
+};
+
+enum class IceTransportPolicy {
+ Relay,
+ All
+};
+
+enum class BundlePolicy {
+ Balanced,
+ MaxCompat,
+ MaxBundle
+};
+
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/PeerMediaDescription.h b/Source/WebCore/platform/mediastream/PeerMediaDescription.h
new file mode 100644
index 000000000..157dc8a29
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/PeerMediaDescription.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "IceCandidate.h"
+#include "MediaPayload.h"
+#include "RealtimeMediaSource.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+struct PeerMediaDescription {
+ void addPayload(MediaPayload&& payload) { payloads.append(WTFMove(payload)); }
+ void addSsrc(unsigned ssrc) { ssrcs.append(ssrc); }
+ void clearSsrcs() { ssrcs.clear(); }
+ void addIceCandidate(IceCandidate&& candidate) { iceCandidates.append(WTFMove(candidate)); }
+
+ String type;
+ unsigned short port { 9 };
+ String address { "0.0.0.0" };
+ String mode { ASCIILiteral { "sendrecv" } };
+ String mid;
+
+ Vector<MediaPayload> payloads;
+
+ bool rtcpMux { true };
+ String rtcpAddress;
+ unsigned short rtcpPort { 0 };
+
+ String mediaStreamId;
+ String mediaStreamTrackId;
+
+ String dtlsSetup { "actpass" };
+ String dtlsFingerprintHashFunction;
+ String dtlsFingerprint;
+
+ Vector<unsigned> ssrcs;
+ String cname;
+
+ String iceUfrag;
+ String icePassword;
+ Vector<IceCandidate> iceCandidates;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/RTCConfiguration.h b/Source/WebCore/platform/mediastream/RTCConfiguration.h
deleted file mode 100644
index 73c4cfcf0..000000000
--- a/Source/WebCore/platform/mediastream/RTCConfiguration.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- * 3. Neither the name of Google Inc. 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 RTCConfiguration_h
-#define RTCConfiguration_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "URL.h"
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-
-class RTCIceServer : public RefCounted<RTCIceServer> {
-public:
- static PassRefPtr<RTCIceServer> create(const URL& uri, const String& credential, const String& username)
- {
- return adoptRef(new RTCIceServer(uri, credential, username));
- }
- virtual ~RTCIceServer() { }
-
- const URL& uri() { return m_uri; }
- const String& credential() { return m_credential; }
- const String& username() { return m_username; }
-
-private:
- RTCIceServer(const URL& uri, const String& credential, const String& username)
- : m_uri(uri)
- , m_credential(credential)
- , m_username(username)
- {
- }
-
- URL m_uri;
- String m_credential;
- String m_username;
-};
-
-class RTCConfiguration : public RefCounted<RTCConfiguration> {
-public:
- static PassRefPtr<RTCConfiguration> create() { return adoptRef(new RTCConfiguration()); }
- virtual ~RTCConfiguration() { }
-
- void appendServer(PassRefPtr<RTCIceServer> server) { m_servers.append(server); }
- size_t numberOfServers() { return m_servers.size(); }
- RTCIceServer* server(size_t index) { return m_servers[index].get(); }
-
- private:
- RTCConfiguration() { }
-
- Vector<RefPtr<RTCIceServer>> m_servers;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCConfiguration_h
diff --git a/Source/WebCore/platform/mediastream/RTCDTMFSenderHandler.h b/Source/WebCore/platform/mediastream/RTCDTMFSenderHandler.h
index b96aa8f3c..1733cf2a2 100644
--- a/Source/WebCore/platform/mediastream/RTCDTMFSenderHandler.h
+++ b/Source/WebCore/platform/mediastream/RTCDTMFSenderHandler.h
@@ -26,7 +26,7 @@
#ifndef RTCDTMFSenderHandler_h
#define RTCDTMFSenderHandler_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include <wtf/text/WTFString.h>
@@ -48,6 +48,6 @@ public:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
#endif // RTCDTMFSenderHandler_h
diff --git a/Source/WebCore/platform/mediastream/RTCDTMFSenderHandlerClient.h b/Source/WebCore/platform/mediastream/RTCDTMFSenderHandlerClient.h
index 17c47154f..32f18e5c1 100644
--- a/Source/WebCore/platform/mediastream/RTCDTMFSenderHandlerClient.h
+++ b/Source/WebCore/platform/mediastream/RTCDTMFSenderHandlerClient.h
@@ -26,7 +26,7 @@
#ifndef RTCDTMFSenderHandlerClient_h
#define RTCDTMFSenderHandlerClient_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
namespace WebCore {
@@ -39,6 +39,6 @@ public:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
#endif // RTCDTMFSenderHandlerClient_h
diff --git a/Source/WebCore/platform/mediastream/RTCDataChannelHandler.h b/Source/WebCore/platform/mediastream/RTCDataChannelHandler.h
index 74bd11fb1..e4655dd30 100644
--- a/Source/WebCore/platform/mediastream/RTCDataChannelHandler.h
+++ b/Source/WebCore/platform/mediastream/RTCDataChannelHandler.h
@@ -22,15 +22,23 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCDataChannelHandler_h
-#define RTCDataChannelHandler_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include <wtf/text/WTFString.h>
namespace WebCore {
+struct RTCDataChannelInit {
+ bool ordered { true };
+ int maxRetransmitTime { -1 };
+ int maxRetransmits { -1 };
+ String protocol;
+ bool negotiated { false };
+ int id { -1 };
+};
+
class RTCDataChannelHandlerClient;
class RTCDataChannelHandler {
@@ -39,22 +47,13 @@ public:
virtual void setClient(RTCDataChannelHandlerClient*) = 0;
- virtual String label() = 0;
- virtual bool ordered() = 0;
- virtual unsigned short maxRetransmitTime() = 0;
- virtual unsigned short maxRetransmits() = 0;
- virtual String protocol() = 0;
- virtual bool negotiated() = 0;
- virtual unsigned short id() = 0;
- virtual unsigned long bufferedAmount() = 0;
-
virtual bool sendStringData(const String&) = 0;
virtual bool sendRawData(const char*, size_t) = 0;
virtual void close() = 0;
+
+ virtual size_t bufferedAmount() const = 0;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCDataChannelHandler_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/RTCDataChannelHandlerClient.h b/Source/WebCore/platform/mediastream/RTCDataChannelHandlerClient.h
index 288ee16f3..981316d14 100644
--- a/Source/WebCore/platform/mediastream/RTCDataChannelHandlerClient.h
+++ b/Source/WebCore/platform/mediastream/RTCDataChannelHandlerClient.h
@@ -22,16 +22,16 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCDataChannelHandlerClient_h
-#define RTCDataChannelHandlerClient_h
+#pragma once
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
+#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
-class RTCDataChannelHandlerClient {
+class RTCDataChannelHandlerClient : public ThreadSafeRefCounted<RTCDataChannelHandlerClient> {
public:
enum ReadyState {
ReadyStateConnecting = 0,
@@ -46,10 +46,9 @@ public:
virtual void didReceiveStringData(const String&) = 0;
virtual void didReceiveRawData(const char*, size_t) = 0;
virtual void didDetectError() = 0;
+ virtual void bufferedAmountIsDecreasing() = 0;
};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCDataChannelHandlerClient_h
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.cpp b/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.cpp
index 34bb4bece..7f7538eed 100644
--- a/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.cpp
+++ b/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.cpp
@@ -30,7 +30,7 @@
#include "config.h"
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "RTCIceCandidateDescriptor.h"
@@ -54,4 +54,4 @@ RTCIceCandidateDescriptor::~RTCIceCandidateDescriptor()
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.h b/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.h
index f5123a3fc..64cf7ac8c 100644
--- a/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.h
+++ b/Source/WebCore/platform/mediastream/RTCIceCandidateDescriptor.h
@@ -31,7 +31,7 @@
#ifndef RTCIceCandidateDescriptor_h
#define RTCIceCandidateDescriptor_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -58,6 +58,6 @@ private:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
#endif // RTCIceCandidateDescriptor_h
diff --git a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp
deleted file mode 100644
index 8f36b60e5..000000000
--- a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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.
- * * Neither the name of Google Inc. 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 "RTCPeerConnectionHandler.h"
-
-#include <wtf/NeverDestroyed.h>
-
-namespace WebCore {
-class RTCPeerConnectionHandlerClient;
-
-static std::unique_ptr<RTCPeerConnectionHandler> createHandler(RTCPeerConnectionHandlerClient*)
-{
- return nullptr;
-}
-
-CreatePeerConnectionHandler RTCPeerConnectionHandler::create = createHandler;
-
-const AtomicString& RTCPeerConnectionHandler::incompatibleConstraintsErrorName()
-{
- static NeverDestroyed<AtomicString> incompatibleConstraints("IncompatibleConstraintsError", AtomicString::ConstructFromLiteral);
- return incompatibleConstraints;
-}
-
-const AtomicString& RTCPeerConnectionHandler::invalidSessionDescriptionErrorName()
-{
- static NeverDestroyed<AtomicString> invalidSessionDescription("InvalidSessionDescriptionError", AtomicString::ConstructFromLiteral);
- return invalidSessionDescription;
-}
-
-const AtomicString& RTCPeerConnectionHandler::incompatibleSessionDescriptionErrorName()
-{
- static NeverDestroyed<AtomicString> incompatibleSessionDescription("IncompatibleSessionDescriptionError", AtomicString::ConstructFromLiteral);
- return incompatibleSessionDescription;
-}
-
-const AtomicString& RTCPeerConnectionHandler::internalErrorName()
-{
- static NeverDestroyed<AtomicString> internal("InternalError", AtomicString::ConstructFromLiteral);
- return internal;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h
deleted file mode 100644
index 954acb9a3..000000000
--- a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandler.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- * Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
- *
- * 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 Google Inc. 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 RTCPeerConnectionHandler_h
-#define RTCPeerConnectionHandler_h
-
-#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamPrivate.h"
-#include <wtf/PassRefPtr.h>
-
-namespace WebCore {
-
-class MediaConstraints;
-class MediaStreamSource;
-class RTCConfiguration;
-class RTCDTMFSenderHandler;
-class RTCDataChannelHandler;
-class RTCIceCandidateDescriptor;
-class RTCPeerConnectionHandler;
-class RTCPeerConnectionHandlerClient;
-class RTCSessionDescriptionDescriptor;
-class RTCSessionDescriptionRequest;
-class RTCStatsRequest;
-class RTCVoidRequest;
-
-struct RTCDataChannelInit {
-public:
- RTCDataChannelInit()
- : ordered(true)
- , maxRetransmitTime(-1)
- , maxRetransmits(-1)
- , negotiated(false)
- , id(-1) { }
- bool ordered;
- int maxRetransmitTime;
- int maxRetransmits;
- String protocol;
- bool negotiated;
- int id;
-};
-
-typedef std::unique_ptr<RTCPeerConnectionHandler> (*CreatePeerConnectionHandler)(RTCPeerConnectionHandlerClient*);
-
-class RTCPeerConnectionHandler {
-public:
- static CreatePeerConnectionHandler create;
- virtual ~RTCPeerConnectionHandler() { }
-
- static const AtomicString& incompatibleConstraintsErrorName();
- static const AtomicString& invalidSessionDescriptionErrorName();
- static const AtomicString& incompatibleSessionDescriptionErrorName();
- static const AtomicString& internalErrorName();
-
- virtual bool initialize(PassRefPtr<RTCConfiguration>, PassRefPtr<MediaConstraints>) = 0;
-
- virtual void createOffer(PassRefPtr<RTCSessionDescriptionRequest>, PassRefPtr<MediaConstraints>) = 0;
- virtual void createAnswer(PassRefPtr<RTCSessionDescriptionRequest>, PassRefPtr<MediaConstraints>) = 0;
- virtual void setLocalDescription(PassRefPtr<RTCVoidRequest>, PassRefPtr<RTCSessionDescriptionDescriptor>) = 0;
- virtual void setRemoteDescription(PassRefPtr<RTCVoidRequest>, PassRefPtr<RTCSessionDescriptionDescriptor>) = 0;
- virtual PassRefPtr<RTCSessionDescriptionDescriptor> localDescription() = 0;
- virtual PassRefPtr<RTCSessionDescriptionDescriptor> remoteDescription() = 0;
- virtual bool updateIce(PassRefPtr<RTCConfiguration>, PassRefPtr<MediaConstraints>) = 0;
- virtual bool addIceCandidate(PassRefPtr<RTCVoidRequest>, PassRefPtr<RTCIceCandidateDescriptor>) = 0;
- virtual bool addStream(PassRefPtr<MediaStreamPrivate>, PassRefPtr<MediaConstraints>) = 0;
- virtual void removeStream(PassRefPtr<MediaStreamPrivate>) = 0;
- virtual void getStats(PassRefPtr<RTCStatsRequest>) = 0;
- virtual std::unique_ptr<RTCDataChannelHandler> createDataChannel(const String& label, const RTCDataChannelInit&) = 0;
- virtual std::unique_ptr<RTCDTMFSenderHandler> createDTMFSender(PassRefPtr<MediaStreamSource>) = 0;
- virtual void stop() = 0;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(MEDIA_STREAM)
-
-#endif // RTCPeerConnectionHandler_h
diff --git a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h
index e2ed35bce..16b763b17 100644
--- a/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h
+++ b/Source/WebCore/platform/mediastream/RTCPeerConnectionHandlerClient.h
@@ -31,7 +31,7 @@
#ifndef RTCPeerConnectionHandlerClient_h
#define RTCPeerConnectionHandlerClient_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include <wtf/PassRefPtr.h>
@@ -82,6 +82,6 @@ public:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
#endif // RTCPeerConnectionHandlerClient_h
diff --git a/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.cpp b/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.cpp
index 9178676b1..493219ef0 100644
--- a/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.cpp
+++ b/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.cpp
@@ -30,7 +30,7 @@
#include "config.h"
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include "RTCSessionDescriptionDescriptor.h"
@@ -53,4 +53,4 @@ RTCSessionDescriptionDescriptor::~RTCSessionDescriptionDescriptor()
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.h b/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.h
index 523c27fa1..95d845ec9 100644
--- a/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.h
+++ b/Source/WebCore/platform/mediastream/RTCSessionDescriptionDescriptor.h
@@ -31,7 +31,7 @@
#ifndef RTCSessionDescriptionDescriptor_h
#define RTCSessionDescriptionDescriptor_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -59,6 +59,6 @@ private:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
#endif // RTCSessionDescriptionDescriptor_h
diff --git a/Source/WebCore/platform/mediastream/RTCSessionDescriptionRequest.h b/Source/WebCore/platform/mediastream/RTCSessionDescriptionRequest.h
index f198e8405..107f4ba58 100644
--- a/Source/WebCore/platform/mediastream/RTCSessionDescriptionRequest.h
+++ b/Source/WebCore/platform/mediastream/RTCSessionDescriptionRequest.h
@@ -31,7 +31,7 @@
#ifndef RTCSessionDescriptionRequest_h
#define RTCSessionDescriptionRequest_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -66,6 +66,6 @@ private:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
#endif // RTCSessionDescriptionRequest_h
diff --git a/Source/WebCore/platform/mediastream/RTCVoidRequest.h b/Source/WebCore/platform/mediastream/RTCVoidRequest.h
index 8f64f7693..470e4c002 100644
--- a/Source/WebCore/platform/mediastream/RTCVoidRequest.h
+++ b/Source/WebCore/platform/mediastream/RTCVoidRequest.h
@@ -31,11 +31,9 @@
#ifndef RTCVoidRequest_h
#define RTCVoidRequest_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -53,6 +51,6 @@ protected:
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
#endif // RTCVoidRequest_h
diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
new file mode 100644
index 000000000..d0bd028dd
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
@@ -0,0 +1,783 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2013-2016 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
+ * 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 Google Inc. 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 "RealtimeMediaSource.h"
+
+#include "MediaConstraints.h"
+#include "NotImplemented.h"
+#include "RealtimeMediaSourceCapabilities.h"
+#include "UUID.h"
+#include <wtf/MainThread.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+RealtimeMediaSource::RealtimeMediaSource(const String& id, Type type, const String& name)
+ : m_weakPtrFactory(this)
+ , m_id(id)
+ , m_type(type)
+ , m_name(name)
+{
+ // FIXME(147205): Need to implement fitness score for constraints
+
+ if (m_id.isEmpty())
+ m_id = createCanonicalUUIDString();
+ m_persistentID = m_id;
+ m_suppressNotifications = false;
+}
+
+void RealtimeMediaSource::reset()
+{
+ m_stopped = false;
+ m_muted = false;
+ m_readonly = false;
+ m_remote = false;
+}
+
+void RealtimeMediaSource::addObserver(RealtimeMediaSource::Observer& observer)
+{
+ m_observers.append(&observer);
+}
+
+void RealtimeMediaSource::removeObserver(RealtimeMediaSource::Observer& observer)
+{
+ m_observers.removeFirstMatching([&observer](auto* anObserver) {
+ return anObserver == &observer;
+ });
+
+ if (!m_observers.size())
+ stop();
+}
+
+void RealtimeMediaSource::setMuted(bool muted)
+{
+ if (m_stopped || m_muted == muted)
+ return;
+
+ m_muted = muted;
+
+ if (stopped())
+ return;
+
+ for (auto& observer : m_observers)
+ observer->sourceMutedChanged();
+}
+
+void RealtimeMediaSource::setEnabled(bool enabled)
+{
+ if (m_stopped || m_enabled == enabled)
+ return;
+
+ m_enabled = enabled;
+
+ if (m_stopped)
+ return;
+
+ for (auto& observer : m_observers)
+ observer->sourceEnabledChanged();
+}
+
+void RealtimeMediaSource::settingsDidChange()
+{
+ ASSERT(isMainThread());
+
+ if (m_pendingSettingsDidChangeNotification || m_suppressNotifications)
+ return;
+
+ m_pendingSettingsDidChangeNotification = true;
+
+ scheduleDeferredTask([this] {
+ m_pendingSettingsDidChangeNotification = false;
+ for (auto& observer : m_observers)
+ observer->sourceSettingsChanged();
+ });
+}
+
+void RealtimeMediaSource::videoSampleAvailable(MediaSample& mediaSample)
+{
+ ASSERT(isMainThread());
+ for (const auto& observer : m_observers)
+ observer->videoSampleAvailable(mediaSample);
+}
+
+void RealtimeMediaSource::audioSamplesAvailable(const MediaTime& time, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t numberOfFrames)
+{
+ for (const auto& observer : m_observers)
+ observer->audioSamplesAvailable(time, audioData, description, numberOfFrames);
+}
+
+bool RealtimeMediaSource::readonly() const
+{
+ return m_readonly;
+}
+
+void RealtimeMediaSource::stop(Observer* callingObserver)
+{
+ if (stopped())
+ return;
+
+ m_stopped = true;
+
+ for (const auto& observer : m_observers) {
+ if (observer != callingObserver)
+ observer->sourceStopped();
+ }
+
+ stopProducingData();
+}
+
+void RealtimeMediaSource::requestStop(Observer* callingObserver)
+{
+ if (stopped())
+ return;
+
+ for (const auto& observer : m_observers) {
+ if (observer->preventSourceFromStopping())
+ return;
+ }
+ stop(callingObserver);
+}
+
+bool RealtimeMediaSource::supportsSizeAndFrameRate(std::optional<int>, std::optional<int>, std::optional<double>)
+{
+ // The size and frame rate are within the capability limits, so they are supported.
+ return true;
+}
+
+bool RealtimeMediaSource::supportsSizeAndFrameRate(std::optional<IntConstraint> widthConstraint, std::optional<IntConstraint> heightConstraint, std::optional<DoubleConstraint> frameRateConstraint, String& badConstraint)
+{
+ if (!widthConstraint && !heightConstraint && !frameRateConstraint)
+ return true;
+
+ ASSERT(this->capabilities());
+ RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
+
+ std::optional<int> width;
+ if (widthConstraint && capabilities.supportsWidth()) {
+ if (std::isinf(fitnessDistance(*widthConstraint))) {
+ badConstraint = widthConstraint->name();
+ return false;
+ }
+
+ auto range = capabilities.width();
+ width = widthConstraint->valueForCapabilityRange(size().width(), range.rangeMin().asInt, range.rangeMax().asInt);
+ }
+
+ std::optional<int> height;
+ if (heightConstraint && capabilities.supportsHeight()) {
+ if (std::isinf(fitnessDistance(*heightConstraint))) {
+ badConstraint = heightConstraint->name();
+ return false;
+ }
+
+ auto range = capabilities.height();
+ height = heightConstraint->valueForCapabilityRange(size().height(), range.rangeMin().asInt, range.rangeMax().asInt);
+ }
+
+ std::optional<double> frameRate;
+ if (frameRateConstraint && capabilities.supportsFrameRate()) {
+ if (std::isinf(fitnessDistance(*frameRateConstraint))) {
+ badConstraint = frameRateConstraint->name();
+ return false;
+ }
+
+ auto range = capabilities.frameRate();
+ frameRate = frameRateConstraint->valueForCapabilityRange(this->frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble);
+ }
+
+ // Each of the values is supported individually, see if they all can be applied at the same time.
+ if (!supportsSizeAndFrameRate(WTFMove(width), WTFMove(height), WTFMove(frameRate))) {
+ if (widthConstraint)
+ badConstraint = widthConstraint->name();
+ else if (heightConstraint)
+ badConstraint = heightConstraint->name();
+ else
+ badConstraint = frameRateConstraint->name();
+ return false;
+ }
+
+ return true;
+}
+
+double RealtimeMediaSource::fitnessDistance(const MediaConstraint& constraint)
+{
+ ASSERT(this->capabilities());
+ RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
+
+ switch (constraint.constraintType()) {
+ case MediaConstraintType::Width: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsWidth())
+ return 0;
+
+ auto range = capabilities.width();
+ return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
+ break;
+ }
+
+ case MediaConstraintType::Height: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsHeight())
+ return 0;
+
+ auto range = capabilities.height();
+ return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
+ break;
+ }
+
+ case MediaConstraintType::FrameRate: {
+ ASSERT(constraint.isDouble());
+ if (!capabilities.supportsFrameRate())
+ return 0;
+
+ auto range = capabilities.frameRate();
+ return downcast<DoubleConstraint>(constraint).fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
+ break;
+ }
+
+ case MediaConstraintType::AspectRatio: {
+ ASSERT(constraint.isDouble());
+ if (!capabilities.supportsAspectRatio())
+ return 0;
+
+ auto range = capabilities.aspectRatio();
+ return downcast<DoubleConstraint>(constraint).fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
+ break;
+ }
+
+ case MediaConstraintType::Volume: {
+ ASSERT(constraint.isDouble());
+ if (!capabilities.supportsVolume())
+ return 0;
+
+ auto range = capabilities.volume();
+ return downcast<DoubleConstraint>(constraint).fitnessDistance(range.rangeMin().asDouble, range.rangeMax().asDouble);
+ break;
+ }
+
+ case MediaConstraintType::SampleRate: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsSampleRate())
+ return 0;
+
+ auto range = capabilities.sampleRate();
+ return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
+ break;
+ }
+
+ case MediaConstraintType::SampleSize: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsSampleSize())
+ return 0;
+
+ auto range = capabilities.sampleSize();
+ return downcast<IntConstraint>(constraint).fitnessDistance(range.rangeMin().asInt, range.rangeMax().asInt);
+ break;
+ }
+
+ case MediaConstraintType::FacingMode: {
+ ASSERT(constraint.isString());
+ if (!capabilities.supportsFacingMode())
+ return 0;
+
+ auto& modes = capabilities.facingMode();
+ Vector<String> supportedModes;
+ supportedModes.reserveInitialCapacity(modes.size());
+ for (auto& mode : modes)
+ supportedModes.uncheckedAppend(RealtimeMediaSourceSettings::facingMode(mode));
+ return downcast<StringConstraint>(constraint).fitnessDistance(supportedModes);
+ break;
+ }
+
+ case MediaConstraintType::EchoCancellation: {
+ ASSERT(constraint.isBoolean());
+ if (!capabilities.supportsEchoCancellation())
+ return 0;
+
+ bool echoCancellationReadWrite = capabilities.echoCancellation() == RealtimeMediaSourceCapabilities::EchoCancellation::ReadWrite;
+ return downcast<BooleanConstraint>(constraint).fitnessDistance(echoCancellationReadWrite);
+ break;
+ }
+
+ case MediaConstraintType::DeviceId: {
+ ASSERT(constraint.isString());
+ if (!capabilities.supportsDeviceId())
+ return 0;
+
+ return downcast<StringConstraint>(constraint).fitnessDistance(m_id);
+ break;
+ }
+
+ case MediaConstraintType::GroupId: {
+ ASSERT(constraint.isString());
+ if (!capabilities.supportsDeviceId())
+ return 0;
+
+ return downcast<StringConstraint>(constraint).fitnessDistance(settings().groupId());
+ break;
+ }
+
+ case MediaConstraintType::Unknown:
+ // Unknown (or unsupported) constraints should be ignored.
+ break;
+ }
+
+ return 0;
+}
+
+template <typename ValueType>
+static void applyNumericConstraint(const NumericConstraint<ValueType>& constraint, ValueType current, ValueType capabilityMin, ValueType capabilityMax, RealtimeMediaSource* source, void (RealtimeMediaSource::*applier)(ValueType))
+{
+ ValueType value = constraint.valueForCapabilityRange(current, capabilityMin, capabilityMax);
+ if (value != current)
+ (source->*applier)(value);
+}
+
+void RealtimeMediaSource::applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate)
+{
+ if (width)
+ setWidth(width.value());
+ if (height)
+ setHeight(height.value());
+ if (frameRate)
+ setFrameRate(frameRate.value());
+}
+
+void RealtimeMediaSource::applyConstraint(const MediaConstraint& constraint)
+{
+ RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
+ switch (constraint.constraintType()) {
+ case MediaConstraintType::Width: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsWidth())
+ return;
+
+ auto range = capabilities.width();
+ applyNumericConstraint(downcast<IntConstraint>(constraint), size().width(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setWidth);
+ break;
+ }
+
+ case MediaConstraintType::Height: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsHeight())
+ return;
+
+ auto range = capabilities.height();
+ applyNumericConstraint(downcast<IntConstraint>(constraint), size().height(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setHeight);
+ break;
+ }
+
+ case MediaConstraintType::FrameRate: {
+ ASSERT(constraint.isDouble());
+ if (!capabilities.supportsFrameRate())
+ return;
+
+ auto range = capabilities.frameRate();
+ applyNumericConstraint(downcast<DoubleConstraint>(constraint), frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setFrameRate);
+ break;
+ }
+
+ case MediaConstraintType::AspectRatio: {
+ ASSERT(constraint.isDouble());
+ if (!capabilities.supportsAspectRatio())
+ return;
+
+ auto range = capabilities.aspectRatio();
+ applyNumericConstraint(downcast<DoubleConstraint>(constraint), aspectRatio(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setAspectRatio);
+ break;
+ }
+
+ case MediaConstraintType::Volume: {
+ ASSERT(constraint.isDouble());
+ if (!capabilities.supportsVolume())
+ return;
+
+ auto range = capabilities.volume();
+ applyNumericConstraint(downcast<DoubleConstraint>(constraint), volume(), range.rangeMin().asDouble, range.rangeMax().asDouble, this, &RealtimeMediaSource::setVolume);
+ break;
+ }
+
+ case MediaConstraintType::SampleRate: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsSampleRate())
+ return;
+
+ auto range = capabilities.sampleRate();
+ applyNumericConstraint(downcast<IntConstraint>(constraint), sampleRate(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setSampleRate);
+ break;
+ }
+
+ case MediaConstraintType::SampleSize: {
+ ASSERT(constraint.isInt());
+ if (!capabilities.supportsSampleSize())
+ return;
+
+ auto range = capabilities.sampleSize();
+ applyNumericConstraint(downcast<IntConstraint>(constraint), sampleSize(), range.rangeMin().asInt, range.rangeMax().asInt, this, &RealtimeMediaSource::setSampleSize);
+ break;
+ }
+
+ case MediaConstraintType::EchoCancellation: {
+ ASSERT(constraint.isBoolean());
+ if (!capabilities.supportsEchoCancellation())
+ return;
+
+ bool setting;
+ const BooleanConstraint& boolConstraint = downcast<BooleanConstraint>(constraint);
+ if (boolConstraint.getExact(setting) || boolConstraint.getIdeal(setting))
+ setEchoCancellation(setting);
+ break;
+ }
+
+ case MediaConstraintType::FacingMode: {
+ ASSERT(constraint.isString());
+ if (!capabilities.supportsFacingMode())
+ return;
+
+ auto& supportedModes = capabilities.facingMode();
+ auto filter = [supportedModes](const String& modeString) {
+ auto mode = RealtimeMediaSourceSettings::videoFacingModeEnum(modeString);
+ for (auto& supportedMode : supportedModes) {
+ if (mode == supportedMode)
+ return true;
+ }
+ return false;
+ };
+
+ auto modeString = downcast<StringConstraint>(constraint).find(filter);
+ if (!modeString.isEmpty())
+ setFacingMode(RealtimeMediaSourceSettings::videoFacingModeEnum(modeString));
+ break;
+ }
+
+ case MediaConstraintType::DeviceId:
+ case MediaConstraintType::GroupId:
+ ASSERT(constraint.isString());
+ // There is nothing to do here, neither can be changed.
+ break;
+
+ case MediaConstraintType::Unknown:
+ break;
+ }
+}
+
+bool RealtimeMediaSource::selectSettings(const MediaConstraints& constraints, FlattenedConstraint& candidates, String& failedConstraint)
+{
+ // https://w3c.github.io/mediacapture-main/#dfn-selectsettings
+ //
+ // 1. Each constraint specifies one or more values (or a range of values) for its property.
+ // A property may appear more than once in the list of 'advanced' ConstraintSets. If an
+ // empty object or list has been given as the value for a constraint, it must be interpreted
+ // as if the constraint were not specified (in other words, an empty constraint == no constraint).
+ //
+ // Note that unknown properties are discarded by WebIDL, which means that unknown/unsupported required
+ // constraints will silently disappear. To avoid this being a surprise, application authors are
+ // expected to first use the getSupportedConstraints() method as shown in the Examples below.
+
+ // 2. Let object be the ConstrainablePattern object on which this algorithm is applied. Let copy be an
+ // unconstrained copy of object (i.e., copy should behave as if it were object with all ConstraintSets
+ // removed.)
+
+ // 3. For every possible settings dictionary of copy compute its fitness distance, treating bare values of
+ // properties as ideal values. Let candidates be the set of settings dictionaries for which the fitness
+ // distance is finite.
+
+ failedConstraint = emptyString();
+
+ // Check width, height, and frame rate separately, because while they may be supported individually the combination may not be supported.
+ if (!supportsSizeAndFrameRate(constraints.mandatoryConstraints().width(), constraints.mandatoryConstraints().height(), constraints.mandatoryConstraints().frameRate(), failedConstraint))
+ return false;
+
+ constraints.mandatoryConstraints().filter([&](const MediaConstraint& constraint) {
+ if (constraint.constraintType() == MediaConstraintType::Width || constraint.constraintType() == MediaConstraintType::Height || constraint.constraintType() == MediaConstraintType::FrameRate) {
+ candidates.set(constraint);
+ return false;
+ }
+
+ if (std::isinf(fitnessDistance(constraint))) {
+ failedConstraint = constraint.name();
+ return true;
+ }
+
+ candidates.set(constraint);
+ return false;
+ });
+
+ if (!failedConstraint.isEmpty())
+ return false;
+
+ // 4. If candidates is empty, return undefined as the result of the SelectSettings() algorithm.
+ if (candidates.isEmpty())
+ return true;
+
+ // 5. Iterate over the 'advanced' ConstraintSets in newConstraints in the order in which they were specified.
+ // For each ConstraintSet:
+
+ // 5.1 compute the fitness distance between it and each settings dictionary in candidates, treating bare
+ // values of properties as exact.
+ Vector<std::pair<double, MediaTrackConstraintSetMap>> supportedConstraints;
+ double minimumDistance = std::numeric_limits<double>::infinity();
+
+ for (const auto& advancedConstraint : constraints.advancedConstraints()) {
+ double constraintDistance = 0;
+ bool supported = false;
+
+ advancedConstraint.forEach([&](const MediaConstraint& constraint) {
+ double distance = fitnessDistance(constraint);
+ constraintDistance += distance;
+ if (!std::isinf(distance))
+ supported = true;
+ });
+
+ if (constraintDistance < minimumDistance)
+ minimumDistance = constraintDistance;
+
+ // 5.2 If the fitness distance is finite for one or more settings dictionaries in candidates, keep those
+ // settings dictionaries in candidates, discarding others.
+ // If the fitness distance is infinite for all settings dictionaries in candidates, ignore this ConstraintSet.
+ if (supported)
+ supportedConstraints.append({constraintDistance, advancedConstraint});
+ }
+
+ // 6. Select one settings dictionary from candidates, and return it as the result of the SelectSettings() algorithm.
+ // The UA should use the one with the smallest fitness distance, as calculated in step 3.
+ if (!std::isinf(minimumDistance)) {
+ supportedConstraints.removeAllMatching([&](const std::pair<double, MediaTrackConstraintSetMap>& pair) -> bool {
+ return pair.first > minimumDistance;
+ });
+
+ if (!supportedConstraints.isEmpty()) {
+ auto& advancedConstraint = supportedConstraints[0].second;
+ advancedConstraint.forEach([&](const MediaConstraint& constraint) {
+ candidates.merge(constraint);
+ });
+ }
+ }
+
+ return true;
+}
+
+bool RealtimeMediaSource::supportsConstraints(const MediaConstraints& constraints, String& invalidConstraint)
+{
+ ASSERT(constraints.isValid());
+
+ FlattenedConstraint candidates;
+ if (!selectSettings(constraints, candidates, invalidConstraint))
+ return false;
+
+ return true;
+}
+
+void RealtimeMediaSource::applyConstraints(const FlattenedConstraint& constraints)
+{
+ if (constraints.isEmpty())
+ return;
+
+ beginConfiguration();
+
+ RealtimeMediaSourceCapabilities& capabilities = *this->capabilities();
+
+ std::optional<int> width;
+ if (const MediaConstraint* constraint = constraints.find(MediaConstraintType::Width)) {
+ ASSERT(constraint->isInt());
+ if (capabilities.supportsWidth()) {
+ auto range = capabilities.width();
+ width = downcast<IntConstraint>(*constraint).valueForCapabilityRange(size().width(), range.rangeMin().asInt, range.rangeMax().asInt);
+ }
+ }
+
+ std::optional<int> height;
+ if (const MediaConstraint* constraint = constraints.find(MediaConstraintType::Height)) {
+ ASSERT(constraint->isInt());
+ if (capabilities.supportsHeight()) {
+ auto range = capabilities.height();
+ height = downcast<IntConstraint>(*constraint).valueForCapabilityRange(size().height(), range.rangeMin().asInt, range.rangeMax().asInt);
+ }
+ }
+
+ std::optional<double> frameRate;
+ if (const MediaConstraint* constraint = constraints.find(MediaConstraintType::FrameRate)) {
+ ASSERT(constraint->isDouble());
+ if (capabilities.supportsFrameRate()) {
+ auto range = capabilities.frameRate();
+ frameRate = downcast<DoubleConstraint>(*constraint).valueForCapabilityRange(this->frameRate(), range.rangeMin().asDouble, range.rangeMax().asDouble);
+ }
+ }
+ if (width || height || frameRate)
+ applySizeAndFrameRate(WTFMove(width), WTFMove(height), WTFMove(frameRate));
+
+ for (auto& variant : constraints) {
+ if (variant.constraintType() == MediaConstraintType::Width || variant.constraintType() == MediaConstraintType::Height || variant.constraintType() == MediaConstraintType::FrameRate)
+ continue;
+
+ applyConstraint(variant);
+ }
+
+ commitConfiguration();
+}
+
+std::optional<std::pair<String, String>> RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints)
+{
+ ASSERT(constraints.isValid());
+
+ FlattenedConstraint candidates;
+ String failedConstraint;
+ if (!selectSettings(constraints, candidates, failedConstraint))
+ return { { failedConstraint, ASCIILiteral("Constraint not supported") } };
+
+ applyConstraints(candidates);
+ return std::nullopt;
+}
+
+void RealtimeMediaSource::applyConstraints(const MediaConstraints& constraints, SuccessHandler successHandler, FailureHandler failureHandler)
+{
+ auto result = applyConstraints(constraints);
+ if (!result && successHandler)
+ successHandler();
+ else if (result && failureHandler)
+ failureHandler(result.value().first, result.value().second);
+}
+
+void RealtimeMediaSource::setWidth(int width)
+{
+ if (width == m_size.width())
+ return;
+
+ int height = m_aspectRatio ? width / m_aspectRatio : m_size.height();
+ if (!applySize(IntSize(width, height)))
+ return;
+
+ m_size.setWidth(width);
+ if (m_aspectRatio)
+ m_size.setHeight(width / m_aspectRatio);
+
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setHeight(int height)
+{
+ if (height == m_size.height())
+ return;
+
+ int width = m_aspectRatio ? height * m_aspectRatio : m_size.width();
+ if (!applySize(IntSize(width, height)))
+ return;
+
+ if (m_aspectRatio)
+ m_size.setWidth(width);
+ m_size.setHeight(height);
+
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setFrameRate(double rate)
+{
+ if (m_frameRate == rate || !applyFrameRate(rate))
+ return;
+
+ m_frameRate = rate;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setAspectRatio(double ratio)
+{
+ if (m_aspectRatio == ratio || !applyAspectRatio(ratio))
+ return;
+
+ m_aspectRatio = ratio;
+ m_size.setHeight(m_size.width() / ratio);
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
+{
+ if (m_facingMode == mode || !applyFacingMode(mode))
+ return;
+
+ m_facingMode = mode;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setVolume(double volume)
+{
+ if (m_volume == volume || !applyVolume(volume))
+ return;
+
+ m_volume = volume;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setSampleRate(int rate)
+{
+ if (m_sampleRate == rate || !applySampleRate(rate))
+ return;
+
+ m_sampleRate = rate;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setSampleSize(int size)
+{
+ if (m_sampleSize == size || !applySampleSize(size))
+ return;
+
+ m_sampleSize = size;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::setEchoCancellation(bool echoCancellation)
+{
+ if (m_echoCancellation == echoCancellation || !applyEchoCancellation(echoCancellation))
+ return;
+
+ m_echoCancellation = echoCancellation;
+ settingsDidChange();
+}
+
+void RealtimeMediaSource::scheduleDeferredTask(std::function<void()>&& function)
+{
+ ASSERT(function);
+ callOnMainThread([weakThis = createWeakPtr(), function = WTFMove(function)] {
+ if (!weakThis)
+ return;
+
+ function();
+ });
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSource.h b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h
new file mode 100644
index 000000000..29d3d8327
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSource.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2011 Ericsson AB. All rights reserved.
+ * 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).
+ *
+ * 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 RealtimeMediaSource_h
+#define RealtimeMediaSource_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioSourceProvider.h"
+#include "Image.h"
+#include "MediaConstraints.h"
+#include "MediaSample.h"
+#include "PlatformLayer.h"
+#include "RealtimeMediaSourceCapabilities.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WTF {
+class MediaTime;
+}
+
+namespace WebCore {
+
+class AudioStreamDescription;
+class FloatRect;
+class GraphicsContext;
+class MediaStreamPrivate;
+class PlatformAudioData;
+class RealtimeMediaSourceSettings;
+
+class RealtimeMediaSource : public RefCounted<RealtimeMediaSource> {
+public:
+ class Observer {
+ public:
+ virtual ~Observer() { }
+
+ // Source state changes.
+ virtual void sourceStopped() { }
+ virtual void sourceMutedChanged() { }
+ virtual void sourceEnabledChanged() { }
+ virtual void sourceSettingsChanged() { }
+
+ // Observer state queries.
+ virtual bool preventSourceFromStopping() { return false; }
+
+ // Called on the main thread.
+ virtual void videoSampleAvailable(MediaSample&) { }
+
+ // May be called on a background thread.
+ virtual void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t /*numberOfFrames*/) { }
+ };
+
+ virtual ~RealtimeMediaSource() { }
+
+ const String& id() const { return m_id; }
+
+ const String& persistentID() const { return m_persistentID; }
+ virtual void setPersistentID(const String& persistentID) { m_persistentID = persistentID; }
+
+ enum Type { None, Audio, Video };
+ Type type() const { return m_type; }
+
+ virtual const String& name() const { return m_name; }
+ virtual void setName(const String& name) { m_name = name; }
+
+ virtual unsigned fitnessScore() const { return m_fitnessScore; }
+ virtual void setFitnessScore(const unsigned fitnessScore) { m_fitnessScore = fitnessScore; }
+
+ virtual RefPtr<RealtimeMediaSourceCapabilities> capabilities() const = 0;
+ virtual const RealtimeMediaSourceSettings& settings() const = 0;
+
+ using SuccessHandler = std::function<void()>;
+ using FailureHandler = std::function<void(const String& badConstraint, const String& errorString)>;
+ void applyConstraints(const MediaConstraints&, SuccessHandler, FailureHandler);
+ std::optional<std::pair<String, String>> applyConstraints(const MediaConstraints&);
+
+ virtual bool supportsConstraints(const MediaConstraints&, String&);
+
+ virtual void settingsDidChange();
+
+ void videoSampleAvailable(MediaSample&);
+ void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t);
+
+ bool stopped() const { return m_stopped; }
+
+ virtual bool muted() const { return m_muted; }
+ virtual void setMuted(bool);
+
+ virtual bool enabled() const { return m_enabled; }
+ virtual void setEnabled(bool);
+
+ virtual bool readonly() const;
+ virtual void setReadonly(bool readonly) { m_readonly = readonly; }
+
+ virtual bool remote() const { return m_remote; }
+ virtual void setRemote(bool remote) { m_remote = remote; }
+
+ void addObserver(Observer&);
+ void removeObserver(Observer&);
+
+ virtual void startProducingData() { }
+ virtual void stopProducingData() { }
+ virtual bool isProducingData() const { return false; }
+
+ void stop(Observer* callingObserver = nullptr);
+ void requestStop(Observer* callingObserver = nullptr);
+
+ virtual void reset();
+
+ virtual AudioSourceProvider* audioSourceProvider() { return nullptr; }
+
+ virtual RefPtr<Image> currentFrameImage() { return nullptr; }
+ virtual void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&) { }
+
+ void setWidth(int);
+ void setHeight(int);
+ const IntSize& size() const { return m_size; }
+ virtual bool applySize(const IntSize&) { return false; }
+
+ double frameRate() const { return m_frameRate; }
+ void setFrameRate(double);
+ virtual bool applyFrameRate(double) { return false; }
+
+ double aspectRatio() const { return m_aspectRatio; }
+ void setAspectRatio(double);
+ virtual bool applyAspectRatio(double) { return false; }
+
+ RealtimeMediaSourceSettings::VideoFacingMode facingMode() const { return m_facingMode; }
+ void setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode);
+ virtual bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) { return false; }
+
+ double volume() const { return m_volume; }
+ void setVolume(double);
+ virtual bool applyVolume(double) { return false; }
+
+ int sampleRate() const { return m_sampleRate; }
+ void setSampleRate(int);
+ virtual bool applySampleRate(int) { return false; }
+
+ int sampleSize() const { return m_sampleSize; }
+ void setSampleSize(int);
+ virtual bool applySampleSize(int) { return false; }
+
+ bool echoCancellation() const { return m_echoCancellation; }
+ void setEchoCancellation(bool);
+ virtual bool applyEchoCancellation(bool) { return false; }
+
+protected:
+ RealtimeMediaSource(const String& id, Type, const String& name);
+
+ void scheduleDeferredTask(std::function<void()>&&);
+
+ virtual void beginConfiguration() { }
+ virtual void commitConfiguration() { }
+
+ virtual bool selectSettings(const MediaConstraints&, FlattenedConstraint&, String&);
+ virtual double fitnessDistance(const MediaConstraint&);
+ virtual bool supportsSizeAndFrameRate(std::optional<IntConstraint> width, std::optional<IntConstraint> height, std::optional<DoubleConstraint>, String&);
+ virtual bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
+ virtual void applyConstraint(const MediaConstraint&);
+ virtual void applyConstraints(const FlattenedConstraint&);
+ virtual void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
+
+ bool m_muted { false };
+ bool m_enabled { true };
+
+private:
+ WeakPtr<RealtimeMediaSource> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
+ WeakPtrFactory<RealtimeMediaSource> m_weakPtrFactory;
+ String m_id;
+ String m_persistentID;
+ Type m_type;
+ String m_name;
+ Vector<Observer*> m_observers;
+ IntSize m_size;
+ double m_frameRate { 30 };
+ double m_aspectRatio { 0 };
+ double m_volume { 1 };
+ double m_sampleRate { 0 };
+ double m_sampleSize { 0 };
+ unsigned m_fitnessScore { 0 };
+ RealtimeMediaSourceSettings::VideoFacingMode m_facingMode { RealtimeMediaSourceSettings::User};
+
+ bool m_echoCancellation { false };
+ bool m_stopped { false };
+ bool m_readonly { false };
+ bool m_remote { false };
+ bool m_pendingSettingsDidChangeNotification { false };
+ bool m_suppressNotifications { true };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // RealtimeMediaSource_h
diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h
new file mode 100644
index 000000000..2f22d4894
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCapabilities.h
@@ -0,0 +1,192 @@
+/*
+ * 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 RealtimeMediaSourceCapabilities_h
+#define RealtimeMediaSourceCapabilities_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "RealtimeMediaSourceSettings.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class CapabilityValueOrRange {
+public:
+
+ enum Type {
+ Undefined,
+ Double,
+ ULong,
+ DoubleRange,
+ ULongRange,
+ };
+ Type type() const { return m_type; }
+
+ union ValueUnion {
+ int asInt;
+ double asDouble;
+ };
+
+ CapabilityValueOrRange()
+ : m_type(Undefined)
+ {
+ }
+
+ CapabilityValueOrRange(double value)
+ : m_type(Double)
+ {
+ m_minOrValue.asDouble = value;
+ }
+
+ CapabilityValueOrRange(int value)
+ : m_type(ULong)
+ {
+ m_minOrValue.asInt = value;
+ }
+
+ CapabilityValueOrRange(double min, double max)
+ : m_type(DoubleRange)
+ {
+ m_minOrValue.asDouble = min;
+ m_max.asDouble = max;
+ }
+
+ CapabilityValueOrRange(int min, int max)
+ : m_type(ULongRange)
+ {
+ m_minOrValue.asInt = min;
+ m_max.asInt = max;
+ }
+
+ const ValueUnion& rangeMin() const
+ {
+ ASSERT(m_type == DoubleRange || m_type == ULongRange);
+ return m_minOrValue;
+ }
+
+ const ValueUnion& rangeMax() const
+ {
+ ASSERT(m_type == DoubleRange || m_type == ULongRange);
+ return m_max;
+ }
+
+ const ValueUnion& value() const
+ {
+ ASSERT(m_type == Double || m_type == ULong);
+ return m_minOrValue;
+ }
+
+private:
+ ValueUnion m_minOrValue;
+ ValueUnion m_max;
+ Type m_type;
+};
+
+class RealtimeMediaSourceCapabilities : public RefCounted<RealtimeMediaSourceCapabilities> {
+public:
+ static PassRefPtr<RealtimeMediaSourceCapabilities> create(const RealtimeMediaSourceSupportedConstraints& supportedConstraints)
+ {
+ return adoptRef(new RealtimeMediaSourceCapabilities(supportedConstraints));
+ }
+
+ ~RealtimeMediaSourceCapabilities() { }
+
+ bool supportsWidth() const { return m_supportedConstraints.supportsWidth(); }
+ const CapabilityValueOrRange& width() { return m_width; }
+ void setWidth(const CapabilityValueOrRange& width) { m_width = width; }
+
+ bool supportsHeight() const { return m_supportedConstraints.supportsHeight(); }
+ const CapabilityValueOrRange& height() { return m_height; }
+ void setHeight(const CapabilityValueOrRange& height) { m_height = height; }
+
+ bool supportsFrameRate() const { return m_supportedConstraints.supportsFrameRate(); }
+ const CapabilityValueOrRange& frameRate() { return m_frameRate; }
+ void setFrameRate(const CapabilityValueOrRange& frameRate) { m_frameRate = frameRate; }
+
+ bool supportsFacingMode() const { return m_supportedConstraints.supportsFacingMode(); }
+ const Vector<RealtimeMediaSourceSettings::VideoFacingMode>& facingMode() { return m_facingMode; }
+ void addFacingMode(RealtimeMediaSourceSettings::VideoFacingMode mode) { m_facingMode.append(mode); }
+
+ bool supportsAspectRatio() const { return m_supportedConstraints.supportsAspectRatio(); }
+ const CapabilityValueOrRange& aspectRatio() { return m_aspectRatio; }
+ void setAspectRatio(const CapabilityValueOrRange& aspectRatio) { m_aspectRatio = aspectRatio; }
+
+ bool supportsVolume() const { return m_supportedConstraints.supportsVolume(); }
+ const CapabilityValueOrRange& volume() { return m_volume; }
+ void setVolume(const CapabilityValueOrRange& volume) { m_volume = volume; }
+
+ bool supportsSampleRate() const { return m_supportedConstraints.supportsSampleRate(); }
+ const CapabilityValueOrRange& sampleRate() { return m_sampleRate; }
+ void setSampleRate(const CapabilityValueOrRange& sampleRate) { m_sampleRate = sampleRate; }
+
+ bool supportsSampleSize() const { return m_supportedConstraints.supportsSampleSize(); }
+ const CapabilityValueOrRange& sampleSize() { return m_sampleSize; }
+ void setSampleSize(const CapabilityValueOrRange& sampleSize) { m_sampleSize = sampleSize; }
+
+ enum class EchoCancellation {
+ ReadOnly = 0,
+ ReadWrite = 1,
+ };
+ bool supportsEchoCancellation() const { return m_supportedConstraints.supportsEchoCancellation(); }
+ EchoCancellation echoCancellation() { return m_echoCancellation; }
+ void setEchoCancellation(EchoCancellation echoCancellation) { m_echoCancellation = echoCancellation; }
+
+ bool supportsDeviceId() const { return m_supportedConstraints.supportsDeviceId(); }
+ const AtomicString& deviceId() { return m_deviceId; }
+ void setDeviceId(const AtomicString& id) { m_deviceId = id; }
+
+ bool supportsGroupId() const { return m_supportedConstraints.supportsGroupId(); }
+ const AtomicString& groupId() { return m_groupId; }
+ void setGroupId(const AtomicString& id) { m_groupId = id; }
+
+private:
+ RealtimeMediaSourceCapabilities(const RealtimeMediaSourceSupportedConstraints& supportedConstraints)
+ : m_supportedConstraints(supportedConstraints)
+ {
+ }
+
+ CapabilityValueOrRange m_width;
+ CapabilityValueOrRange m_height;
+ CapabilityValueOrRange m_aspectRatio;
+ CapabilityValueOrRange m_frameRate;
+ Vector<RealtimeMediaSourceSettings::VideoFacingMode> m_facingMode;
+ CapabilityValueOrRange m_volume;
+ CapabilityValueOrRange m_sampleRate;
+ CapabilityValueOrRange m_sampleSize;
+ EchoCancellation m_echoCancellation;
+ AtomicString m_deviceId;
+ AtomicString m_groupId;
+
+ const RealtimeMediaSourceSupportedConstraints& m_supportedConstraints;
+};
+
+} // namespace WebCore
+
+#endif // RealtimeMediaSourceCapabilities_h
+
+#endif
diff --git a/Source/WebCore/platform/mediastream/MediaStreamCenter.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp
index 389138c9b..236f65654 100644
--- a/Source/WebCore/platform/mediastream/MediaStreamCenter.cpp
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp
@@ -32,38 +32,37 @@
#include "config.h"
#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamCenter.h"
+#include "RealtimeMediaSourceCenter.h"
#include "MediaStreamPrivate.h"
namespace WebCore {
-static MediaStreamCenter*& mediaStreamCenterOverride()
+static RealtimeMediaSourceCenter*& mediaStreamCenterOverride()
{
- static MediaStreamCenter* override;
+ static RealtimeMediaSourceCenter* override;
return override;
}
-MediaStreamCenter& MediaStreamCenter::shared()
+RealtimeMediaSourceCenter& RealtimeMediaSourceCenter::singleton()
{
- MediaStreamCenter* override = mediaStreamCenterOverride();
+ RealtimeMediaSourceCenter* override = mediaStreamCenterOverride();
if (override)
return *override;
- return MediaStreamCenter::platformCenter();
+ return RealtimeMediaSourceCenter::platformCenter();
}
-void MediaStreamCenter::setSharedStreamCenter(MediaStreamCenter* center)
+void RealtimeMediaSourceCenter::setSharedStreamCenterOverride(RealtimeMediaSourceCenter* center)
{
mediaStreamCenterOverride() = center;
}
-MediaStreamCenter::MediaStreamCenter()
+RealtimeMediaSourceCenter::RealtimeMediaSourceCenter()
{
}
-MediaStreamCenter::~MediaStreamCenter()
+RealtimeMediaSourceCenter::~RealtimeMediaSourceCenter()
{
}
diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h
new file mode 100644
index 000000000..81e8f434d
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 Ericsson AB. All rights reserved.
+ * Copyright (C) 2012 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.
+ * 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 RealtimeMediaSourceCenter_h
+#define RealtimeMediaSourceCenter_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "RealtimeMediaSource.h"
+#include "RealtimeMediaSourceSupportedConstraints.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class CaptureDevice;
+class MediaConstraints;
+class RealtimeMediaSourceSettings;
+class RealtimeMediaSourceSupportedConstraints;
+class TrackSourceInfo;
+
+class RealtimeMediaSourceCenter {
+public:
+ virtual ~RealtimeMediaSourceCenter();
+
+ WEBCORE_EXPORT static RealtimeMediaSourceCenter& singleton();
+ static void setSharedStreamCenterOverride(RealtimeMediaSourceCenter*);
+
+ using ValidConstraintsHandler = std::function<void(const Vector<String>&& audioDeviceUIDs, const Vector<String>&& videoDeviceUIDs)>;
+ using InvalidConstraintsHandler = std::function<void(const String& invalidConstraint)>;
+ virtual void validateRequestConstraints(ValidConstraintsHandler, InvalidConstraintsHandler, const MediaConstraints& audioConstraints, const MediaConstraints& videoConstraints) = 0;
+
+ using NewMediaStreamHandler = std::function<void(RefPtr<MediaStreamPrivate>&&)>;
+ virtual void createMediaStream(NewMediaStreamHandler, const String& audioDeviceID, const String& videoDeviceID, const MediaConstraints* audioConstraints, const MediaConstraints* videoConstraints) = 0;
+
+ virtual Vector<CaptureDevice> getMediaStreamDevices() = 0;
+
+ virtual const RealtimeMediaSourceSupportedConstraints& supportedConstraints() { return m_supportedConstraints; }
+
+protected:
+ RealtimeMediaSourceCenter();
+
+ static RealtimeMediaSourceCenter& platformCenter();
+ RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // RealtimeMediaSourceCenter_h
diff --git a/Source/WebCore/platform/mediastream/MediaStreamSourceStates.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp
index 04e4ce3ce..7872901ef 100644
--- a/Source/WebCore/platform/mediastream/MediaStreamSourceStates.cpp
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,30 +31,47 @@
#include "config.h"
#if ENABLE(MEDIA_STREAM)
-
-#include "MediaStreamSourceStates.h"
+#include "RealtimeMediaSourceSettings.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
-const AtomicString& MediaStreamSourceStates::facingMode(MediaStreamSourceStates::VideoFacingMode mode)
+static const AtomicString& userFacing()
{
static NeverDestroyed<AtomicString> userFacing("user", AtomicString::ConstructFromLiteral);
+ return userFacing;
+}
+static const AtomicString& environmentFacing()
+{
static NeverDestroyed<AtomicString> environmentFacing("environment", AtomicString::ConstructFromLiteral);
+ return environmentFacing;
+}
+
+static const AtomicString& leftFacing()
+{
static NeverDestroyed<AtomicString> leftFacing("left", AtomicString::ConstructFromLiteral);
+ return leftFacing;
+}
+
+static const AtomicString& rightFacing()
+{
static NeverDestroyed<AtomicString> rightFacing("right", AtomicString::ConstructFromLiteral);
-
+ return rightFacing;
+}
+
+const AtomicString& RealtimeMediaSourceSettings::facingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
+{
switch (mode) {
- case MediaStreamSourceStates::User:
- return userFacing;
- case MediaStreamSourceStates::Environment:
- return environmentFacing;
- case MediaStreamSourceStates::Left:
- return leftFacing;
- case MediaStreamSourceStates::Right:
- return rightFacing;
- case MediaStreamSourceStates::Unknown:
+ case RealtimeMediaSourceSettings::User:
+ return userFacing();
+ case RealtimeMediaSourceSettings::Environment:
+ return environmentFacing();
+ case RealtimeMediaSourceSettings::Left:
+ return leftFacing();
+ case RealtimeMediaSourceSettings::Right:
+ return rightFacing();
+ case RealtimeMediaSourceSettings::Unknown:
return emptyAtom;
}
@@ -62,23 +79,18 @@ const AtomicString& MediaStreamSourceStates::facingMode(MediaStreamSourceStates:
return emptyAtom;
}
-const AtomicString& MediaStreamSourceStates::sourceType(MediaStreamSourceStates::SourceType sourceType)
+RealtimeMediaSourceSettings::VideoFacingMode RealtimeMediaSourceSettings::videoFacingModeEnum(const String& mode)
{
- static NeverDestroyed<AtomicString> none("none", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> camera("camera", AtomicString::ConstructFromLiteral);
- static NeverDestroyed<AtomicString> microphone("microphone", AtomicString::ConstructFromLiteral);
-
- switch (sourceType) {
- case MediaStreamSourceStates::None:
- return none;
- case MediaStreamSourceStates::Camera:
- return camera;
- case MediaStreamSourceStates::Microphone:
- return microphone;
- }
-
- ASSERT_NOT_REACHED();
- return emptyAtom;
+ if (mode == userFacing())
+ return RealtimeMediaSourceSettings::User;
+ if (mode == environmentFacing())
+ return RealtimeMediaSourceSettings::Environment;
+ if (mode == leftFacing())
+ return RealtimeMediaSourceSettings::Left;
+ if (mode == rightFacing())
+ return RealtimeMediaSourceSettings::Right;
+
+ return RealtimeMediaSourceSettings::Unknown;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h
new file mode 100644
index 000000000..7b5dc717c
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSettings.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2013-2015 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 RealtimeMediaSourceSettings_h
+#define RealtimeMediaSourceSettings_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "RealtimeMediaSourceSupportedConstraints.h"
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+class RealtimeMediaSourceSettings {
+public:
+ enum SourceType { None, Camera, Microphone };
+ enum VideoFacingMode { Unknown, User, Environment, Left, Right };
+
+ static const AtomicString& facingMode(RealtimeMediaSourceSettings::VideoFacingMode);
+
+ static RealtimeMediaSourceSettings::VideoFacingMode videoFacingModeEnum(const String&);
+
+ explicit RealtimeMediaSourceSettings()
+ {
+ }
+
+ bool supportsWidth() const { return m_supportedConstraints.supportsWidth(); }
+ unsigned long width() const { return m_width; }
+ void setWidth(unsigned long width) { m_width = width; }
+
+ bool supportsHeight() const { return m_supportedConstraints.supportsHeight(); }
+ unsigned long height() const { return m_height; }
+ void setHeight(unsigned long height) { m_height = height; }
+
+ bool supportsAspectRatio() const { return m_supportedConstraints.supportsAspectRatio(); }
+ float aspectRatio() const { return m_aspectRatio; }
+ void setAspectRatio(float aspectRatio) { m_aspectRatio = aspectRatio; }
+
+ bool supportsFrameRate() const { return m_supportedConstraints.supportsFrameRate(); }
+ float frameRate() const { return m_frameRate; }
+ void setFrameRate(float frameRate) { m_frameRate = frameRate; }
+
+ bool supportsFacingMode() const { return m_supportedConstraints.supportsFacingMode(); }
+ VideoFacingMode facingMode() const { return m_facingMode; }
+ void setFacingMode(VideoFacingMode facingMode) { m_facingMode = facingMode; }
+
+ bool supportsVolume() const { return m_supportedConstraints.supportsVolume(); }
+ double volume() const { return m_volume; }
+ void setVolume(double volume) { m_volume = volume; }
+
+ bool supportsSampleRate() const { return m_supportedConstraints.supportsSampleRate(); }
+ unsigned long sampleRate() const { return m_sampleRate; }
+ void setSampleRate(unsigned long sampleRate) { m_sampleRate = sampleRate; }
+
+ bool supportsSampleSize() const { return m_supportedConstraints.supportsSampleSize(); }
+ unsigned long sampleSize() const { return m_sampleSize; }
+ void setSampleSize(unsigned long sampleSize) { m_sampleSize = sampleSize; }
+
+ bool supportsEchoCancellation() const { return m_supportedConstraints.supportsEchoCancellation(); }
+ bool echoCancellation() const { return m_echoCancellation; }
+ void setEchoCancellation(bool echoCancellation) { m_echoCancellation = echoCancellation; }
+
+ bool supportsDeviceId() const { return m_supportedConstraints.supportsDeviceId(); }
+ const AtomicString& deviceId() const { return m_deviceId; }
+ void setDeviceId(const AtomicString& deviceId) { m_deviceId = deviceId; }
+
+ bool supportsGroupId() const { return m_supportedConstraints.supportsGroupId(); }
+ const AtomicString& groupId() const { return m_groupId; }
+ void setGroupId(const AtomicString& groupId) { m_groupId = groupId; }
+
+ void setSupportedConstraits(const RealtimeMediaSourceSupportedConstraints& supportedConstraints) { m_supportedConstraints = supportedConstraints; }
+
+private:
+ unsigned long m_width { 0 };
+ unsigned long m_height { 0 };
+ float m_aspectRatio { 0 };
+ float m_frameRate { 0 };
+ VideoFacingMode m_facingMode { Unknown };
+ double m_volume { 0 };
+ unsigned long m_sampleRate { 0 };
+ unsigned long m_sampleSize { 0 };
+ bool m_echoCancellation { 0 };
+
+ AtomicString m_deviceId;
+ AtomicString m_groupId;
+
+ RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
+};
+
+} // namespace WebCore
+
+#endif // RealtimeMediaSourceSettings_h
+
+#endif
diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp
new file mode 100644
index 000000000..73775a0f2
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2015 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 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 "RealtimeMediaSourceSupportedConstraints.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+const AtomicString& RealtimeMediaSourceSupportedConstraints::nameForConstraint(MediaConstraintType constraint)
+{
+ static NeverDestroyed<AtomicString> unknownConstraintName(emptyString());
+ static NeverDestroyed<AtomicString> widthConstraintName("width");
+ static NeverDestroyed<AtomicString> heightConstraintName("height");
+ static NeverDestroyed<AtomicString> aspectRatioConstraintName("aspectRatio");
+ static NeverDestroyed<AtomicString> frameRateConstraintName("frameRate");
+ static NeverDestroyed<AtomicString> facingModeConstraintName("facingMode");
+ static NeverDestroyed<AtomicString> volumeConstraintName("volume");
+ static NeverDestroyed<AtomicString> sampleRateConstraintName("sampleRate");
+ static NeverDestroyed<AtomicString> sampleSizeConstraintName("sampleSize");
+ static NeverDestroyed<AtomicString> echoCancellationConstraintName("echoCancellation");
+ static NeverDestroyed<AtomicString> deviceIdConstraintName("deviceId");
+ static NeverDestroyed<AtomicString> groupIdConstraintName("groupId");
+ switch (constraint) {
+ case MediaConstraintType::Unknown:
+ return unknownConstraintName;
+ case MediaConstraintType::Width:
+ return widthConstraintName;
+ case MediaConstraintType::Height:
+ return heightConstraintName;
+ case MediaConstraintType::AspectRatio:
+ return aspectRatioConstraintName;
+ case MediaConstraintType::FrameRate:
+ return frameRateConstraintName;
+ case MediaConstraintType::FacingMode:
+ return facingModeConstraintName;
+ case MediaConstraintType::Volume:
+ return volumeConstraintName;
+ case MediaConstraintType::SampleRate:
+ return sampleRateConstraintName;
+ case MediaConstraintType::SampleSize:
+ return sampleSizeConstraintName;
+ case MediaConstraintType::EchoCancellation:
+ return echoCancellationConstraintName;
+ case MediaConstraintType::DeviceId:
+ return deviceIdConstraintName;
+ case MediaConstraintType::GroupId:
+ return groupIdConstraintName;
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+}
+
+MediaConstraintType RealtimeMediaSourceSupportedConstraints::constraintFromName(const String& constraintName)
+{
+ static NeverDestroyed<HashMap<AtomicString, MediaConstraintType>> nameToConstraintMap;
+ HashMap<AtomicString, MediaConstraintType>& nameToConstraintMapValue = nameToConstraintMap.get();
+ if (!nameToConstraintMapValue.size()) {
+ nameToConstraintMapValue.add("width", MediaConstraintType::Width);
+ nameToConstraintMapValue.add("height", MediaConstraintType::Height);
+ nameToConstraintMapValue.add("aspectRatio", MediaConstraintType::AspectRatio);
+ nameToConstraintMapValue.add("frameRate", MediaConstraintType::FrameRate);
+ nameToConstraintMapValue.add("facingMode", MediaConstraintType::FacingMode);
+ nameToConstraintMapValue.add("volume", MediaConstraintType::Volume);
+ nameToConstraintMapValue.add("sampleRate", MediaConstraintType::SampleRate);
+ nameToConstraintMapValue.add("sampleSize", MediaConstraintType::SampleSize);
+ nameToConstraintMapValue.add("echoCancellation", MediaConstraintType::EchoCancellation);
+ nameToConstraintMapValue.add("deviceId", MediaConstraintType::DeviceId);
+ nameToConstraintMapValue.add("groupId", MediaConstraintType::GroupId);
+ }
+ auto iter = nameToConstraintMapValue.find(constraintName);
+ return iter == nameToConstraintMapValue.end() ? MediaConstraintType::Unknown : iter->value;
+}
+
+bool RealtimeMediaSourceSupportedConstraints::supportsConstraint(MediaConstraintType constraint) const
+{
+ switch (constraint) {
+ case MediaConstraintType::Unknown:
+ return false;
+ case MediaConstraintType::Width:
+ return supportsWidth();
+ case MediaConstraintType::Height:
+ return supportsHeight();
+ case MediaConstraintType::AspectRatio:
+ return supportsAspectRatio();
+ case MediaConstraintType::FrameRate:
+ return supportsFrameRate();
+ case MediaConstraintType::FacingMode:
+ return supportsFacingMode();
+ case MediaConstraintType::Volume:
+ return supportsVolume();
+ case MediaConstraintType::SampleRate:
+ return supportsSampleRate();
+ case MediaConstraintType::SampleSize:
+ return supportsSampleSize();
+ case MediaConstraintType::EchoCancellation:
+ return supportsEchoCancellation();
+ case MediaConstraintType::DeviceId:
+ return supportsDeviceId();
+ case MediaConstraintType::GroupId:
+ return supportsGroupId();
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h
new file mode 100644
index 000000000..bfb54e6d6
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/RealtimeMediaSourceSupportedConstraints.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 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.
+ * 3. Neither the name of Google Inc. 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 RealtimeMediaSourceSupportedConstraints_h
+#define RealtimeMediaSourceSupportedConstraints_h
+
+#if ENABLE(MEDIA_STREAM)
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+enum class MediaConstraintType {
+ Unknown,
+ Width,
+ Height,
+ AspectRatio,
+ FrameRate,
+ FacingMode,
+ Volume,
+ SampleRate,
+ SampleSize,
+ EchoCancellation,
+ DeviceId,
+ GroupId
+};
+
+class RealtimeMediaSourceSupportedConstraints {
+public:
+ RealtimeMediaSourceSupportedConstraints()
+ {
+ }
+
+ bool supportsWidth() const { return m_supportsWidth; }
+ void setSupportsWidth(bool value) { m_supportsWidth = value; }
+
+ bool supportsHeight() const { return m_supportsHeight; }
+ void setSupportsHeight(bool value) { m_supportsHeight = value; }
+
+ bool supportsAspectRatio() const { return m_supportsAspectRatio; }
+ void setSupportsAspectRatio(bool value) { m_supportsAspectRatio = value; }
+
+ bool supportsFrameRate() const { return m_supportsFrameRate; }
+ void setSupportsFrameRate(bool value) { m_supportsFrameRate = value; }
+
+ bool supportsFacingMode() const { return m_supportsFacingMode; }
+ void setSupportsFacingMode(bool value) { m_supportsFacingMode = value; }
+
+ bool supportsVolume() const { return m_supportsVolume; }
+ void setSupportsVolume(bool value) { m_supportsVolume = value; }
+
+ bool supportsSampleRate() const { return m_supportsSampleRate; }
+ void setSupportsSampleRate(bool value) { m_supportsSampleRate = value; }
+
+ bool supportsSampleSize() const { return m_supportsSampleSize; }
+ void setSupportsSampleSize(bool value) { m_supportsSampleSize = value; }
+
+ bool supportsEchoCancellation() const { return m_supportsEchoCancellation; }
+ void setSupportsEchoCancellation(bool value) { m_supportsEchoCancellation = value; }
+
+ bool supportsDeviceId() const { return m_supportsDeviceId; }
+ void setSupportsDeviceId(bool value) { m_supportsDeviceId = value; }
+
+ bool supportsGroupId() const { return m_supportsGroupId; }
+ void setSupportsGroupId(bool value) { m_supportsGroupId = value; }
+
+ bool supportsConstraint(MediaConstraintType) const;
+
+ static const AtomicString& nameForConstraint(MediaConstraintType);
+ static MediaConstraintType constraintFromName(const String&);
+
+private:
+ bool m_supportsWidth { false };
+ bool m_supportsHeight { false };
+ bool m_supportsAspectRatio { false };
+ bool m_supportsFrameRate { false };
+ bool m_supportsFacingMode { false };
+ bool m_supportsVolume { false };
+ bool m_supportsSampleRate { false };
+ bool m_supportsSampleSize { false };
+ bool m_supportsEchoCancellation { false };
+ bool m_supportsDeviceId { false };
+ bool m_supportsGroupId { false };
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
+
+#endif // RealtimeMediaSourceSupportedConstraints_h
diff --git a/Source/WebCore/platform/mediastream/SDPProcessorScriptResource.cpp b/Source/WebCore/platform/mediastream/SDPProcessorScriptResource.cpp
new file mode 100644
index 000000000..669ed2a76
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/SDPProcessorScriptResource.cpp
@@ -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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_RTC)
+#include "SDPProcessorScriptResource.h"
+
+#include "SDPProcessorScriptsData.h"
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+namespace SDPProcessorScriptResource {
+
+const String& scriptString()
+{
+ static NeverDestroyed<const String> script(sdpJavaScript, sizeof(sdpJavaScript));
+ return script;
+}
+
+} // namespace SDPProcessorScriptResource
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/RTCStatsRequest.h b/Source/WebCore/platform/mediastream/SDPProcessorScriptResource.h
index b53dcf1a7..cb5443bb0 100644
--- a/Source/WebCore/platform/mediastream/RTCStatsRequest.h
+++ b/Source/WebCore/platform/mediastream/SDPProcessorScriptResource.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Google 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
@@ -11,7 +11,7 @@
* 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 Google Inc. nor the names of its contributors
+ * 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.
*
@@ -28,35 +28,23 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RTCStatsRequest_h
-#define RTCStatsRequest_h
+#ifndef SDPProcessorScriptResource_h
+#define SDPProcessorScriptResource_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(WEB_RTC)
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
-class MediaStreamTrack;
-class RTCStatsResponseBase;
+namespace SDPProcessorScriptResource {
-class RTCStatsRequest : public RefCounted<RTCStatsRequest> {
-public:
- virtual ~RTCStatsRequest() { }
+const String& scriptString();
- virtual PassRefPtr<RTCStatsResponseBase> createResponse() = 0;
- virtual bool hasSelector() = 0;
- virtual MediaStreamTrack* track() = 0;
- virtual void requestSucceeded(PassRefPtr<RTCStatsResponseBase>) = 0;
-
-protected:
- RTCStatsRequest() { }
-};
+} // namespace SDPProcessorScriptResource
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(WEB_RTC)
-#endif // RTCStatsRequest_h
+#endif // SDPProcessorScriptResource_h
diff --git a/Source/WebCore/platform/mediastream/VideoTrackPrivateMediaStream.h b/Source/WebCore/platform/mediastream/VideoTrackPrivateMediaStream.h
new file mode 100644
index 000000000..19a6b66ac
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/VideoTrackPrivateMediaStream.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015-2017 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM)
+
+#include "MediaStreamTrackPrivate.h"
+#include "VideoTrackPrivate.h"
+
+namespace WebCore {
+
+class VideoTrackPrivateMediaStream final : public VideoTrackPrivate {
+ WTF_MAKE_NONCOPYABLE(VideoTrackPrivateMediaStream)
+public:
+ static RefPtr<VideoTrackPrivateMediaStream> create(MediaStreamTrackPrivate& streamTrack)
+ {
+ return adoptRef(*new VideoTrackPrivateMediaStream(streamTrack));
+ }
+
+ void setTrackIndex(int index) { m_index = index; }
+
+ MediaStreamTrackPrivate& streamTrack() { return m_streamTrack.get(); }
+
+ MediaTime timelineOffset() const { return m_timelineOffset; }
+ void setTimelineOffset(const MediaTime& offset) { m_timelineOffset = offset; }
+
+private:
+ VideoTrackPrivateMediaStream(MediaStreamTrackPrivate& track)
+ : m_streamTrack(track)
+ , m_id(track.id())
+ , m_label(track.label())
+ , m_timelineOffset(MediaTime::invalidTime())
+ {
+ }
+
+ Kind kind() const final { return Kind::Main; }
+ AtomicString id() const final { return m_id; }
+ AtomicString label() const final { return m_label; }
+ AtomicString language() const final { return emptyAtom; }
+ int trackIndex() const final { return m_index; }
+
+ Ref<MediaStreamTrackPrivate> m_streamTrack;
+ AtomicString m_id;
+ AtomicString m_label;
+ int m_index { 0 };
+ MediaTime m_timelineOffset;
+};
+
+}
+
+#endif // ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h
new file mode 100644
index 000000000..e49107f10
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioFormat.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+namespace WebCore {
+
+namespace LibWebRTCAudioFormat {
+
+static const size_t sampleRate = 48000;
+static const size_t chunkSampleCount = 480;
+static const size_t sampleSize = 16;
+static const size_t sampleByteSize = 2;
+static const bool isFloat = false;
+static const bool isBigEndian = false;
+static const bool isNonInterleaved = false;
+
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp
new file mode 100644
index 000000000..8ba6f4333
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 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. 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 "LibWebRTCAudioModule.h"
+
+#if USE(LIBWEBRTC)
+
+namespace WebCore {
+
+LibWebRTCAudioModule::LibWebRTCAudioModule()
+ : m_audioTaskRunner(rtc::Thread::Create())
+{
+ m_audioTaskRunner->Start();
+}
+
+int32_t LibWebRTCAudioModule::RegisterAudioCallback(webrtc::AudioTransport* audioTransport)
+{
+ m_audioTransport = audioTransport;
+ return 0;
+}
+
+void LibWebRTCAudioModule::OnMessage(rtc::Message* message)
+{
+ ASSERT_UNUSED(message, message->message_id == 1);
+ StartPlayoutOnAudioThread();
+}
+
+int32_t LibWebRTCAudioModule::StartPlayout()
+{
+ if (!m_isPlaying && m_audioTaskRunner) {
+ m_audioTaskRunner->Post(RTC_FROM_HERE, this, 1);
+ m_isPlaying = true;
+ }
+ return 0;
+}
+
+int32_t LibWebRTCAudioModule::StopPlayout()
+{
+ if (m_isPlaying)
+ m_isPlaying = false;
+ return 0;
+}
+
+// libwebrtc uses 10ms frames.
+const unsigned samplingRate = 48000;
+const unsigned frameLengthMs = 10;
+const unsigned samplesPerFrame = samplingRate * frameLengthMs / 1000;
+const unsigned pollSamples = 5;
+const unsigned pollInterval = 5 * frameLengthMs;
+const unsigned channels = 2;
+const unsigned bytesPerSample = 2;
+
+void LibWebRTCAudioModule::StartPlayoutOnAudioThread()
+{
+ while (true) {
+ PollFromSource();
+ m_audioTaskRunner->SleepMs(pollInterval);
+ if (!m_isPlaying)
+ return;
+ }
+}
+
+void LibWebRTCAudioModule::PollFromSource()
+{
+ if (!m_audioTransport)
+ return;
+
+ for (unsigned i = 0; i < pollSamples; i++) {
+ int64_t elapsedTime = -1;
+ int64_t ntpTime = -1;
+ char data[(bytesPerSample * channels * samplesPerFrame)];
+ m_audioTransport->PullRenderData(bytesPerSample * 8, samplingRate, channels, samplesPerFrame, data, &elapsedTime, &ntpTime);
+ }
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h
new file mode 100644
index 000000000..95988609d
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCAudioModule.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCMacros.h"
+#include <webrtc/base/messagehandler.h>
+#include <webrtc/base/thread.h>
+#include <webrtc/modules/audio_device/include/audio_device.h>
+
+namespace WebCore {
+
+// LibWebRTCAudioModule is pulling streamed data to ensure audio data is passed to the audio track.
+class LibWebRTCAudioModule final : public webrtc::AudioDeviceModule, private rtc::MessageHandler {
+public:
+ LibWebRTCAudioModule();
+
+private:
+ template<typename U> U shouldNotBeCalled(U value) const
+ {
+ ASSERT_NOT_REACHED();
+ return value;
+ }
+
+ int32_t AddRef() const final { return 1; }
+ int32_t Release() const final { return 1; }
+ void OnMessage(rtc::Message*);
+
+ // webrtc::AudioDeviceModule API
+ int32_t StartPlayout() final;
+ int32_t StopPlayout() final;
+ int32_t RegisterAudioCallback(webrtc::AudioTransport*) final;
+ bool Playing() const final { return m_isPlaying; }
+
+ int64_t TimeUntilNextProcess() final { return std::numeric_limits<int64_t>::max(); }
+ void Process() final { }
+ int32_t ActiveAudioLayer(AudioLayer*) const final { return shouldNotBeCalled(-1); }
+ ErrorCode LastError() const final { return kAdmErrNone; }
+ int32_t RegisterEventObserver(webrtc::AudioDeviceObserver*) final { return 0; }
+ int32_t Init() final { return 0; }
+ int32_t Terminate() final { return 0; }
+ bool Initialized() const final { return true; }
+ int16_t PlayoutDevices() final { return 0; }
+ int16_t RecordingDevices() final { return 0; }
+ int32_t PlayoutDeviceName(uint16_t, char[webrtc::kAdmMaxDeviceNameSize], char[webrtc::kAdmMaxGuidSize]) final { return 0; }
+ int32_t RecordingDeviceName(uint16_t, char[webrtc::kAdmMaxDeviceNameSize], char[webrtc::kAdmMaxGuidSize]) final { return 0; }
+ int32_t SetPlayoutDevice(uint16_t) final { return 0; }
+ int32_t SetPlayoutDevice(WindowsDeviceType) final { return 0; }
+ int32_t SetRecordingDevice(uint16_t) final { return 0; }
+ int32_t SetRecordingDevice(WindowsDeviceType) final { return 0; }
+ int32_t PlayoutIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t InitPlayout() final { return 0; }
+ bool PlayoutIsInitialized() const final { return true; }
+ int32_t RecordingIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t InitRecording() final { return 0; }
+ bool RecordingIsInitialized() const final { return false; }
+ int32_t StartRecording() final { return 0; }
+ int32_t StopRecording() final { return 0; }
+ bool Recording() const final { return 0; }
+ int32_t SetAGC(bool) final { return 0; }
+ bool AGC() const final { return shouldNotBeCalled(0); }
+ int32_t SetWaveOutVolume(uint16_t, uint16_t) final { return shouldNotBeCalled(-1); }
+ int32_t WaveOutVolume(uint16_t*, uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t InitSpeaker() final { return 0; }
+ bool SpeakerIsInitialized() const final { return false; }
+ int32_t InitMicrophone() final { return 0; }
+ bool MicrophoneIsInitialized() const final { return false; }
+ int32_t SpeakerVolumeIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetSpeakerVolume(uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MaxSpeakerVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MinSpeakerVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerVolumeStepSize(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneVolumeIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetMicrophoneVolume(uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MaxMicrophoneVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MinMicrophoneVolume(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneVolumeStepSize(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerMuteIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetSpeakerMute(bool) final { return shouldNotBeCalled(-1); }
+ int32_t SpeakerMute(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneMuteIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetMicrophoneMute(bool) final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneMute(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneBoostIsAvailable(bool*) final { return shouldNotBeCalled(-1); }
+ int32_t SetMicrophoneBoost(bool) final { return shouldNotBeCalled(-1); }
+ int32_t MicrophoneBoost(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t StereoPlayoutIsAvailable(bool* available) const final { *available = false; return 0; }
+ int32_t SetStereoPlayout(bool) final { return 0; }
+ int32_t StereoPlayout(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t StereoRecordingIsAvailable(bool* available) const final { *available = false; return 0; }
+ int32_t SetStereoRecording(bool) final { return 0; }
+ int32_t StereoRecording(bool*) const final { return shouldNotBeCalled(-1); }
+ int32_t SetRecordingChannel(const ChannelType) final { return 0; }
+ int32_t RecordingChannel(ChannelType*) const final { return shouldNotBeCalled(-1); }
+ int32_t SetPlayoutBuffer(const BufferType, uint16_t) final { return shouldNotBeCalled(-1); }
+ int32_t PlayoutBuffer(BufferType*, uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t PlayoutDelay(uint16_t* delay) const final { *delay = 0; return 0; }
+ int32_t RecordingDelay(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t CPULoad(uint16_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t StartRawOutputFileRecording(const char[webrtc::kAdmMaxFileNameSize]) final { return shouldNotBeCalled(-1); }
+ int32_t StopRawOutputFileRecording() final { return shouldNotBeCalled(-1); }
+ int32_t StartRawInputFileRecording(const char[webrtc::kAdmMaxFileNameSize]) final { return shouldNotBeCalled(-1); }
+ int32_t StopRawInputFileRecording() final { return shouldNotBeCalled(-1); }
+ int32_t SetRecordingSampleRate(const uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t RecordingSampleRate(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t SetPlayoutSampleRate(const uint32_t) final { return shouldNotBeCalled(-1); }
+ int32_t PlayoutSampleRate(uint32_t*) const final { return shouldNotBeCalled(-1); }
+ int32_t ResetAudioDevice() final { return shouldNotBeCalled(-1); }
+ int32_t SetLoudspeakerStatus(bool) final { return shouldNotBeCalled(-1); }
+ int32_t GetLoudspeakerStatus(bool*) const final { return shouldNotBeCalled(-1); }
+ bool BuiltInAECIsAvailable() const final { return false; }
+ bool BuiltInAGCIsAvailable() const final { return false; }
+ bool BuiltInNSIsAvailable() const final { return false; }
+ int32_t EnableBuiltInAEC(bool) final { return shouldNotBeCalled(-1); }
+ int32_t EnableBuiltInAGC(bool) final { return shouldNotBeCalled(-1); }
+ int32_t EnableBuiltInNS(bool) final { return shouldNotBeCalled(-1); }
+
+#if defined(WEBRTC_IOS)
+ int GetPlayoutAudioParameters(webrtc::AudioParameters*) const final { return shouldNotBeCalled(-1); }
+ int GetRecordAudioParameters(webrtc::AudioParameters*) const final { return shouldNotBeCalled(-1); }
+#endif
+
+private:
+ void StartPlayoutOnAudioThread();
+
+ void PollFromSource();
+
+ std::unique_ptr<rtc::Thread> m_audioTaskRunner;
+
+ bool m_isPlaying = false;
+ webrtc::AudioTransport* m_audioTransport = nullptr;
+};
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h
new file mode 100644
index 000000000..982d94be5
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCMacros.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted, provided that the following conditions
+ * are required to be 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 Apple Inc. 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 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. AND ITS CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if USE(LIBWEBRTC)
+
+#if PLATFORM(IOS)
+#define WEBRTC_IOS
+#endif
+
+#if PLATFORM(MAC)
+#define WEBRTC_MAC
+#endif
+
+#define WEBRTC_POSIX 1
+#define _COMMON_INCLUDED_
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp
new file mode 100644
index 000000000..0095c517f
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2017 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. 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 "LibWebRTCProvider.h"
+
+#if USE(LIBWEBRTC)
+
+#include "LibWebRTCAudioModule.h"
+#include <webrtc/api/peerconnectionfactory.h>
+#include <webrtc/api/peerconnectionfactoryproxy.h>
+#include <webrtc/base/physicalsocketserver.h>
+#include <webrtc/p2p/client/basicportallocator.h>
+#include <webrtc/sdk/objc/Framework/Classes/videotoolboxvideocodecfactory.h>
+#include <wtf/Function.h>
+#include <wtf/NeverDestroyed.h>
+
+namespace WebCore {
+
+struct PeerConnectionFactoryAndThreads : public rtc::MessageHandler {
+ std::unique_ptr<LibWebRTCAudioModule> audioDeviceModule;
+ std::unique_ptr<rtc::Thread> networkThread;
+ std::unique_ptr<rtc::Thread> signalingThread;
+ rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory;
+ bool networkThreadWithSocketServer { false };
+private:
+ void OnMessage(rtc::Message*);
+};
+
+static inline PeerConnectionFactoryAndThreads& staticFactoryAndThreads()
+{
+ static NeverDestroyed<PeerConnectionFactoryAndThreads> factoryAndThreads;
+ return factoryAndThreads.get();
+}
+
+struct ThreadMessageData : public rtc::MessageData {
+ ThreadMessageData(Function<void()>&& callback)
+ : callback(WTFMove(callback))
+ { }
+ Function<void()> callback;
+};
+
+void PeerConnectionFactoryAndThreads::OnMessage(rtc::Message* message)
+{
+ ASSERT(message->message_id == 1);
+ static_cast<ThreadMessageData*>(message->pdata)->callback();
+}
+
+void LibWebRTCProvider::callOnWebRTCNetworkThread(Function<void()>&& callback)
+{
+ PeerConnectionFactoryAndThreads& threads = staticFactoryAndThreads();
+ threads.networkThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
+}
+
+void LibWebRTCProvider::callOnWebRTCSignalingThread(Function<void()>&& callback)
+{
+ PeerConnectionFactoryAndThreads& threads = staticFactoryAndThreads();
+ threads.signalingThread->Post(RTC_FROM_HERE, &threads, 1, new ThreadMessageData(WTFMove(callback)));
+}
+
+static void initializePeerConnectionFactoryAndThreads()
+{
+ auto& factoryAndThreads = staticFactoryAndThreads();
+
+ ASSERT(!factoryAndThreads.factory);
+
+ auto thread = rtc::Thread::Create();
+ factoryAndThreads.networkThread = factoryAndThreads.networkThreadWithSocketServer ? rtc::Thread::CreateWithSocketServer() : rtc::Thread::Create();
+ bool result = factoryAndThreads.networkThread->Start();
+ ASSERT_UNUSED(result, result);
+
+ factoryAndThreads.signalingThread = rtc::Thread::Create();
+ result = factoryAndThreads.signalingThread->Start();
+ ASSERT(result);
+
+ factoryAndThreads.audioDeviceModule = std::make_unique<LibWebRTCAudioModule>();
+
+ factoryAndThreads.factory = webrtc::CreatePeerConnectionFactory(factoryAndThreads.networkThread.get(), factoryAndThreads.networkThread.get(), factoryAndThreads.signalingThread.get(), factoryAndThreads.audioDeviceModule.get(), new webrtc::VideoToolboxVideoEncoderFactory(), new webrtc::VideoToolboxVideoDecoderFactory());
+
+ ASSERT(factoryAndThreads.factory);
+}
+
+webrtc::PeerConnectionFactoryInterface& LibWebRTCProvider::factory()
+{
+ if (!staticFactoryAndThreads().factory)
+ initializePeerConnectionFactoryAndThreads();
+ return *staticFactoryAndThreads().factory;
+}
+
+void LibWebRTCProvider::setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&& factory)
+{
+ if (!staticFactoryAndThreads().factory)
+ initializePeerConnectionFactoryAndThreads();
+
+ staticFactoryAndThreads().factory = webrtc::PeerConnectionFactoryProxy::Create(staticFactoryAndThreads().signalingThread.get(), WTFMove(factory));
+}
+
+static rtc::scoped_refptr<webrtc::PeerConnectionInterface> createActualPeerConnection(webrtc::PeerConnectionObserver& observer, std::unique_ptr<cricket::BasicPortAllocator>&& portAllocator)
+{
+ ASSERT(staticFactoryAndThreads().factory);
+
+ webrtc::PeerConnectionInterface::RTCConfiguration config;
+ // FIXME: Add a default configuration.
+ return staticFactoryAndThreads().factory->CreatePeerConnection(config, WTFMove(portAllocator), nullptr, &observer);
+}
+
+rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer)
+{
+ // Default WK1 implementation.
+ auto& factoryAndThreads = staticFactoryAndThreads();
+ if (!factoryAndThreads.factory) {
+ staticFactoryAndThreads().networkThreadWithSocketServer = true;
+ initializePeerConnectionFactoryAndThreads();
+ }
+ ASSERT(staticFactoryAndThreads().networkThreadWithSocketServer);
+
+ return createActualPeerConnection(observer, nullptr);
+}
+
+rtc::scoped_refptr<webrtc::PeerConnectionInterface> LibWebRTCProvider::createPeerConnection(webrtc::PeerConnectionObserver& observer, rtc::NetworkManager& networkManager, rtc::PacketSocketFactory& packetSocketFactory)
+{
+ ASSERT(!staticFactoryAndThreads().networkThreadWithSocketServer);
+
+ auto& factoryAndThreads = staticFactoryAndThreads();
+ if (!factoryAndThreads.factory)
+ initializePeerConnectionFactoryAndThreads();
+
+ std::unique_ptr<cricket::BasicPortAllocator> portAllocator;
+ staticFactoryAndThreads().signalingThread->Invoke<void>(RTC_FROM_HERE, [&]() {
+ portAllocator.reset(new cricket::BasicPortAllocator(&networkManager, &packetSocketFactory));
+ });
+
+ return createActualPeerConnection(observer, WTFMove(portAllocator));
+}
+
+} // namespace WebCore
+
+#endif // USE(LIBWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
new file mode 100644
index 000000000..dca1c2275
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/libwebrtc/LibWebRTCProvider.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "LibWebRTCMacros.h"
+#include <wtf/Forward.h>
+
+#if USE(LIBWEBRTC)
+
+#include <webrtc/api/peerconnectioninterface.h>
+#include <webrtc/base/scoped_ref_ptr.h>
+
+namespace rtc {
+class NetworkManager;
+class PacketSocketFactory;
+}
+
+namespace webrtc {
+class PeerConnectionFactoryInterface;
+}
+#endif
+
+namespace WebCore {
+
+class WEBCORE_EXPORT LibWebRTCProvider {
+public:
+ LibWebRTCProvider() = default;
+ virtual ~LibWebRTCProvider() = default;
+
+#if USE(LIBWEBRTC)
+ WEBCORE_EXPORT virtual rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&);
+
+ // FIXME: Make these methods not static.
+ static WEBCORE_EXPORT void callOnWebRTCNetworkThread(Function<void()>&&);
+ static WEBCORE_EXPORT void callOnWebRTCSignalingThread(Function<void()>&&);
+ static WEBCORE_EXPORT webrtc::PeerConnectionFactoryInterface& factory();
+ // Used for mock testing
+ static void setPeerConnectionFactory(rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>&&);
+
+protected:
+ WEBCORE_EXPORT rtc::scoped_refptr<webrtc::PeerConnectionInterface> createPeerConnection(webrtc::PeerConnectionObserver&, rtc::NetworkManager&, rtc::PacketSocketFactory&);
+#endif
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp
new file mode 100644
index 000000000..44839d13a
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.cpp
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2015, 2016 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(WEB_RTC)
+#include "MediaEndpointOwr.h"
+
+#include "MediaEndpointSessionConfiguration.h"
+#include "MediaPayload.h"
+#include "NotImplemented.h"
+#include "OpenWebRTCUtilities.h"
+#include "PeerConnectionStates.h"
+#include "RTCDataChannelHandler.h"
+#include "RealtimeAudioSourceOwr.h"
+#include "RealtimeVideoSourceOwr.h"
+#include <owr/owr.h>
+#include <owr/owr_audio_payload.h>
+#include <owr/owr_crypto_utils.h>
+#include <owr/owr_media_session.h>
+#include <owr/owr_transport_agent.h>
+#include <owr/owr_video_payload.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+static void gotCandidate(OwrSession*, OwrCandidate*, MediaEndpointOwr*);
+static void candidateGatheringDone(OwrSession*, MediaEndpointOwr*);
+static void iceConnectionStateChange(OwrSession*, GParamSpec*, MediaEndpointOwr*);
+static void gotIncomingSource(OwrMediaSession*, OwrMediaSource*, MediaEndpointOwr*);
+
+static const Vector<String> candidateTypes = { "host", "srflx", "prflx", "relay" };
+static const Vector<String> candidateTcpTypes = { "", "active", "passive", "so" };
+static const Vector<String> codecTypes = { "NONE", "PCMU", "PCMA", "OPUS", "H264", "VP8" };
+
+static const char* helperServerRegEx = "(turns|turn|stun):([\\w\\.\\-]+|\\[[\\w\\:]+\\])(:\\d+)?(\\?.+)?";
+
+static const unsigned short helperServerDefaultPort = 3478;
+static const unsigned short candidateDefaultPort = 9;
+
+static std::unique_ptr<MediaEndpoint> createMediaEndpointOwr(MediaEndpointClient& client)
+{
+ return std::unique_ptr<MediaEndpoint>(new MediaEndpointOwr(client));
+}
+
+CreateMediaEndpoint MediaEndpoint::create = createMediaEndpointOwr;
+
+MediaEndpointOwr::MediaEndpointOwr(MediaEndpointClient& client)
+ : m_transportAgent(nullptr)
+ , m_client(client)
+ , m_numberOfReceivePreparedSessions(0)
+ , m_numberOfSendPreparedSessions(0)
+{
+ initializeOpenWebRTC();
+
+ GRegexCompileFlags compileFlags = G_REGEX_JAVASCRIPT_COMPAT;
+ GRegexMatchFlags matchFlags = static_cast<GRegexMatchFlags>(0);
+ m_helperServerRegEx = g_regex_new(helperServerRegEx, compileFlags, matchFlags, nullptr);
+}
+
+MediaEndpointOwr::~MediaEndpointOwr()
+{
+ stop();
+
+ g_regex_unref(m_helperServerRegEx);
+}
+
+void MediaEndpointOwr::setConfiguration(MediaEndpointConfiguration&& configuration)
+{
+ m_configuration = WTFMove(configuration);
+}
+
+std::unique_ptr<RTCDataChannelHandler> MediaEndpointOwr::createDataChannelHandler(const String&, const RTCDataChannelInit&)
+{
+ // FIXME: Implement data channel.
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+static void cryptoDataCallback(gchar* privateKey, gchar* certificate, gchar* fingerprint, gchar* fingerprintFunction, gpointer data)
+{
+ MediaEndpointOwr* mediaEndpoint = (MediaEndpointOwr*) data;
+ mediaEndpoint->dispatchDtlsFingerprint(g_strdup(privateKey), g_strdup(certificate), String(fingerprint), String(fingerprintFunction));
+}
+
+void MediaEndpointOwr::generateDtlsInfo()
+{
+ owr_crypto_create_crypto_data(cryptoDataCallback, this);
+}
+
+MediaPayloadVector MediaEndpointOwr::getDefaultAudioPayloads()
+{
+ MediaPayloadVector payloads;
+
+ // FIXME: This list should be based on what is available in the platform (bug: http://webkit.org/b/163723)
+ MediaPayload payload1;
+ payload1.type = 111;
+ payload1.encodingName = "OPUS";
+ payload1.clockRate = 48000;
+ payload1.channels = 2;
+ payloads.append(WTFMove(payload1));
+
+ MediaPayload payload2;
+ payload2.type = 8;
+ payload2.encodingName = "PCMA";
+ payload2.clockRate = 8000;
+ payload2.channels = 1;
+ payloads.append(WTFMove(payload2));
+
+ MediaPayload payload3;
+ payload3.type = 0;
+ payload3.encodingName = "PCMU";
+ payload3.clockRate = 8000;
+ payload3.channels = 1;
+ payloads.append(WTFMove(payload3));
+
+ return payloads;
+}
+
+MediaPayloadVector MediaEndpointOwr::getDefaultVideoPayloads()
+{
+ MediaPayloadVector payloads;
+
+ // FIXME: This list should be based on what is available in the platform (bug: http://webkit.org/b/163723)
+ MediaPayload payload1;
+ payload1.type = 103;
+ payload1.encodingName = "H264";
+ payload1.clockRate = 90000;
+ payload1.ccmfir = true;
+ payload1.nackpli = true;
+ payload1.addParameter("packetizationMode", 1);
+ payloads.append(WTFMove(payload1));
+
+ MediaPayload payload2;
+ payload2.type = 100;
+ payload2.encodingName = "VP8";
+ payload2.clockRate = 90000;
+ payload2.ccmfir = true;
+ payload2.nackpli = true;
+ payload2.nack = true;
+ payloads.append(WTFMove(payload2));
+
+ MediaPayload payload3;
+ payload3.type = 120;
+ payload3.encodingName = "RTX";
+ payload3.clockRate = 90000;
+ payload3.addParameter("apt", 100);
+ payload3.addParameter("rtxTime", 200);
+ payloads.append(WTFMove(payload3));
+
+ return payloads;
+}
+
+static bool payloadsContainType(const Vector<const MediaPayload*>& payloads, unsigned payloadType)
+{
+ for (auto payload : payloads) {
+ ASSERT(payload);
+ if (payload->type == payloadType)
+ return true;
+ }
+ return false;
+}
+
+MediaPayloadVector MediaEndpointOwr::filterPayloads(const MediaPayloadVector& remotePayloads, const MediaPayloadVector& defaultPayloads)
+{
+ Vector<const MediaPayload*> filteredPayloads;
+
+ for (auto& remotePayload : remotePayloads) {
+ const MediaPayload* defaultPayload = nullptr;
+ for (auto& p : defaultPayloads) {
+ if (p.encodingName == remotePayload.encodingName.convertToASCIIUppercase()) {
+ defaultPayload = &p;
+ 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);
+ }
+
+ MediaPayloadVector filteredAptPayloads;
+
+ for (auto filteredPayload : filteredPayloads) {
+ if (filteredPayload->parameters.contains("apt") && (!payloadsContainType(filteredPayloads, filteredPayload->parameters.get("apt"))))
+ continue;
+ filteredAptPayloads.append(*filteredPayload);
+ }
+
+ return filteredAptPayloads;
+}
+
+MediaEndpoint::UpdateResult MediaEndpointOwr::updateReceiveConfiguration(MediaEndpointSessionConfiguration* configuration, bool isInitiator)
+{
+ Vector<TransceiverConfig> transceiverConfigs;
+ for (unsigned i = m_transceivers.size(); i < configuration->mediaDescriptions().size(); ++i) {
+ TransceiverConfig config;
+ config.type = SessionTypeMedia;
+ config.isDtlsClient = configuration->mediaDescriptions()[i].dtlsSetup == "active";
+ config.mid = configuration->mediaDescriptions()[i].mid;
+ transceiverConfigs.append(WTFMove(config));
+ }
+
+ ensureTransportAgentAndTransceivers(isInitiator, transceiverConfigs);
+
+ // Prepare the new sessions.
+ for (unsigned i = m_numberOfReceivePreparedSessions; i < m_transceivers.size(); ++i) {
+ OwrSession* session = m_transceivers[i]->session();
+ prepareMediaSession(OWR_MEDIA_SESSION(session), &configuration->mediaDescriptions()[i], isInitiator);
+ owr_transport_agent_add_session(m_transportAgent, session);
+ }
+
+ owr_transport_agent_start(m_transportAgent);
+ m_numberOfReceivePreparedSessions = m_transceivers.size();
+
+ return UpdateResult::Success;
+}
+
+static const MediaPayload* findRtxPayload(const MediaPayloadVector& payloads, unsigned apt)
+{
+ for (auto& payload : payloads) {
+ if (payload.encodingName.convertToASCIIUppercase() == "RTX" && payload.parameters.contains("apt")
+ && (payload.parameters.get("apt") == apt))
+ return &payload;
+ }
+ return nullptr;
+}
+
+MediaEndpoint::UpdateResult MediaEndpointOwr::updateSendConfiguration(MediaEndpointSessionConfiguration* configuration, const RealtimeMediaSourceMap& sendSourceMap, bool isInitiator)
+{
+ Vector<TransceiverConfig> transceiverConfigs;
+ for (unsigned i = m_transceivers.size(); i < configuration->mediaDescriptions().size(); ++i) {
+ TransceiverConfig config;
+ config.type = SessionTypeMedia;
+ config.isDtlsClient = configuration->mediaDescriptions()[i].dtlsSetup != "active";
+ config.mid = configuration->mediaDescriptions()[i].mid;
+ transceiverConfigs.append(WTFMove(config));
+ }
+
+ ensureTransportAgentAndTransceivers(isInitiator, transceiverConfigs);
+
+ for (unsigned i = 0; i < m_transceivers.size(); ++i) {
+ auto* session = m_transceivers[i]->session();
+ auto& 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 (!sendSourceMap.contains(mdesc.mid))
+ continue;
+
+ const MediaPayload* payload = nullptr;
+ for (auto& p : mdesc.payloads) {
+ if (p.encodingName.convertToASCIIUppercase() != "RTX") {
+ payload = &p;
+ break;
+ }
+ }
+
+ if (!payload)
+ return UpdateResult::Failed;
+
+ auto* rtxPayload = findRtxPayload(mdesc.payloads, payload->type);
+ auto* source = static_cast<RealtimeMediaSourceOwr*>(sendSourceMap.get(mdesc.mid));
+
+ ASSERT(codecTypes.find(payload->encodingName.convertToASCIIUppercase()) != notFound);
+ auto codecType = static_cast<OwrCodecType>(codecTypes.find(payload->encodingName.convertToASCIIUppercase()));
+
+ 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);
+ owr_media_session_set_send_source(OWR_MEDIA_SESSION(session), source->mediaSource());
+
+ // FIXME: Support for group-ssrc SDP line is missing.
+ const Vector<unsigned> receiveSsrcs = mdesc.ssrcs;
+ if (receiveSsrcs.size()) {
+ g_object_set(session, "receive-ssrc", receiveSsrcs[0], nullptr);
+ if (receiveSsrcs.size() == 2)
+ g_object_set(session, "receive-rtx-ssrc", receiveSsrcs[1], nullptr);
+ }
+
+ m_numberOfSendPreparedSessions = i + 1;
+ }
+
+ return UpdateResult::Success;
+}
+
+void MediaEndpointOwr::addRemoteCandidate(const IceCandidate& candidate, const String& mid, const String& ufrag, const String& password)
+{
+ for (auto& transceiver : m_transceivers) {
+ if (transceiver->mid() == mid) {
+ internalAddRemoteCandidate(transceiver->session(), candidate, ufrag, password);
+ break;
+ }
+ }
+}
+
+void MediaEndpointOwr::replaceMutedRemoteSourceMid(const String& oldMid, const String& newMid)
+{
+ RefPtr<RealtimeMediaSourceOwr> remoteSource = m_mutedRemoteSources.take(oldMid);
+ m_mutedRemoteSources.set(newMid, remoteSource);
+}
+
+Ref<RealtimeMediaSource> MediaEndpointOwr::createMutedRemoteSource(const String& mid, RealtimeMediaSource::Type type)
+{
+ String name;
+ String id("not used");
+ RefPtr<RealtimeMediaSourceOwr> source;
+
+ switch (type) {
+ case RealtimeMediaSource::Audio:
+ name = "remote audio";
+ source = adoptRef(new RealtimeAudioSourceOwr(nullptr, id, type, name));
+ break;
+ case RealtimeMediaSource::Video:
+ name = "remote video";
+ source = adoptRef(new RealtimeVideoSourceOwr(nullptr, id, type, name));
+ break;
+ case RealtimeMediaSource::None:
+ ASSERT_NOT_REACHED();
+ }
+
+ m_mutedRemoteSources.set(mid, source);
+
+ return *source;
+}
+
+void MediaEndpointOwr::replaceSendSource(RealtimeMediaSource& newSource, const String& mid)
+{
+ UNUSED_PARAM(newSource);
+ UNUSED_PARAM(mid);
+
+ // FIXME: We want to use owr_media_session_set_send_source here, but it doesn't work as intended.
+ // Issue tracked by OpenWebRTC bug: https://github.com/EricssonResearch/openwebrtc/issues/533
+
+ notImplemented();
+}
+
+void MediaEndpointOwr::stop()
+{
+ if (!m_transportAgent)
+ return;
+
+ for (auto& transceiver : m_transceivers)
+ owr_media_session_set_send_source(OWR_MEDIA_SESSION(transceiver->session()), nullptr);
+
+ g_object_unref(m_transportAgent);
+ m_transportAgent = nullptr;
+}
+
+size_t MediaEndpointOwr::transceiverIndexForSession(OwrSession* session) const
+{
+ for (unsigned i = 0; i < m_transceivers.size(); ++i) {
+ if (m_transceivers[i]->session() == session)
+ return i;
+ }
+
+ ASSERT_NOT_REACHED();
+ return notFound;
+}
+
+const String& MediaEndpointOwr::sessionMid(OwrSession* session) const
+{
+ size_t index = transceiverIndexForSession(session);
+ return m_transceivers[index]->mid();
+}
+
+OwrTransceiver* MediaEndpointOwr::matchTransceiverByMid(const String& mid) const
+{
+ for (auto& transceiver : m_transceivers) {
+ if (transceiver->mid() == mid)
+ return transceiver.get();
+ }
+ return nullptr;
+}
+
+void MediaEndpointOwr::dispatchNewIceCandidate(const String& mid, IceCandidate&& iceCandidate)
+{
+ m_client.gotIceCandidate(mid, WTFMove(iceCandidate));
+}
+
+void MediaEndpointOwr::dispatchGatheringDone(const String& mid)
+{
+ m_client.doneGatheringCandidates(mid);
+}
+
+void MediaEndpointOwr::processIceTransportStateChange(OwrSession* session)
+{
+ OwrIceState owrIceState;
+ g_object_get(session, "ice-connection-state", &owrIceState, nullptr);
+
+ OwrTransceiver& transceiver = *m_transceivers[transceiverIndexForSession(session)];
+ if (owrIceState < transceiver.owrIceState())
+ return;
+
+ transceiver.setOwrIceState(owrIceState);
+
+ // We cannot go to Completed if there may be more remote candidates.
+ if (owrIceState == OWR_ICE_STATE_READY && !transceiver.gotEndOfRemoteCandidates())
+ return;
+
+ MediaEndpoint::IceTransportState transportState;
+ switch (owrIceState) {
+ case OWR_ICE_STATE_CONNECTING:
+ transportState = MediaEndpoint::IceTransportState::Checking;
+ break;
+ case OWR_ICE_STATE_CONNECTED:
+ transportState = MediaEndpoint::IceTransportState::Connected;
+ break;
+ case OWR_ICE_STATE_READY:
+ transportState = MediaEndpoint::IceTransportState::Completed;
+ break;
+ case OWR_ICE_STATE_FAILED:
+ transportState = MediaEndpoint::IceTransportState::Failed;
+ break;
+ default:
+ return;
+ }
+
+ m_client.iceTransportStateChanged(transceiver.mid(), transportState);
+}
+
+void MediaEndpointOwr::dispatchDtlsFingerprint(gchar* privateKey, gchar* certificate, const String& fingerprint, const String& fingerprintFunction)
+{
+ m_dtlsPrivateKey = String(privateKey);
+ m_dtlsCertificate = String(certificate);
+
+ g_free(privateKey);
+ g_free(certificate);
+
+ m_client.gotDtlsFingerprint(fingerprint, fingerprintFunction);
+}
+
+void MediaEndpointOwr::unmuteRemoteSource(const String& mid, OwrMediaSource* realSource)
+{
+ RefPtr<RealtimeMediaSourceOwr> remoteSource = m_mutedRemoteSources.take(mid);
+ if (!remoteSource) {
+ LOG_ERROR("Unable to find muted remote source.");
+ return;
+ }
+
+ if (!remoteSource->stopped())
+ remoteSource->swapOutShallowSource(*realSource);
+}
+
+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::ice-connection-state", G_CALLBACK(iceConnectionStateChange), this);
+}
+
+void MediaEndpointOwr::prepareMediaSession(OwrMediaSession* mediaSession, PeerMediaDescription* mediaDescription, bool isInitiator)
+{
+ prepareSession(OWR_SESSION(mediaSession), mediaDescription);
+
+ bool useRtcpMux = !isInitiator && mediaDescription->rtcpMux;
+ g_object_set(mediaSession, "rtcp-mux", useRtcpMux, nullptr);
+
+ if (!mediaDescription->cname.isEmpty() && mediaDescription->ssrcs.size()) {
+ g_object_set(mediaSession, "cname", mediaDescription->cname.ascii().data(),
+ "send-ssrc", mediaDescription->ssrcs[0],
+ nullptr);
+ }
+
+ g_signal_connect(mediaSession, "on-incoming-source", G_CALLBACK(gotIncomingSource), this);
+
+ for (auto& payload : mediaDescription->payloads) {
+ if (payload.encodingName.convertToASCIIUppercase() == "RTX")
+ continue;
+
+ auto* rtxPayload = findRtxPayload(mediaDescription->payloads, payload.type);
+
+ ASSERT(codecTypes.find(payload.encodingName) != notFound);
+ OwrCodecType codecType = static_cast<OwrCodecType>(codecTypes.find(payload.encodingName.convertToASCIIUppercase()));
+
+ 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);
+ }
+}
+
+struct HelperServerUrl {
+ String protocol;
+ String host;
+ unsigned short port;
+ String query;
+};
+
+static void parseHelperServerUrl(GRegex& regex, const URL& url, HelperServerUrl& outUrl)
+{
+ GMatchInfo* matchInfo;
+
+ if (g_regex_match(&regex, url.string().ascii().data(), static_cast<GRegexMatchFlags>(0), &matchInfo)) {
+ gchar** matches = g_match_info_fetch_all(matchInfo);
+ gint matchCount = g_strv_length(matches);
+
+ outUrl.protocol = matches[1];
+ outUrl.host = matches[2][0] == '[' ? String(matches[2] + 1, strlen(matches[2]) - 2) // IPv6
+ : matches[2];
+
+ outUrl.port = 0;
+ if (matchCount >= 4) {
+ String portString = String(matches[3] + 1); // Skip port colon
+ outUrl.port = portString.toUIntStrict();
+ }
+
+ if (matchCount == 5)
+ outUrl.query = String(matches[4] + 1); // Skip question mark
+
+ g_strfreev(matches);
+ }
+
+ g_match_info_free(matchInfo);
+}
+
+void MediaEndpointOwr::ensureTransportAgentAndTransceivers(bool isInitiator, const Vector<TransceiverConfig>& transceiverConfigs)
+{
+ ASSERT(m_dtlsPrivateKey);
+ ASSERT(m_dtlsCertificate);
+
+ if (!m_transportAgent) {
+ // FIXME: Handle SDP BUNDLE line from the remote source instead of falling back to balanced.
+ OwrBundlePolicyType bundlePolicy = OWR_BUNDLE_POLICY_TYPE_BALANCED;
+
+ switch (m_configuration->bundlePolicy) {
+ case PeerConnectionStates::BundlePolicy::Balanced:
+ bundlePolicy = OWR_BUNDLE_POLICY_TYPE_BALANCED;
+ break;
+ case PeerConnectionStates::BundlePolicy::MaxCompat:
+ bundlePolicy = OWR_BUNDLE_POLICY_TYPE_MAX_COMPAT;
+ break;
+ case PeerConnectionStates::BundlePolicy::MaxBundle:
+ bundlePolicy = OWR_BUNDLE_POLICY_TYPE_MAX_BUNDLE;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ };
+
+ m_transportAgent = owr_transport_agent_new(false, bundlePolicy);
+
+ ASSERT(m_configuration);
+ for (auto& server : m_configuration->iceServers) {
+ for (auto& webkitUrl : server.urls) {
+ HelperServerUrl url;
+ // WebKit's URL class can't handle ICE helper server urls properly
+ parseHelperServerUrl(*m_helperServerRegEx, webkitUrl, url);
+
+ unsigned short port = url.port ? url.port : helperServerDefaultPort;
+
+ if (url.protocol == "stun") {
+ owr_transport_agent_add_helper_server(m_transportAgent, OWR_HELPER_SERVER_TYPE_STUN,
+ url.host.ascii().data(), port, nullptr, nullptr);
+
+ } else if (url.protocol == "turn") {
+ OwrHelperServerType serverType = url.query == "transport=tcp" ? OWR_HELPER_SERVER_TYPE_TURN_TCP
+ : OWR_HELPER_SERVER_TYPE_TURN_UDP;
+
+ owr_transport_agent_add_helper_server(m_transportAgent, serverType,
+ url.host.ascii().data(), port,
+ server.username.ascii().data(), server.credential.ascii().data());
+ } else if (url.protocol == "turns") {
+ owr_transport_agent_add_helper_server(m_transportAgent, OWR_HELPER_SERVER_TYPE_TURN_TLS,
+ url.host.ascii().data(), port,
+ server.username.ascii().data(), server.credential.ascii().data());
+ } else
+ ASSERT_NOT_REACHED();
+ }
+ }
+ }
+
+ g_object_set(m_transportAgent, "ice-controlling-mode", isInitiator, nullptr);
+
+ for (auto& config : transceiverConfigs) {
+ OwrSession* session = OWR_SESSION(owr_media_session_new(config.isDtlsClient));
+ g_object_set(session, "dtls-certificate", m_dtlsCertificate.utf8().data(),
+ "dtls-key", m_dtlsPrivateKey.utf8().data(),
+ nullptr);
+
+ m_transceivers.append(OwrTransceiver::create(config.mid, session));
+ }
+}
+
+void MediaEndpointOwr::internalAddRemoteCandidate(OwrSession* session, const 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);
+
+ OwrCandidateType candidateType = static_cast<OwrCandidateType>(candidateTypes.find(candidate.type));
+ OwrComponentType componentId = static_cast<OwrComponentType>(candidate.componentId);
+ OwrTransportType transportType;
+
+ if (candidate.transport.convertToASCIIUppercase() == "UDP")
+ transportType = OWR_TRANSPORT_TYPE_UDP;
+ else {
+ ASSERT(candidateTcpTypes.find(candidate.tcpType) != notFound);
+ transportType = static_cast<OwrTransportType>(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;
+ gchar* foundation;
+ OwrComponentType componentId;
+ OwrTransportType transportType;
+ gint priority;
+ gchar* address;
+ guint port;
+ gchar* relatedAddress;
+ guint relatedPort;
+
+ g_object_get(candidate, "type", &candidateType,
+ "foundation", &foundation,
+ "component-type", &componentId,
+ "transport-type", &transportType,
+ "priority", &priority,
+ "address", &address,
+ "port", &port,
+ "base-address", &relatedAddress,
+ "base-port", &relatedPort,
+ nullptr);
+
+ ASSERT(candidateType >= 0 && candidateType < candidateTypes.size());
+ ASSERT(transportType >= 0 && transportType < candidateTcpTypes.size());
+
+ IceCandidate iceCandidate;
+ iceCandidate.type = candidateTypes[candidateType];
+ iceCandidate.foundation = foundation;
+ iceCandidate.componentId = componentId;
+ iceCandidate.priority = priority;
+ iceCandidate.address = address;
+ iceCandidate.port = port ? port : candidateDefaultPort;
+
+ if (transportType == OWR_TRANSPORT_TYPE_UDP)
+ iceCandidate.transport = "UDP";
+ else {
+ iceCandidate.transport = "TCP";
+ iceCandidate.tcpType = candidateTcpTypes[transportType];
+ }
+
+ if (candidateType != OWR_CANDIDATE_TYPE_HOST) {
+ iceCandidate.relatedAddress = relatedAddress;
+ iceCandidate.relatedPort = relatedPort ? relatedPort : candidateDefaultPort;
+ }
+
+ 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->sessionMid(session), WTFMove(iceCandidate));
+
+ g_free(foundation);
+ g_free(address);
+ g_free(relatedAddress);
+}
+
+static void candidateGatheringDone(OwrSession* session, MediaEndpointOwr* mediaEndpoint)
+{
+ mediaEndpoint->dispatchGatheringDone(mediaEndpoint->sessionMid(session));
+}
+
+static void iceConnectionStateChange(OwrSession* session, GParamSpec*, MediaEndpointOwr* mediaEndpoint)
+{
+ mediaEndpoint->processIceTransportStateChange(session);
+}
+
+static void gotIncomingSource(OwrMediaSession* mediaSession, OwrMediaSource* source, MediaEndpointOwr* mediaEndpoint)
+{
+ mediaEndpoint->unmuteRemoteSource(mediaEndpoint->sessionMid(OWR_SESSION(mediaSession)), source);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h
new file mode 100644
index 000000000..f31048c9e
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/MediaEndpointOwr.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2015, 2016 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEB_RTC)
+
+#include "MediaEndpoint.h"
+#include <owr/owr_session.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+
+typedef struct _OwrMediaSession OwrMediaSession;
+typedef struct _OwrMediaSource OwrMediaSource;
+typedef struct _OwrTransportAgent OwrTransportAgent;
+
+namespace WebCore {
+
+class RealtimeMediaSourceOwr;
+class RTCConfigurationPrivate;
+
+struct PeerMediaDescription;
+
+class OwrTransceiver : public RefCounted<OwrTransceiver> {
+public:
+ static Ref<OwrTransceiver> create(const String& mid, OwrSession* session)
+ {
+ return adoptRef(*new OwrTransceiver(mid, session));
+ }
+ virtual ~OwrTransceiver() { }
+
+ const String& mid() const { return m_mid; }
+ OwrSession* session() const { return m_session; }
+
+ OwrIceState owrIceState() const { return m_owrIceState; }
+ void setOwrIceState(OwrIceState state) { m_owrIceState = state; }
+
+ bool gotEndOfRemoteCandidates() const { return m_gotEndOfRemoteCandidates; }
+ void markGotEndOfRemoteCandidates() { m_gotEndOfRemoteCandidates = true; }
+
+private:
+ OwrTransceiver(const String& mid, OwrSession* session)
+ : m_mid(mid)
+ , m_session(session)
+ { }
+
+ String m_mid;
+ OwrSession* m_session;
+
+ OwrIceState m_owrIceState { OWR_ICE_STATE_DISCONNECTED };
+ bool m_gotEndOfRemoteCandidates { false };
+};
+
+class MediaEndpointOwr : public MediaEndpoint {
+public:
+ MediaEndpointOwr(MediaEndpointClient&);
+ ~MediaEndpointOwr();
+
+ void setConfiguration(MediaEndpointConfiguration&&) override;
+
+ void generateDtlsInfo() override;
+ MediaPayloadVector getDefaultAudioPayloads() override;
+ MediaPayloadVector getDefaultVideoPayloads() override;
+ MediaPayloadVector filterPayloads(const MediaPayloadVector& remotePayloads, const MediaPayloadVector& defaultPayloads) override;
+
+ UpdateResult updateReceiveConfiguration(MediaEndpointSessionConfiguration*, bool isInitiator) override;
+ UpdateResult updateSendConfiguration(MediaEndpointSessionConfiguration*, const RealtimeMediaSourceMap&, bool isInitiator) override;
+
+ void addRemoteCandidate(const IceCandidate&, const String& mid, const String& ufrag, const String& password) override;
+
+ Ref<RealtimeMediaSource> createMutedRemoteSource(const String& mid, RealtimeMediaSource::Type) override;
+ void replaceMutedRemoteSourceMid(const String&, const String&) final;
+ void replaceSendSource(RealtimeMediaSource&, const String& mid) override;
+
+ void stop() override;
+
+ size_t transceiverIndexForSession(OwrSession*) const;
+ const String& sessionMid(OwrSession*) const;
+ OwrTransceiver* matchTransceiverByMid(const String& mid) const;
+
+ void dispatchNewIceCandidate(const String& mid, IceCandidate&&);
+ void dispatchGatheringDone(const String& mid);
+ void processIceTransportStateChange(OwrSession*);
+ void dispatchDtlsFingerprint(gchar* privateKey, gchar* certificate, const String& fingerprint, const String& fingerprintFunction);
+ void unmuteRemoteSource(const String& mid, OwrMediaSource*);
+
+private:
+ enum SessionType { SessionTypeMedia };
+
+ struct TransceiverConfig {
+ SessionType type;
+ bool isDtlsClient;
+ String mid;
+ };
+
+ std::unique_ptr<RTCDataChannelHandler> createDataChannelHandler(const String&, const RTCDataChannelInit&) final;
+
+ void prepareSession(OwrSession*, PeerMediaDescription*);
+ void prepareMediaSession(OwrMediaSession*, PeerMediaDescription*, bool isInitiator);
+
+ void ensureTransportAgentAndTransceivers(bool isInitiator, const Vector<TransceiverConfig>&);
+ void internalAddRemoteCandidate(OwrSession*, const IceCandidate&, const String& ufrag, const String& password);
+
+ std::optional<MediaEndpointConfiguration> m_configuration;
+ GRegex* m_helperServerRegEx;
+
+ OwrTransportAgent* m_transportAgent;
+ Vector<RefPtr<OwrTransceiver>> m_transceivers;
+ HashMap<String, RefPtr<RealtimeMediaSourceOwr>> m_mutedRemoteSources;
+
+ MediaEndpointClient& m_client;
+
+ unsigned m_numberOfReceivePreparedSessions;
+ unsigned m_numberOfSendPreparedSessions;
+
+ String m_dtlsPrivateKey;
+ String m_dtlsCertificate;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_RTC)
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp
new file mode 100644
index 000000000..e4cfb59df
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 Igalia S.L
+ * Copyright (C) 2015 Metrological
+ *
+ * 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 the copyright holder 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
+ * HOLDER 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 USE(OPENWEBRTC)
+#include "OpenWebRTCUtilities.h"
+
+#include <owr/owr.h>
+
+namespace WebCore {
+
+void initializeOpenWebRTC()
+{
+ static bool isInitialized = false;
+ if (isInitialized)
+ return;
+
+ owr_init(g_main_context_default());
+ isInitialized = true;
+}
+
+}
+
+#endif // USE(OPENWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.h b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.h
new file mode 100644
index 000000000..bed474bbf
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/OpenWebRTCUtilities.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 Igalia S.L
+ * Copyright (C) 2015 Metrological
+ *
+ * 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 the copyright holder 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
+ * HOLDER 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.
+ */
+
+
+namespace WebCore {
+
+void initializeOpenWebRTC();
+
+}
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h
new file mode 100644
index 000000000..2349f051b
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeAudioSourceOwr.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015,2016 Igalia S.L
+ * Copyright (C) 2015 Metrological
+ *
+ * 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 the copyright holder 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
+ * HOLDER 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.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
+
+#include "RealtimeMediaSourceOwr.h"
+
+namespace WebCore {
+
+class RealtimeAudioSourceOwr : public RealtimeMediaSourceOwr {
+public:
+RealtimeAudioSourceOwr(OwrMediaSource* mediaSource, const String& id, RealtimeMediaSource::Type type, const String& name)
+ : RealtimeMediaSourceOwr(mediaSource, id, type, name)
+ {
+ }
+
+RealtimeAudioSourceOwr(const String& id, RealtimeMediaSource::Type type, const String& name)
+ : RealtimeMediaSourceOwr(id, type, name)
+ {
+ }
+
+ virtual ~RealtimeAudioSourceOwr() { }
+
+ bool applySize(const IntSize&) final { return false; }
+
+protected:
+ void initializeSettings() final {
+ if (m_currentSettings.deviceId().isEmpty())
+ m_currentSettings.setSupportedConstraits(supportedConstraints());
+
+ m_currentSettings.setDeviceId(id());
+ }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp
new file mode 100644
index 000000000..f3e6f1fed
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2011 Ericsson AB. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2015 Igalia S.L. All rights reserved.
+ * Copyright (C) 2015 Metrological. 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) && USE(OPENWEBRTC)
+#include "RealtimeMediaSourceCenterOwr.h"
+
+#include "CaptureDevice.h"
+#include "MediaStreamPrivate.h"
+#include "NotImplemented.h"
+#include "OpenWebRTCUtilities.h"
+#include "RealtimeAudioSourceOwr.h"
+#include "RealtimeMediaSourceCapabilities.h"
+#include "RealtimeVideoSourceOwr.h"
+#include "UUID.h"
+#include <owr/owr.h>
+#include <owr/owr_local.h>
+#include <owr/owr_media_source.h>
+#include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/glib/GUniquePtr.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringHash.h>
+
+
+namespace WebCore {
+
+RealtimeMediaSourceCenter& RealtimeMediaSourceCenter::platformCenter()
+{
+ ASSERT(isMainThread());
+ static NeverDestroyed<RealtimeMediaSourceCenterOwr> center;
+ return center;
+}
+
+static void mediaSourcesAvailableCallback(GList* sources, gpointer userData)
+{
+ RealtimeMediaSourceCenterOwr* center = reinterpret_cast<RealtimeMediaSourceCenterOwr*>(userData);
+ center->mediaSourcesAvailable(sources);
+}
+
+RealtimeMediaSourceCenterOwr::RealtimeMediaSourceCenterOwr()
+{
+ initializeOpenWebRTC();
+}
+
+RealtimeMediaSourceCenterOwr::~RealtimeMediaSourceCenterOwr()
+{
+}
+
+void RealtimeMediaSourceCenterOwr::validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, const MediaConstraints& audioConstraints, const MediaConstraints& videoConstraints)
+{
+ m_validConstraintsHandler = WTFMove(validHandler);
+ m_invalidConstraintsHandler = WTFMove(invalidHandler);
+
+ Vector<String> audioSources;
+ Vector<String> videoSources;
+
+ // FIXME: Actually do constraints validation. The MediaConstraints
+ // need to comply with the available audio/video device(s)
+ // capabilities. See bug #123345.
+ if (audioConstraints.isValid())
+ audioSources.append(String("audio"));
+
+ if (videoConstraints.isValid())
+ videoSources.append(String("video"));
+
+ m_validConstraintsHandler(WTFMove(audioSources), WTFMove(videoSources));
+ m_validConstraintsHandler = nullptr;
+ m_invalidConstraintsHandler = nullptr;
+}
+
+void RealtimeMediaSourceCenterOwr::createMediaStream(NewMediaStreamHandler completionHandler, const String& audioDeviceID, const String& videoDeviceID, const MediaConstraints*, const MediaConstraints*)
+{
+ int types = OWR_MEDIA_TYPE_UNKNOWN;
+
+ if (!audioDeviceID.isEmpty())
+ types |= OWR_MEDIA_TYPE_AUDIO;
+ if (!videoDeviceID.isEmpty())
+ types |= OWR_MEDIA_TYPE_VIDEO;
+
+ m_completionHandler = completionHandler;
+
+ owr_get_capture_sources(static_cast<OwrMediaType>(types), mediaSourcesAvailableCallback, this);
+}
+
+Vector<CaptureDevice> RealtimeMediaSourceCenterOwr::getMediaStreamDevices()
+{
+ notImplemented();
+ return Vector<CaptureDevice>();
+}
+
+void RealtimeMediaSourceCenterOwr::mediaSourcesAvailable(GList* sources)
+{
+ Vector<Ref<RealtimeMediaSource>> audioSources;
+ Vector<Ref<RealtimeMediaSource>> videoSources;
+
+ for (auto item = sources; item; item = item->next) {
+ OwrMediaSource* source = OWR_MEDIA_SOURCE(item->data);
+
+ GUniqueOutPtr<gchar> name;
+ OwrMediaType mediaType;
+ g_object_get(source, "media-type", &mediaType, "name", &name.outPtr(), NULL);
+ String sourceName(name.get());
+ String id(createCanonicalUUIDString());
+
+ if (g_getenv("OWR_USE_TEST_SOURCES")) {
+ OwrSourceType sourceType = OWR_SOURCE_TYPE_UNKNOWN;
+ g_object_get(source, "type", &sourceType, NULL);
+ if (sourceType != OWR_SOURCE_TYPE_TEST)
+ continue;
+ }
+
+ RealtimeMediaSource::Type mediaSourceType;
+ if (mediaType & OWR_MEDIA_TYPE_AUDIO)
+ mediaSourceType = RealtimeMediaSource::Audio;
+ else if (mediaType & OWR_MEDIA_TYPE_VIDEO)
+ mediaSourceType = RealtimeMediaSource::Video;
+ else {
+ mediaSourceType = RealtimeMediaSource::None;
+ ASSERT_NOT_REACHED();
+ }
+
+ RefPtr<RealtimeMediaSourceOwr> mediaSource;
+ if (mediaSourceType == RealtimeMediaSource::Audio)
+ mediaSource = adoptRef(new RealtimeAudioSourceOwr(source, id, mediaSourceType, sourceName));
+ else
+ mediaSource = adoptRef(new RealtimeVideoSourceOwr(source, id, mediaSourceType, sourceName));
+
+ RealtimeMediaSourceOwrMap::iterator sourceIterator = m_sourceMap.find(id);
+ if (sourceIterator == m_sourceMap.end())
+ m_sourceMap.add(id, mediaSource.copyRef());
+
+ if (mediaType & OWR_MEDIA_TYPE_AUDIO)
+ audioSources.append(mediaSource.releaseNonNull());
+ else if (mediaType & OWR_MEDIA_TYPE_VIDEO)
+ videoSources.append(mediaSource.releaseNonNull());
+
+ }
+
+ if (videoSources.isEmpty() && audioSources.isEmpty())
+ m_completionHandler(nullptr);
+ else
+ m_completionHandler(MediaStreamPrivate::create(audioSources, videoSources));
+
+}
+
+PassRefPtr<RealtimeMediaSource> RealtimeMediaSourceCenterOwr::firstSource(RealtimeMediaSource::Type type)
+{
+ for (auto iter = m_sourceMap.begin(); iter != m_sourceMap.end(); ++iter) {
+ RefPtr<RealtimeMediaSource> source = iter->value;
+ if (source->type() == type)
+ return source;
+ }
+
+ return nullptr;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/gstreamer/MediaStreamCenterGStreamer.cpp b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h
index 5e4f34e84..6cdd7d5fe 100644
--- a/Source/WebCore/platform/mediastream/gstreamer/MediaStreamCenterGStreamer.cpp
+++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h
@@ -1,6 +1,8 @@
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2015 Igalia S.L. All rights reserved.
+ * Copyright (C) 2015 Metrological. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,52 +31,47 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
+#ifndef RealtimeMediaSourceCenterOwr_h
+#define RealtimeMediaSourceCenterOwr_h
-#if ENABLE(MEDIA_STREAM)
+#if ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
-#include "MediaStreamCenterGStreamer.h"
+#include "RealtimeMediaSourceCenter.h"
-#include "MediaStreamCreationClient.h"
-#include "MediaStreamPrivate.h"
-#include "MediaStreamSourceCapabilities.h"
-#include "MediaStreamTrackSourcesRequestClient.h"
-#include "NotImplemented.h"
-#include <wtf/MainThread.h>
+#include "RealtimeMediaSourceOwr.h"
+#include <wtf/PassRefPtr.h>
namespace WebCore {
-MediaStreamCenter& MediaStreamCenter::platformCenter()
-{
- ASSERT(isMainThread());
- DEFINE_STATIC_LOCAL(MediaStreamCenterGStreamer, center, ());
- return center;
-}
+class CaptureDevice;
+class MediaStreamPrivate;
+class RealtimeMediaSource;
+class MediaStreamSourcesQueryClient;
+class TrackSourceInfo;
-MediaStreamCenterGStreamer::MediaStreamCenterGStreamer()
-{
-}
+class RealtimeMediaSourceCenterOwr final : public RealtimeMediaSourceCenter {
+public:
+ RealtimeMediaSourceCenterOwr();
+ ~RealtimeMediaSourceCenterOwr();
-MediaStreamCenterGStreamer::~MediaStreamCenterGStreamer()
-{
-}
+ void validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, const MediaConstraints& audioConstraints, const MediaConstraints& videoConstraints) final;
-void MediaStreamCenterGStreamer::validateRequestConstraints(PassRefPtr<MediaStreamCreationClient>, PassRefPtr<MediaConstraints>, PassRefPtr<MediaConstraints>)
-{
- notImplemented();
-}
-
-void MediaStreamCenterGStreamer::createMediaStream(PassRefPtr<MediaStreamCreationClient>, PassRefPtr<MediaConstraints>, PassRefPtr<MediaConstraints>)
-{
- notImplemented();
-}
+ void createMediaStream(NewMediaStreamHandler, const String& audioDeviceID, const String& videoDeviceID, const MediaConstraints* videoConstraints, const MediaConstraints* audioConstraints) final;
-bool MediaStreamCenterGStreamer::getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequestClient>)
-{
- notImplemented();
- return false;
-}
+ Vector<CaptureDevice> getMediaStreamDevices() final;
+
+ void mediaSourcesAvailable(GList* sources);
+
+private:
+ PassRefPtr<RealtimeMediaSource> firstSource(RealtimeMediaSource::Type);
+ RealtimeMediaSourceOwrMap m_sourceMap;
+ ValidConstraintsHandler m_validConstraintsHandler;
+ InvalidConstraintsHandler m_invalidConstraintsHandler;
+ NewMediaStreamHandler m_completionHandler;
+};
} // namespace WebCore
-#endif // ENABLE(MEDIA_STREAM)
+#endif // ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
+
+#endif // RealtimeMediaSourceCenterOwr_h
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.cpp b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.cpp
new file mode 100644
index 000000000..ee7499d38
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 Igalia S.L
+ *
+ * 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 the copyright holder 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
+ * HOLDER 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) && USE(OPENWEBRTC)
+#include "RealtimeMediaSourceOwr.h"
+
+namespace WebCore {
+
+const RealtimeMediaSourceSettings& RealtimeMediaSourceOwr::settings() const
+{
+ const_cast<RealtimeMediaSourceOwr&>(*this).initializeSettings();
+ return m_currentSettings;
+}
+
+RealtimeMediaSourceSupportedConstraints& RealtimeMediaSourceOwr::supportedConstraints()
+{
+ if (m_supportedConstraints.supportsDeviceId())
+ return m_supportedConstraints;
+
+ m_supportedConstraints.setSupportsDeviceId(true);
+ initializeSupportedConstraints(m_supportedConstraints);
+
+ return m_supportedConstraints;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.h
new file mode 100644
index 000000000..a8f78e222
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceOwr.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 Igalia S.L
+ * Copyright (C) 2015 Metrological
+ *
+ * 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 the copyright holder 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
+ * HOLDER 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 RealtimeMediaSourceOwr_h
+#define RealtimeMediaSourceOwr_h
+
+#if ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
+
+#include "GRefPtrGStreamer.h"
+#include "RealtimeMediaSource.h"
+#include <owr/owr_media_source.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class RealtimeMediaSourceCapabilities;
+
+class RealtimeMediaSourceOwr : public RealtimeMediaSource {
+public:
+RealtimeMediaSourceOwr(OwrMediaSource* mediaSource, const String& id, RealtimeMediaSource::Type type, const String& name)
+ : RealtimeMediaSource(id, type, name)
+ , m_mediaSource(mediaSource)
+ {
+ if (!mediaSource)
+ m_muted = true;
+ }
+
+RealtimeMediaSourceOwr(const String& id, RealtimeMediaSource::Type type, const String& name)
+ : RealtimeMediaSource(id, type, name)
+ , m_mediaSource(nullptr)
+ {
+ }
+
+ virtual ~RealtimeMediaSourceOwr() { }
+
+ void swapOutShallowSource(OwrMediaSource& realSource)
+ {
+ m_mediaSource = &realSource;
+ setMuted(false);
+ }
+
+ RefPtr<RealtimeMediaSourceCapabilities> capabilities() const override { return m_capabilities; }
+ const RealtimeMediaSourceSettings& settings() const override;
+
+ OwrMediaSource* mediaSource() const { return m_mediaSource; }
+
+protected:
+ virtual void initializeSettings() { };
+ virtual void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints&) { };
+ RealtimeMediaSourceSupportedConstraints& supportedConstraints();
+
+ RealtimeMediaSourceSettings m_currentSettings;
+
+private:
+ RealtimeMediaSourceSupportedConstraints m_supportedConstraints;
+ RefPtr<RealtimeMediaSourceCapabilities> m_capabilities;
+ OwrMediaSource* m_mediaSource;
+};
+
+typedef HashMap<String, RefPtr<RealtimeMediaSourceOwr>> RealtimeMediaSourceOwrMap;
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
+
+#endif // RealtimeMediaSourceOwr_h
diff --git a/Source/WebCore/platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h
new file mode 100644
index 000000000..dc66a3e2b
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeVideoSourceOwr.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015,2016 Igalia S.L
+ * Copyright (C) 2015 Metrological
+ *
+ * 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 the copyright holder 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
+ * HOLDER 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.
+ */
+
+#pragma once
+
+#if ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
+
+#include "RealtimeMediaSourceOwr.h"
+
+namespace WebCore {
+
+class RealtimeVideoSourceOwr : public RealtimeMediaSourceOwr {
+public:
+RealtimeVideoSourceOwr(OwrMediaSource* mediaSource, const String& id, RealtimeMediaSource::Type type, const String& name)
+ : RealtimeMediaSourceOwr(mediaSource, id, type, name)
+ {
+ }
+
+RealtimeVideoSourceOwr(const String& id, RealtimeMediaSource::Type type, const String& name)
+ : RealtimeMediaSourceOwr(id, type, name)
+ {
+ }
+
+ virtual ~RealtimeVideoSourceOwr() { }
+
+ bool applySize(const IntSize&) final { return true; }
+
+protected:
+ void initializeSettings() final {
+ if (m_currentSettings.deviceId().isEmpty())
+ m_currentSettings.setSupportedConstraits(supportedConstraints());
+
+ m_currentSettings.setDeviceId(id());
+
+ m_currentSettings.setFrameRate(frameRate());
+ m_currentSettings.setWidth(size().width());
+ m_currentSettings.setHeight(size().height());
+ }
+
+ void initializeSupportedConstraints(RealtimeMediaSourceSupportedConstraints& supportedConstraints) final {
+ supportedConstraints.setSupportsFacingMode(RealtimeMediaSourceSettings::Unknown);
+ supportedConstraints.setSupportsWidth(true);
+ supportedConstraints.setSupportsHeight(true);
+ supportedConstraints.setSupportsAspectRatio(true);
+ supportedConstraints.setSupportsFrameRate(true);
+ }
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)