Skip to content

Commit 0b254ee

Browse files
asurdej-comcasteocanha
authored andcommitted
[MSE SourceBuffer] Disable audio flush on samples replacement for Spotify (#1244)
With edit lists enabled recently, Spotify started to append the same segment multiple times that to samples replacement and audio flush. As a result audio is breaking on every append. Disable audio flush on samples replacement for Spotify until this is fixed by Spotify
1 parent f70f314 commit 0b254ee

5 files changed

Lines changed: 36 additions & 1 deletion

File tree

Source/WebCore/Modules/mediasource/SourceBuffer.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "BufferSource.h"
4141
#include "BufferedChangeEvent.h"
4242
#include "ContentTypeUtilities.h"
43+
#include "DocumentInlines.h"
4344
#include "Event.h"
4445
#include "EventNames.h"
4546
#include "HTMLMediaElement.h"
@@ -48,6 +49,7 @@
4849
#include "Logging.h"
4950
#include "MediaDescription.h"
5051
#include "MediaSource.h"
52+
#include "Quirks.h"
5153
#include "Settings.h"
5254
#include "SharedBuffer.h"
5355
#include "SourceBufferList.h"
@@ -185,6 +187,11 @@ SourceBuffer::SourceBuffer(Ref<SourceBufferPrivate>&& sourceBufferPrivate, Media
185187

186188
m_private->setClient(m_client);
187189
m_private->setMaximumBufferSize(maximumBufferSize());
190+
191+
RefPtr document = dynamicDowncast<Document>(scriptExecutionContext());
192+
if (document && document->quirks().shouldBypassAudioFlushOnSampleReplacement()) {
193+
m_private->setShouldBypassAudioFlushOnSampleReplacement(true);
194+
}
188195
}
189196

190197
SourceBuffer::~SourceBuffer()

Source/WebCore/page/Quirks.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,4 +1963,22 @@ std::optional<TargetedElementSelectors> Quirks::defaultVisibilityAdjustmentSelec
19631963
#endif
19641964
}
19651965

1966+
#if ENABLE(MEDIA_SOURCE)
1967+
bool Quirks::shouldBypassAudioFlushOnSampleReplacement() const
1968+
{
1969+
if (!needsQuirks())
1970+
return false;
1971+
1972+
if (m_shouldBypassAudioFlushOnSampleReplacementQuirk)
1973+
return m_shouldBypassAudioFlushOnSampleReplacementQuirk.value();
1974+
1975+
auto domain = m_document->securityOrigin().domain().convertToASCIILowercase();
1976+
1977+
m_shouldBypassAudioFlushOnSampleReplacementQuirk =
1978+
(domain.endsWith(".spotify.com"_s) || domain == "tv.scdn.co"_s);
1979+
1980+
return m_shouldBypassAudioFlushOnSampleReplacementQuirk.value();
1981+
}
1982+
#endif
1983+
19661984
}

Source/WebCore/page/Quirks.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ class Quirks {
207207
bool needsRelaxedCorsMixedContentCheckQuirk() const;
208208
bool needsLaxSameSiteCookieQuirk(const URL&) const;
209209

210+
#if ENABLE(MEDIA_SOURCE)
211+
bool shouldBypassAudioFlushOnSampleReplacement() const;
212+
#endif
213+
210214
private:
211215
bool needsQuirks() const;
212216
bool isDomain(const String&) const;
@@ -283,6 +287,9 @@ class Quirks {
283287
mutable std::optional<bool> m_needsYouTubeDarkModeQuirk;
284288

285289
Vector<RegistrableDomain> m_subFrameDomainsForStorageAccessQuirk;
290+
#if ENABLE(MEDIA_SOURCE)
291+
mutable std::optional<bool> m_shouldBypassAudioFlushOnSampleReplacementQuirk;
292+
#endif
286293
};
287294

288295
} // namespace WebCore

Source/WebCore/platform/graphics/SourceBufferPrivate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,7 @@ bool SourceBufferPrivate::processMediaSample(SourceBufferPrivateClient& client,
11521152
// Only force the TrackBuffer to re-enqueue if the removed ranges overlap with enqueued and possibly
11531153
// not yet displayed samples.
11541154
MediaTime currentTime = this->currentTime();
1155-
if (trackBuffer.highestEnqueuedPresentationTime().isValid() && currentTime < trackBuffer.highestEnqueuedPresentationTime()) {
1155+
if (trackBuffer.highestEnqueuedPresentationTime().isValid() && currentTime < trackBuffer.highestEnqueuedPresentationTime() && (!hasAudio() || !m_shouldBypassAudioFlushOnSampleReplacement)) {
11561156
PlatformTimeRanges possiblyEnqueuedRanges(currentTime, trackBuffer.highestEnqueuedPresentationTime());
11571157
possiblyEnqueuedRanges.intersectWith(erasedRanges);
11581158
if (possiblyEnqueuedRanges.length())

Source/WebCore/platform/graphics/SourceBufferPrivate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class SourceBufferPrivate
165165
virtual void attemptToDecrypt() { }
166166
#endif
167167

168+
void setShouldBypassAudioFlushOnSampleReplacement(bool flag) { m_shouldBypassAudioFlushOnSampleReplacement = flag; }
168169
protected:
169170
WEBCORE_EXPORT explicit SourceBufferPrivate(MediaSourcePrivate&, RefCountedSerialFunctionDispatcher&);
170171
MediaTime currentTime() const;
@@ -275,6 +276,8 @@ class SourceBufferPrivate
275276
MediaTime m_groupEndTimestamp { MediaTime::zeroTime() };
276277

277278
bool m_isMediaSourceEnded { false };
279+
280+
bool m_shouldBypassAudioFlushOnSampleReplacement { false };
278281
};
279282

280283
} // namespace WebCore

0 commit comments

Comments
 (0)