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;