Title: [271575] trunk
Revision
271575
Author
[email protected]
Date
2021-01-18 00:40:55 -0800 (Mon, 18 Jan 2021)

Log Message

WebRTC live Opus audio stream stutters
https://bugs.webkit.org/show_bug.cgi?id=220599
<rdar://problem/73190139>

Reviewed by Darin Adler.

Source/WebCore:

Before the patch, the MediaStreamTrack was owning its audio source provider.
Two MediaStreamAudioSourceNode reading the same track would read on the same provider buffer.
Instead, create a provider for each node.

Covered by updated test.

* Modules/mediastream/MediaStreamTrack.cpp:
(WebCore::MediaStreamTrack::createAudioSourceProvider):
* Modules/mediastream/MediaStreamTrack.h:
* Modules/webaudio/MediaStreamAudioSourceNode.cpp:
(WebCore::MediaStreamAudioSourceNode::create):
(WebCore::MediaStreamAudioSourceNode::MediaStreamAudioSourceNode):
(WebCore::MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode):
(WebCore::MediaStreamAudioSourceNode::provideInput):
* Modules/webaudio/MediaStreamAudioSourceNode.h:
* platform/mediastream/MediaStreamTrackPrivate.cpp:
(WebCore::MediaStreamTrackPrivate::createAudioSourceProvider):
* platform/mediastream/MediaStreamTrackPrivate.h:

LayoutTests:

Add media stream source nodes to ensure that concurrent reading is not an issue anymore.

* fast/mediastream/mock-media-source-webaudio.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (271574 => 271575)


--- trunk/LayoutTests/ChangeLog	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/LayoutTests/ChangeLog	2021-01-18 08:40:55 UTC (rev 271575)
@@ -1,3 +1,15 @@
+2021-01-18  Youenn Fablet  <[email protected]>
+
+        WebRTC live Opus audio stream stutters
+        https://bugs.webkit.org/show_bug.cgi?id=220599
+        <rdar://problem/73190139>
+
+        Reviewed by Darin Adler.
+
+        Add media stream source nodes to ensure that concurrent reading is not an issue anymore.
+
+        * fast/mediastream/mock-media-source-webaudio.html:
+
 2021-01-15  Rob Buis  <[email protected]>
 
         https://bugs.webkit.org/show_bug.cgi?id=220224

Modified: trunk/LayoutTests/fast/mediastream/mock-media-source-webaudio.html (271574 => 271575)


--- trunk/LayoutTests/fast/mediastream/mock-media-source-webaudio.html	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/LayoutTests/fast/mediastream/mock-media-source-webaudio.html	2021-01-18 08:40:55 UTC (rev 271575)
@@ -32,6 +32,11 @@
             analyser.connect(gain);
             gain.connect(context.destination);
 
+            const secondSource = context.createMediaStreamSource(stream);
+            const sourceGain = new GainNode(context, { gain : 0 });
+            secondSource.connect(gain);
+            sourceGain.connect(context.destination);
+
             function analyse() {
                 var freqDomain = new Uint8Array(analyser.frequencyBinCount);
                 analyser.getByteFrequencyData(freqDomain);

Modified: trunk/Source/WebCore/ChangeLog (271574 => 271575)


--- trunk/Source/WebCore/ChangeLog	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/Source/WebCore/ChangeLog	2021-01-18 08:40:55 UTC (rev 271575)
@@ -1,3 +1,30 @@
+2021-01-18  Youenn Fablet  <[email protected]>
+
+        WebRTC live Opus audio stream stutters
+        https://bugs.webkit.org/show_bug.cgi?id=220599
+        <rdar://problem/73190139>
+
+        Reviewed by Darin Adler.
+
+        Before the patch, the MediaStreamTrack was owning its audio source provider.
+        Two MediaStreamAudioSourceNode reading the same track would read on the same provider buffer.
+        Instead, create a provider for each node.
+
+        Covered by updated test.
+
+        * Modules/mediastream/MediaStreamTrack.cpp:
+        (WebCore::MediaStreamTrack::createAudioSourceProvider):
+        * Modules/mediastream/MediaStreamTrack.h:
+        * Modules/webaudio/MediaStreamAudioSourceNode.cpp:
+        (WebCore::MediaStreamAudioSourceNode::create):
+        (WebCore::MediaStreamAudioSourceNode::MediaStreamAudioSourceNode):
+        (WebCore::MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode):
+        (WebCore::MediaStreamAudioSourceNode::provideInput):
+        * Modules/webaudio/MediaStreamAudioSourceNode.h:
+        * platform/mediastream/MediaStreamTrackPrivate.cpp:
+        (WebCore::MediaStreamTrackPrivate::createAudioSourceProvider):
+        * platform/mediastream/MediaStreamTrackPrivate.h:
+
 2021-01-17  Kimmo Kinnunen  <[email protected]>
 
         GraphicsContextGLOpenGL::reshapeFBOs() ANGLE variant calls into makeContextCurrent()

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp (271574 => 271575)


--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp	2021-01-18 08:40:55 UTC (rev 271575)
@@ -50,6 +50,7 @@
 #include "RuntimeEnabledFeatures.h"
 #include "ScriptExecutionContext.h"
 #include "Settings.h"
+#include "WebAudioSourceProvider.h"
 #include <wtf/CompletionHandler.h>
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/NeverDestroyed.h>
@@ -622,9 +623,9 @@
     return !m_ended;
 }
 
-AudioSourceProvider* MediaStreamTrack::audioSourceProvider()
+RefPtr<WebAudioSourceProvider> MediaStreamTrack::createAudioSourceProvider()
 {
-    return m_private->audioSourceProvider();
+    return m_private->createAudioSourceProvider();
 }
 
 Document* MediaStreamTrack::document() const

Modified: trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h (271574 => 271575)


--- trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/Source/WebCore/Modules/mediastream/MediaStreamTrack.h	2021-01-18 08:40:55 UTC (rev 271575)
@@ -139,7 +139,7 @@
     RealtimeMediaSource& source() const { return m_private->source(); }
     MediaStreamTrackPrivate& privateTrack() { return m_private.get(); }
 
-    AudioSourceProvider* audioSourceProvider();
+    RefPtr<WebAudioSourceProvider> createAudioSourceProvider();
 
     MediaProducer::MediaStateFlags mediaState() const;
 

Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp (271574 => 271575)


--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.cpp	2021-01-18 08:40:55 UTC (rev 271575)
@@ -34,6 +34,7 @@
 #include "AudioUtilities.h"
 #include "Logging.h"
 #include "MediaStreamAudioSourceOptions.h"
+#include "WebAudioSourceProvider.h"
 #include <wtf/IsoMallocInlines.h>
 #include <wtf/Locker.h>
 
@@ -49,17 +50,16 @@
     if (audioTracks.isEmpty())
         return Exception { InvalidStateError, "Media stream has no audio tracks"_s };
 
-    MediaStreamTrack* providerTrack = nullptr;
+    RefPtr<WebAudioSourceProvider> provider;
     for (auto& track : audioTracks) {
-        if (track->audioSourceProvider()) {
-            providerTrack = track.get();
+        provider = track->createAudioSourceProvider();
+        if (provider)
             break;
-        }
     }
-    if (!providerTrack)
+    if (!provider)
         return Exception { InvalidStateError, "Could not find an audio track with an audio source provider"_s };
 
-    auto node = adoptRef(*new MediaStreamAudioSourceNode(context, *options.mediaStream, *providerTrack));
+    auto node = adoptRef(*new MediaStreamAudioSourceNode(context, *options.mediaStream, provider.releaseNonNull()));
     node->setFormat(2, context.sampleRate());
 
     // Context keeps reference until node is disconnected.
@@ -68,15 +68,12 @@
     return node;
 }
 
-MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(BaseAudioContext& context, MediaStream& mediaStream, MediaStreamTrack& audioTrack)
+MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(BaseAudioContext& context, MediaStream& mediaStream, Ref<WebAudioSourceProvider>&& provider)
     : AudioNode(context, NodeTypeMediaStreamAudioSource)
     , m_mediaStream(mediaStream)
-    , m_audioTrack(audioTrack)
+    , m_provider(provider)
 {
-    AudioSourceProvider* audioSourceProvider = m_audioTrack->audioSourceProvider();
-    ASSERT(audioSourceProvider);
-
-    audioSourceProvider->setClient(this);
+    m_provider->setClient(this);
     
     // Default to stereo. This could change depending on the format of the MediaStream's audio track.
     addOutput(2);
@@ -86,9 +83,7 @@
 
 MediaStreamAudioSourceNode::~MediaStreamAudioSourceNode()
 {
-    AudioSourceProvider* audioSourceProvider = m_audioTrack->audioSourceProvider();
-    ASSERT(audioSourceProvider);
-    audioSourceProvider->setClient(nullptr);
+    m_provider->setClient(nullptr);
     uninitialize();
 }
 
@@ -132,10 +127,7 @@
 
 void MediaStreamAudioSourceNode::provideInput(AudioBus* bus, size_t framesToProcess)
 {
-    if (auto* provider = m_audioTrack->audioSourceProvider())
-        provider->provideInput(bus, framesToProcess);
-    else
-        bus->zero();
+    m_provider->provideInput(bus, framesToProcess);
 }
 
 void MediaStreamAudioSourceNode::process(size_t numberOfFrames)

Modified: trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h (271574 => 271575)


--- trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/Source/WebCore/Modules/webaudio/MediaStreamAudioSourceNode.h	2021-01-18 08:40:55 UTC (rev 271575)
@@ -37,6 +37,7 @@
 class AudioContext;
 struct MediaStreamAudioSourceOptions;
 class MultiChannelResampler;
+class WebAudioSourceProvider;
 
 class MediaStreamAudioSourceNode final : public AudioNode, public AudioSourceProviderClient {
     WTF_MAKE_ISO_ALLOCATED(MediaStreamAudioSourceNode);
@@ -43,19 +44,18 @@
 public:
     static ExceptionOr<Ref<MediaStreamAudioSourceNode>> create(BaseAudioContext&, MediaStreamAudioSourceOptions&&);
 
-    virtual ~MediaStreamAudioSourceNode();
+    ~MediaStreamAudioSourceNode();
 
     MediaStream* mediaStream() { return &m_mediaStream.get(); }
 
+private:
+    MediaStreamAudioSourceNode(BaseAudioContext&, MediaStream&, Ref<WebAudioSourceProvider>&&);
+
     // AudioNode
-    void process(size_t framesToProcess) override;
-
+    void process(size_t framesToProcess) final;
     // AudioSourceProviderClient
-    void setFormat(size_t numberOfChannels, float sampleRate) override;
+    void setFormat(size_t numberOfChannels, float sampleRate) final;
 
-private:
-    MediaStreamAudioSourceNode(BaseAudioContext&, MediaStream&, MediaStreamTrack&);
-
     void provideInput(AudioBus*, size_t framesToProcess);
 
     double tailTime() const override { return 0; }
@@ -66,7 +66,7 @@
     bool propagatesSilence() const override { return false; }
 
     Ref<MediaStream> m_mediaStream;
-    Ref<MediaStreamTrack> m_audioTrack;
+    Ref<WebAudioSourceProvider> m_provider;
     std::unique_ptr<MultiChannelResampler> m_multiChannelResampler;
 
     Lock m_processLock;

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp (271574 => 271575)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp	2021-01-18 08:40:55 UTC (rev 271575)
@@ -184,16 +184,15 @@
     m_source->applyConstraints(constraints, WTFMove(completionHandler));
 }
 
-AudioSourceProvider* MediaStreamTrackPrivate::audioSourceProvider()
+RefPtr<WebAudioSourceProvider> MediaStreamTrackPrivate::createAudioSourceProvider()
 {
 #if PLATFORM(COCOA)
-    if (!m_audioSourceProvider)
-        m_audioSourceProvider = MediaStreamTrackAudioSourceProviderCocoa::create(*this);
+    return MediaStreamTrackAudioSourceProviderCocoa::create(*this);
 #elif USE(LIBWEBRTC) && USE(GSTREAMER)
-    if (!m_audioSourceProvider)
-        m_audioSourceProvider = AudioSourceProviderGStreamer::create(*this);
+    return AudioSourceProviderGStreamer::create(*this);
+#else
+    return nullptr;
 #endif
-    return m_audioSourceProvider.get();
 }
 
 void MediaStreamTrackPrivate::sourceStarted()

Modified: trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h (271574 => 271575)


--- trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h	2021-01-18 08:40:04 UTC (rev 271574)
+++ trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h	2021-01-18 08:40:55 UTC (rev 271575)
@@ -36,7 +36,6 @@
 
 namespace WebCore {
 
-class AudioSourceProvider;
 class GraphicsContext;
 class MediaSample;
 class RealtimeMediaSourceCapabilities;
@@ -109,7 +108,7 @@
 
     void applyConstraints(const MediaConstraints&, RealtimeMediaSource::ApplyConstraintsHandler&&);
 
-    AudioSourceProvider* audioSourceProvider();
+    RefPtr<WebAudioSourceProvider> createAudioSourceProvider();
 
     void paintCurrentFrameInContext(GraphicsContext&, const FloatRect&);
 
@@ -153,7 +152,6 @@
     bool m_isEnded { false };
     bool m_hasStartedProducingData { false };
     HintValue m_contentHint { HintValue::Empty };
-    RefPtr<WebAudioSourceProvider> m_audioSourceProvider;
     Ref<const Logger> m_logger;
 #if !RELEASE_LOG_DISABLED
     const void* m_logIdentifier;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to