summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/mediastream/openwebrtc
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/openwebrtc
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/platform/mediastream/openwebrtc')
-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.h77
-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
10 files changed, 1575 insertions, 0 deletions
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/openwebrtc/RealtimeMediaSourceCenterOwr.h b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h
new file mode 100644
index 000000000..6cdd7d5fe
--- /dev/null
+++ b/Source/WebCore/platform/mediastream/openwebrtc/RealtimeMediaSourceCenterOwr.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#ifndef RealtimeMediaSourceCenterOwr_h
+#define RealtimeMediaSourceCenterOwr_h
+
+#if ENABLE(MEDIA_STREAM) && USE(OPENWEBRTC)
+
+#include "RealtimeMediaSourceCenter.h"
+
+#include "RealtimeMediaSourceOwr.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class CaptureDevice;
+class MediaStreamPrivate;
+class RealtimeMediaSource;
+class MediaStreamSourcesQueryClient;
+class TrackSourceInfo;
+
+class RealtimeMediaSourceCenterOwr final : public RealtimeMediaSourceCenter {
+public:
+ RealtimeMediaSourceCenterOwr();
+ ~RealtimeMediaSourceCenterOwr();
+
+ void validateRequestConstraints(ValidConstraintsHandler validHandler, InvalidConstraintsHandler invalidHandler, const MediaConstraints& audioConstraints, const MediaConstraints& videoConstraints) final;
+
+ void createMediaStream(NewMediaStreamHandler, const String& audioDeviceID, const String& videoDeviceID, const MediaConstraints* videoConstraints, const MediaConstraints* audioConstraints) final;
+
+ 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) && 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)