Support connecting a MediaStreamAudioDestinationNode to RTCPeerConnection
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Jul 2018 00:04:30 +0000 (00:04 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Jul 2018 00:04:30 +0000 (00:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187627
<rdar://problem/35334400>

Reviewed by Jer Noble.

Source/WebCore:

When MediaStreamAudioSource is called to read new audio samples,
convert these samples to a WebAudioBufferList and call RealtimeMediaSource::audioSamplesAvailable.
This makes its observers to get the audio data.

Test: webrtc/peer-connection-createMediaStreamDestination.html

* Modules/mediastream/MediaStream.cpp:
(WebCore::MediaStream::create): Minor refactoring.
* Modules/webaudio/MediaStreamAudioDestinationNode.cpp:
(WebCore::createMediaStream):
(WebCore::MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode):
(WebCore::MediaStreamAudioDestinationNode::process):
* Modules/webaudio/MediaStreamAudioDestinationNode.h:
* Modules/webaudio/MediaStreamAudioSource.cpp:
(WebCore::MediaStreamAudioSource::MediaStreamAudioSource):
(WebCore::MediaStreamAudioSource::consumeAudio):
* Modules/webaudio/MediaStreamAudioSource.h:
* Modules/webaudio/MediaStreamAudioSourceCocoa.cpp: Added.
(WebCore::streamDescription):
(WebCore::MediaStreamAudioSource::consumeAudio):
* WebCore.xcodeproj/project.pbxproj:
* platform/audio/AudioDestinationConsumer.h: Removed.
* platform/mediastream/MediaStreamPrivate.cpp:
(WebCore::MediaStreamPrivate::create):
* platform/mediastream/MediaStreamPrivate.h:

LayoutTests:

* webrtc/peer-connection-createMediaStreamDestination-expected.txt: Added.
* webrtc/peer-connection-createMediaStreamDestination.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@233829 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
LayoutTests/ChangeLog
LayoutTests/webrtc/peer-connection-createMediaStreamDestination-expected.txt [new file with mode: 0644]
LayoutTests/webrtc/peer-connection-createMediaStreamDestination.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaStream.cpp
Source/WebCore/Modules/webaudio/MediaStreamAudioDestinationNode.cpp
Source/WebCore/Modules/webaudio/MediaStreamAudioDestinationNode.h
Source/WebCore/Modules/webaudio/MediaStreamAudioSource.cpp
Source/WebCore/Modules/webaudio/MediaStreamAudioSource.h
Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp [new file with mode: 0644]
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/audio/AudioDestinationConsumer.h [deleted file]
Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp
Source/WebCore/platform/mediastream/MediaStreamPrivate.h

index 54d2157..eab3681 100644 (file)
@@ -1,3 +1,14 @@
+2018-07-13  Youenn Fablet  <youenn@apple.com>
+
+        Support connecting a MediaStreamAudioDestinationNode to RTCPeerConnection
+        https://bugs.webkit.org/show_bug.cgi?id=187627
+        <rdar://problem/35334400>
+
+        Reviewed by Jer Noble.
+
+        * webrtc/peer-connection-createMediaStreamDestination-expected.txt: Added.
+        * webrtc/peer-connection-createMediaStreamDestination.html: Added.
+
 2018-07-13  Truitt Savell  <tsavell@apple.com>
 
         [ MacOS WK1 ] Layout Tests in media/media-fragments/ are flaky
diff --git a/LayoutTests/webrtc/peer-connection-createMediaStreamDestination-expected.txt b/LayoutTests/webrtc/peer-connection-createMediaStreamDestination-expected.txt
new file mode 100644 (file)
index 0000000..1144b64
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS Web audio generated content through a peer connection 
+
diff --git a/LayoutTests/webrtc/peer-connection-createMediaStreamDestination.html b/LayoutTests/webrtc/peer-connection-createMediaStreamDestination.html
new file mode 100644 (file)
index 0000000..264bf87
--- /dev/null
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <title>Testing createMediaStreamDestination piped to peer connection</title>
+    <script src="../resources/testharness.js"></script>
+    <script src="../resources/testharnessreport.js"></script>
+    <script src ="routines.js"></script>
+    <script>
+    const noiseContext = new webkitAudioContext();
+    const oscillator = noiseContext.createOscillator();
+    const audioStreamDestination = noiseContext.createMediaStreamDestination();
+    const audioStream = audioStreamDestination.stream;
+    oscillator.connect(audioStreamDestination);
+    oscillator.start();
+    const audioTrack = audioStream.getAudioTracks()[0];
+
+    var context = new webkitAudioContext();
+    var remoteStream;
+
+    async function checkForHumBipBop(stream, previousResults, counter)
+    {
+        if (!previousResults)
+            previousResults = { heardHum : false, heardBip : false, heardBop : false };
+        if (!counter)
+            counter = 1;
+        if (++counter > 20)
+            return Promise.resolve(false);
+
+        results = await analyseAudio(stream, 500, context);
+        previousResults.heardHum |= results.heardHum;
+        previousResults.heardBip |= results.heardBip;
+        previousResults.heardBop |= results.heardBop;
+        if (previousResults.heardHum || previousResults.heardBip || previousResults.heardBop)
+            return Promise.resolve(true);
+
+        return await checkForHumBipBop(stream, previousResults, counter);
+    }
+
+    promise_test(async (test) => {
+        const stream = await new Promise((resolve, reject) => {
+            createConnections((firstConnection) => {
+                firstConnection.addTrack(audioTrack, audioStream);
+            }, (secondConnection) => {
+                secondConnection.ontrack = (event) => { resolve(event.streams[0]); };
+            });
+            setTimeout(() => reject("Test timed out"), 5000);
+        });
+        const results = await checkForHumBipBop(stream);
+        await  context.close();
+        await  noiseContext.close();
+        assert_true(results, "heard hum bip bop");
+    }, "Web audio generated content through a peer connection");
+    </script>
+</head>
+<body>
+</body>
+</html>
index 71ea0b9..8991d4e 100644 (file)
@@ -1,3 +1,37 @@
+2018-07-13  Youenn Fablet  <youenn@apple.com>
+
+        Support connecting a MediaStreamAudioDestinationNode to RTCPeerConnection
+        https://bugs.webkit.org/show_bug.cgi?id=187627
+        <rdar://problem/35334400>
+
+        Reviewed by Jer Noble.
+
+        When MediaStreamAudioSource is called to read new audio samples,
+        convert these samples to a WebAudioBufferList and call RealtimeMediaSource::audioSamplesAvailable.
+        This makes its observers to get the audio data.
+
+        Test: webrtc/peer-connection-createMediaStreamDestination.html
+
+        * Modules/mediastream/MediaStream.cpp:
+        (WebCore::MediaStream::create): Minor refactoring.
+        * Modules/webaudio/MediaStreamAudioDestinationNode.cpp:
+        (WebCore::createMediaStream):
+        (WebCore::MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode):
+        (WebCore::MediaStreamAudioDestinationNode::process):
+        * Modules/webaudio/MediaStreamAudioDestinationNode.h:
+        * Modules/webaudio/MediaStreamAudioSource.cpp:
+        (WebCore::MediaStreamAudioSource::MediaStreamAudioSource):
+        (WebCore::MediaStreamAudioSource::consumeAudio):
+        * Modules/webaudio/MediaStreamAudioSource.h:
+        * Modules/webaudio/MediaStreamAudioSourceCocoa.cpp: Added.
+        (WebCore::streamDescription):
+        (WebCore::MediaStreamAudioSource::consumeAudio):
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/audio/AudioDestinationConsumer.h: Removed.
+        * platform/mediastream/MediaStreamPrivate.cpp:
+        (WebCore::MediaStreamPrivate::create):
+        * platform/mediastream/MediaStreamPrivate.h:
+
 2018-07-13  Christopher Reid  <chris.reid@sony.com>
 
         [WinCairo] Enable WebGL when Accelerated Compositing is disabled
index c284a41..90d6c56 100644 (file)
@@ -47,7 +47,7 @@ namespace WebCore {
 
 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context)
 {
-    return MediaStream::create(context, MediaStreamPrivate::create(Vector<RefPtr<MediaStreamTrackPrivate>>()));
+    return MediaStream::create(context, MediaStreamPrivate::create({ }));
 }
 
 Ref<MediaStream> MediaStream::create(ScriptExecutionContext& context, MediaStream& stream)
index 1b9072a..8fc41fd 100644 (file)
@@ -42,25 +42,13 @@ Ref<MediaStreamAudioDestinationNode> MediaStreamAudioDestinationNode::create(Aud
 
 MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext& context, size_t numberOfChannels)
     : AudioBasicInspectorNode(context, context.sampleRate(), numberOfChannels)
-    , m_mixBus(AudioBus::create(numberOfChannels, ProcessingSizeInFrames))
+    , m_source(MediaStreamAudioSource::create(context.sampleRate()))
+    , m_stream(MediaStream::create(*context.scriptExecutionContext(), MediaStreamPrivate::create(m_source.copyRef())))
 {
     setNodeType(NodeTypeMediaStreamAudioDestination);
-
-    m_source = MediaStreamAudioSource::create();
-    Vector<Ref<RealtimeMediaSource>> audioSources;
-    audioSources.append(*m_source);
-    m_stream = MediaStream::create(*context.scriptExecutionContext(), MediaStreamPrivate::create(audioSources, { }));
-
-    m_source->setAudioFormat(numberOfChannels, context.sampleRate());
-
     initialize();
 }
 
-RealtimeMediaSource* MediaStreamAudioDestinationNode::mediaStreamSource()
-{
-    return m_source.get();
-}
-
 MediaStreamAudioDestinationNode::~MediaStreamAudioDestinationNode()
 {
     uninitialize();
@@ -68,8 +56,7 @@ MediaStreamAudioDestinationNode::~MediaStreamAudioDestinationNode()
 
 void MediaStreamAudioDestinationNode::process(size_t numberOfFrames)
 {
-    m_mixBus->copyFrom(*input(0)->bus());
-    m_source->consumeAudio(m_mixBus.get(), numberOfFrames);
+    m_source->consumeAudio(*input(0)->bus(), numberOfFrames);
 }
 
 void MediaStreamAudioDestinationNode::reset()
index 8e8f404..b192f26 100644 (file)
@@ -41,26 +41,23 @@ public:
 
     virtual ~MediaStreamAudioDestinationNode();
 
-    MediaStream* stream() { return m_stream.get(); }
+    MediaStream& stream() { return m_stream.get(); }
 
     // AudioNode.
-    void process(size_t framesToProcess) override;
-    void reset() override;
+    void process(size_t framesToProcess) final;
+    void reset() final;
     
-    RealtimeMediaSource* mediaStreamSource();
-
 private:
     MediaStreamAudioDestinationNode(AudioContext&, size_t numberOfChannels);
 
-    double tailTime() const override { return 0; }
-    double latencyTime() const override { return 0; }
+    double tailTime() const final { return 0; }
+    double latencyTime() const final { return 0; }
 
     // As an audio source, we will never propagate silence.
-    bool propagatesSilence() const override { return false; }
+    bool propagatesSilence() const final { return false; }
 
-    RefPtr<MediaStream> m_stream;
-    RefPtr<MediaStreamAudioSource> m_source;
-    RefPtr<AudioBus> m_mixBus;
+    Ref<MediaStreamAudioSource> m_source;
+    Ref<MediaStream> m_stream;
 };
 
 } // namespace WebCore
index 3563fa3..d797b67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #if ENABLE(MEDIA_STREAM)
 
-#include "AudioSourceProvider.h"
 #include "NotImplemented.h"
 #include <wtf/UUID.h>
 
 namespace WebCore {
 
-Ref<MediaStreamAudioSource> MediaStreamAudioSource::create()
-{
-    return adoptRef(*new MediaStreamAudioSource());
-}
-
-MediaStreamAudioSource::MediaStreamAudioSource()
+MediaStreamAudioSource::MediaStreamAudioSource(float sampleRate)
     : RealtimeMediaSource(makeString("WebAudio-"_s, createCanonicalUUIDString()), RealtimeMediaSource::Type::Audio, "MediaStreamAudioDestinationNode")
 {
+    m_currentSettings.setSampleRate(sampleRate);
 }
 
 const RealtimeMediaSourceCapabilities& MediaStreamAudioSource::capabilities() const
@@ -60,36 +55,11 @@ const RealtimeMediaSourceSettings& MediaStreamAudioSource::settings() const
     return m_currentSettings;
 }
 
-void MediaStreamAudioSource::addAudioConsumer(AudioDestinationConsumer* consumer)
-{
-    LockHolder locker(m_audioConsumersLock);
-    m_audioConsumers.append(consumer);
-}
-
-bool MediaStreamAudioSource::removeAudioConsumer(AudioDestinationConsumer* consumer)
-{
-    LockHolder locker(m_audioConsumersLock);
-    size_t pos = m_audioConsumers.find(consumer);
-    if (pos != notFound) {
-        m_audioConsumers.remove(pos);
-        return true;
-    }
-    return false;
-}
-
-void MediaStreamAudioSource::setAudioFormat(size_t numberOfChannels, float sampleRate)
-{
-    LockHolder locker(m_audioConsumersLock);
-    for (auto& consumer : m_audioConsumers)
-        consumer->setFormat(numberOfChannels, sampleRate);
-}
-
-void MediaStreamAudioSource::consumeAudio(AudioBus* bus, size_t numberOfFrames)
+#if !PLATFORM(COCOA)
+void MediaStreamAudioSource::consumeAudio(AudioBus&, size_t)
 {
-    LockHolder locker(m_audioConsumersLock);
-    for (auto& consumer : m_audioConsumers)
-        consumer->consumeAudio(bus, numberOfFrames);
 }
+#endif
 
 } // namespace WebCore
 
index 18b96e6..4b90c8a 100644 (file)
@@ -27,7 +27,6 @@
 
 #if ENABLE(MEDIA_STREAM)
 
-#include "AudioDestinationConsumer.h"
 #include "RealtimeMediaSource.h"
 #include <wtf/Lock.h>
 #include <wtf/Vector.h>
@@ -40,7 +39,7 @@ class RealtimeMediaSourceCapabilities;
 
 class MediaStreamAudioSource final : public RealtimeMediaSource {
 public:
-    static Ref<MediaStreamAudioSource> create();
+    static Ref<MediaStreamAudioSource> create(float sampleRate) { return adoptRef(*new MediaStreamAudioSource { sampleRate }); }
 
     ~MediaStreamAudioSource() = default;
 
@@ -50,22 +49,16 @@ public:
     const String& deviceId() const { return m_deviceId; }
     void setDeviceId(const String& deviceId) { m_deviceId = deviceId; }
 
-    void setAudioFormat(size_t numberOfChannels, float sampleRate);
-    void consumeAudio(AudioBus*, size_t numberOfFrames);
-
-    void addAudioConsumer(AudioDestinationConsumer*);
-    bool removeAudioConsumer(AudioDestinationConsumer*);
-    const Vector<RefPtr<AudioDestinationConsumer>>& audioConsumers() const { return m_audioConsumers; }
+    void consumeAudio(AudioBus&, size_t numberOfFrames);
 
 private:
-    MediaStreamAudioSource();
+    explicit MediaStreamAudioSource(float sampleRate);
 
-    bool isCaptureSource() const final { return true; }
+    bool isCaptureSource() const final { return false; }
 
     String m_deviceId;
-    Lock m_audioConsumersLock;
-    Vector<RefPtr<AudioDestinationConsumer>> m_audioConsumers;
     RealtimeMediaSourceSettings m_currentSettings;
+    size_t m_numberOfFrames { 0 };
 };
 
 } // namespace WebCore
diff --git a/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp b/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceCocoa.cpp
new file mode 100644 (file)
index 0000000..7b19afb
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MediaStreamAudioSource.h"
+
+#if ENABLE(MEDIA_STREAM)
+
+#include "AudioBus.h"
+#include "CAAudioStreamDescription.h"
+#include "Logging.h"
+#include "WebAudioBufferList.h"
+#include <CoreAudio/CoreAudioTypes.h>
+#include <pal/avfoundation/MediaTimeAVFoundation.h>
+#include <pal/cf/CoreMediaSoftLink.h>
+#include "CoreVideoSoftLink.h"
+
+using namespace PAL;
+
+namespace WebCore {
+
+static inline AudioStreamBasicDescription streamDescription(size_t sampleRate, size_t channelCount)
+{
+    bool isFloat = true;
+    bool isBigEndian = false;
+    bool isNonInterleaved = true;
+    static const size_t sampleSize = 8 * sizeof(float);
+
+    AudioStreamBasicDescription streamFormat;
+    FillOutASBDForLPCM(streamFormat, sampleRate, channelCount, sampleSize, sampleSize, isFloat, isBigEndian, isNonInterleaved);
+    return streamFormat;
+}
+
+static inline void copyChannelData(AudioChannel& channel, AudioBuffer& buffer, size_t numberOfFrames, bool isMuted)
+{
+    buffer.mDataByteSize = numberOfFrames * sizeof(float);
+    buffer.mNumberChannels = 1;
+    if (isMuted) {
+        memset(buffer.mData, 0, buffer.mDataByteSize);
+        return;
+    }
+    memcpy(buffer.mData, channel.data(), buffer.mDataByteSize);
+}
+
+void MediaStreamAudioSource::consumeAudio(AudioBus& bus, size_t numberOfFrames)
+{
+    if (bus.numberOfChannels() != 1 && bus.numberOfChannels() != 2) {
+        RELEASE_LOG_ERROR(Media, "MediaStreamAudioSource::consumeAudio(%p) trying to consume bus with %u channels", this, bus.numberOfChannels());
+        return;
+    }
+
+    CMTime startTime = CMTimeMake(m_numberOfFrames, m_currentSettings.sampleRate());
+    auto mediaTime = PAL::toMediaTime(startTime);
+    m_numberOfFrames += numberOfFrames;
+
+    AudioStreamBasicDescription newDescription = streamDescription(m_currentSettings.sampleRate(), bus.numberOfChannels());
+
+    // FIXME: We should do the memory allocation once in MediaStreamAudioSource and resize it according numberOfFrames.
+    WebAudioBufferList audioBufferList { CAAudioStreamDescription(newDescription), WTF::safeCast<uint32_t>(numberOfFrames) };
+
+    for (size_t cptr = 0; cptr < bus.numberOfChannels(); ++cptr)
+        copyChannelData(*bus.channel(cptr), *audioBufferList.buffer(cptr), numberOfFrames, muted());
+
+    audioSamplesAvailable(mediaTime, audioBufferList, CAAudioStreamDescription(newDescription), numberOfFrames);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(MEDIA_STREAM)
index d90ea76..dd93e87 100644 (file)
@@ -93,7 +93,6 @@
                070E09191875EEFC003A1D3C /* PlatformMediaSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 070E09181875ED93003A1D3C /* PlatformMediaSession.h */; settings = {ATTRIBUTES = (Private, ); }; };
                070E81D11BF27656001FDA48 /* VideoTrackPrivateMediaStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 070E81D01BF27656001FDA48 /* VideoTrackPrivateMediaStream.h */; };
                070F549817F12F6B00169E04 /* MediaStreamConstraintsValidationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 070F549717F12F6B00169E04 /* MediaStreamConstraintsValidationClient.h */; };
-               070F549E17F2402700169E04 /* AudioDestinationConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 070F549D17F2402700169E04 /* AudioDestinationConsumer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0719427F1D088F21002AA51D /* AVFoundationMIMETypeCache.mm in Sources */ = {isa = PBXBuildFile; fileRef = 07C8AD111D073D630087C5CE /* AVFoundationMIMETypeCache.mm */; };
                071A9EC2168FBC43002629F9 /* TextTrackCueGeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 071A9EC0168FB56C002629F9 /* TextTrackCueGeneric.cpp */; };
                071A9EC3168FBC55002629F9 /* TextTrackCueGeneric.h in Headers */ = {isa = PBXBuildFile; fileRef = 071A9EC1168FB56C002629F9 /* TextTrackCueGeneric.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4129C9AB1F59C573009D7403 /* ReadableStreamSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 418C395B1C8F0A610051C8A3 /* ReadableStreamSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4129C9AF1F59CF5B009D7403 /* ReadableStreamSink.h in Headers */ = {isa = PBXBuildFile; fileRef = 4129C9801F5861C7009D7403 /* ReadableStreamSink.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4129DF861BB5B80C00322A16 /* JSReadableStreamPrivateConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 4129DF841BB5B7F700322A16 /* JSReadableStreamPrivateConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               4133CB8B20F80E9900E89B11 /* MediaStreamAudioSourceCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4133CB8920F80E8600E89B11 /* MediaStreamAudioSourceCocoa.cpp */; };
                41380C271F3436AC00155FDA /* DOMCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 41380C251F34369A00155FDA /* DOMCache.h */; };
                41380C291F3436AC00155FDA /* DOMCacheStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 41380C221F34369000155FDA /* DOMCacheStorage.h */; };
                4138D3351244054800323D33 /* EventContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4138D3331244054800323D33 /* EventContext.h */; };
                070E091A1875EF71003A1D3C /* PlatformMediaSession.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformMediaSession.cpp; sourceTree = "<group>"; };
                070E81D01BF27656001FDA48 /* VideoTrackPrivateMediaStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoTrackPrivateMediaStream.h; sourceTree = "<group>"; };
                070F549717F12F6B00169E04 /* MediaStreamConstraintsValidationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamConstraintsValidationClient.h; sourceTree = "<group>"; };
-               070F549D17F2402700169E04 /* AudioDestinationConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioDestinationConsumer.h; sourceTree = "<group>"; };
                0711588F17DF633700EDFE2B /* MediaStreamPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamPrivate.cpp; sourceTree = "<group>"; };
                071A9EC0168FB56C002629F9 /* TextTrackCueGeneric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextTrackCueGeneric.cpp; sourceTree = "<group>"; };
                071A9EC1168FB56C002629F9 /* TextTrackCueGeneric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextTrackCueGeneric.h; sourceTree = "<group>"; };
                4131F3B11F9552810059995A /* JSFetchEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFetchEventCustom.cpp; sourceTree = "<group>"; };
                4131F3B41F955BC30059995A /* ExtendableEventInit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtendableEventInit.h; sourceTree = "<group>"; };
                4131F3B51F955BC50059995A /* ExtendableEventInit.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ExtendableEventInit.idl; sourceTree = "<group>"; };
+               4133CB8920F80E8600E89B11 /* MediaStreamAudioSourceCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamAudioSourceCocoa.cpp; sourceTree = "<group>"; };
                41380C201F34368A00155FDA /* DOMCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DOMCache.cpp; path = Modules/cache/DOMCache.cpp; sourceTree = SOURCE_ROOT; };
                41380C211F34368D00155FDA /* DOMCacheStorage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DOMCacheStorage.cpp; path = Modules/cache/DOMCacheStorage.cpp; sourceTree = SOURCE_ROOT; };
                41380C221F34369000155FDA /* DOMCacheStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DOMCacheStorage.h; path = Modules/cache/DOMCacheStorage.h; sourceTree = SOURCE_ROOT; };
                                078E094A17D1709600420AA1 /* MediaStreamAudioDestinationNode.idl */,
                                0783228218013ED700999E0C /* MediaStreamAudioSource.cpp */,
                                0783228318013ED800999E0C /* MediaStreamAudioSource.h */,
+                               4133CB8920F80E8600E89B11 /* MediaStreamAudioSourceCocoa.cpp */,
                                FD671A74159BB07000197559 /* MediaStreamAudioSourceNode.cpp */,
                                FD671A75159BB07000197559 /* MediaStreamAudioSourceNode.h */,
                                FD671A76159BB07000197559 /* MediaStreamAudioSourceNode.idl */,
                                FD31604712B026F700C1A359 /* AudioChannel.cpp */,
                                FD31604812B026F700C1A359 /* AudioChannel.h */,
                                FD31604912B026F700C1A359 /* AudioDestination.h */,
-                               070F549D17F2402700169E04 /* AudioDestinationConsumer.h */,
                                FD31604A12B026F700C1A359 /* AudioDSPKernel.h */,
                                FD31604B12B026F700C1A359 /* AudioDSPKernelProcessor.cpp */,
                                FD31604C12B026F700C1A359 /* AudioDSPKernelProcessor.h */,
                                FD31607E12B026F700C1A359 /* AudioChannel.h in Headers */,
                                FD31600512B0267600C1A359 /* AudioContext.h in Headers */,
                                FD31607F12B026F700C1A359 /* AudioDestination.h in Headers */,
-                               070F549E17F2402700169E04 /* AudioDestinationConsumer.h in Headers */,
                                FD3160BD12B0272A00C1A359 /* AudioDestinationMac.h in Headers */,
                                FD31600812B0267600C1A359 /* AudioDestinationNode.h in Headers */,
                                FD31608012B026F700C1A359 /* AudioDSPKernel.h in Headers */,
                                C90F65551B2253B1002163A1 /* MediaSessionManager.cpp in Sources */,
                                07638A9A1884487200E15A1B /* MediaSessionManagerIOS.mm in Sources */,
                                CDC8B5A6180474F70016E685 /* MediaSourcePrivateAVFObjC.mm in Sources */,
+                               4133CB8B20F80E9900E89B11 /* MediaStreamAudioSourceCocoa.cpp in Sources */,
                                CDF2B0101820540600F2B424 /* MockBox.cpp in Sources */,
                                51058ADF1D67C229009A538C /* MockGamepad.cpp in Sources */,
                                51058AE11D67C229009A538C /* MockGamepadProvider.cpp in Sources */,
diff --git a/Source/WebCore/platform/audio/AudioDestinationConsumer.h b/Source/WebCore/platform/audio/AudioDestinationConsumer.h
deleted file mode 100644 (file)
index f7c3387..0000000
+++ /dev/null
@@ -1,50 +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 AudioDestinationConsumer_h
-#define AudioDestinationConsumer_h
-
-#include <wtf/RefCounted.h>
-
-namespace WebCore {
-
-class AudioBus;
-
-class AudioDestinationConsumer : public RefCounted<AudioDestinationConsumer> {
-public:
-    virtual ~AudioDestinationConsumer() = default;
-
-    virtual void setFormat(size_t numberOfChannels, float sampleRate) = 0;
-    virtual void consumeAudio(AudioBus*, size_t numberOfFrames) = 0;
-};
-
-} // WebCore
-
-#endif // AudioDestinationConsumer_h
index fcb423f..965229e 100644 (file)
 
 namespace WebCore {
 
+Ref<MediaStreamPrivate> MediaStreamPrivate::create(Ref<RealtimeMediaSource>&& source)
+{
+    return MediaStreamPrivate::create(MediaStreamTrackPrivateVector::from(MediaStreamTrackPrivate::create(WTFMove(source))));
+}
+
 Ref<MediaStreamPrivate> MediaStreamPrivate::create(const Vector<Ref<RealtimeMediaSource>>& audioSources, const Vector<Ref<RealtimeMediaSource>>& videoSources)
 {
     MediaStreamTrackPrivateVector tracks;
index b6b640b..dc65ad8 100644 (file)
@@ -65,6 +65,7 @@ public:
         virtual void didRemoveTrack(MediaStreamTrackPrivate&) { }
     };
 
+    static Ref<MediaStreamPrivate> create(Ref<RealtimeMediaSource>&&);
     static Ref<MediaStreamPrivate> create(const Vector<Ref<RealtimeMediaSource>>& audioSources, const Vector<Ref<RealtimeMediaSource>>& videoSources);
     static Ref<MediaStreamPrivate> create(const MediaStreamTrackPrivateVector& tracks, String&& id = createCanonicalUUIDString()) { return adoptRef(*new MediaStreamPrivate(tracks, WTFMove(id))); }