Skip to content

Commit

Permalink
SourceBufferPrivateClient/MediaSourcePrivateClient should use NativeP…
Browse files Browse the repository at this point in the history
…romise

https://bugs.webkit.org/show_bug.cgi?id=264847
rdar://problem/118426574

Reviewed by Youenn Fablet.

By using NativePromise, the SourceBufferPrivate and MediaSourcePrivate can be made to run on any threads
as NativePromise let you control on which thread the result of an operation should be delivered.

We make all internal SourceBufferPrivate/MediaSourcePrivate methods communicate via their respective
SourceBufferPrivateClient/MediaSourcePrivateClient using NativePromise instead of CompletionHandler.

It also allows to more explicitly handle errors.

The communication between SourceBuffer and SourceBufferPrivate will also be made to use NativePromise
in a follow-up change.

No change in behaviour in WK2, in WK1 some asynchronicity introduced which makes the behaviour more similar
to WK2

* LayoutTests/media/media-source/media-source-restrictions.html: Update test as we've introduced more asynchronicity,
and in WK1 events are fired in a different order (but still per spec). So ensure the events are still fired but
don't log them.
* Source/WebCore/Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::waitForTarget):
(WebCore::MediaSource::completeSeek):
(WebCore::MediaSource::seekToTime):
(WebCore::MediaSource::detachFromElement):
(WebCore::MediaSource::stop):
(WebCore::MediaSource::onReadyStateChange):
* Source/WebCore/Modules/mediasource/MediaSource.h:
* Source/WebCore/Modules/mediasource/SourceBuffer.cpp:
(WebCore::SourceBuffer::computeSeekTime):
(WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment):
(WebCore::SourceBuffer::sourceBufferPrivateDurationChanged):
(WebCore::SourceBuffer::sourceBufferPrivateBufferedChanged):
* Source/WebCore/Modules/mediasource/SourceBuffer.h:
* Source/WebCore/Modules/webaudio/BaseAudioContext.cpp:
(WebCore::BaseAudioContext::decodeAudioData):
* Source/WebCore/platform/audio/cocoa/AudioFileReaderCocoa.cpp:
(WebCore::AudioFileReader::demuxWebMData const):
* Source/WebCore/platform/graphics/MediaSourcePrivate.h:
* Source/WebCore/platform/graphics/MediaSourcePrivateClient.h:
* Source/WebCore/platform/graphics/SourceBufferPrivate.cpp:
(WebCore::SourceBufferPrivate::setBufferedRanges):
(WebCore::SourceBufferPrivate::updateBufferedFromTrackBuffers):
(WebCore::SourceBufferPrivate::processAppendCompletedOperation):
(WebCore::SourceBufferPrivate::computeSeekTime):
(WebCore::SourceBufferPrivate::removeCodedFrames):
(WebCore::SourceBufferPrivate::didReceiveInitializationSegment):
(WebCore::SourceBufferPrivate::didUpdateFormatDescriptionForTrackId):
(WebCore::SourceBufferPrivate::processPendingOperations):
(WebCore::SourceBufferPrivate::abortPendingOperations):
(WebCore::SourceBufferPrivate::processInitOperation):
(WebCore::SourceBufferPrivate::appendCompleted): Deleted.
* Source/WebCore/platform/graphics/SourceBufferPrivate.h:
(WebCore::SourceBufferPrivate::precheckInitialisationSegment):
(WebCore::SourceBufferPrivate::processInitialisationSegment):
(WebCore::SourceBufferPrivate::processFormatDescriptionForTrackId):
(WebCore::SourceBufferPrivate::updateBufferedFromTrackBuffers): Deleted.
(WebCore::SourceBufferPrivate::setBufferedRanges): Deleted.
* Source/WebCore/platform/graphics/SourceBufferPrivateClient.h:
(WebCore::SourceBufferPrivateClient::isAsync const): Deleted.
* Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::seekInternal):
* Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.h:
* Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm:
(WebCore::MediaSourcePrivateAVFObjC::waitForTarget):
(WebCore::MediaSourcePrivateAVFObjC::seekToTime):
* Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferParserAVFObjC.h:
* Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferParserAVFObjC.mm:
(WebCore::SourceBufferParserAVFObjC::appendData):
(WebCore::SourceBufferParserAVFObjC::didFailToParseStreamDataWithError):
* Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h:
* Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
(WebCore::SourceBufferPrivateAVFObjC::setTrackChangeCallbacks):
(WebCore::SourceBufferPrivateAVFObjC::didParseInitializationData):
(WebCore::SourceBufferPrivateAVFObjC::precheckInitialisationSegment):
(WebCore::SourceBufferPrivateAVFObjC::processInitialisationSegment):
(WebCore::SourceBufferPrivateAVFObjC::processFormatDescriptionForTrackId):
(WebCore::SourceBufferPrivateAVFObjC::appendInternal):
(WebCore::SourceBufferPrivateAVFObjC::appendCompleted):
(WebCore::SourceBufferPrivateAVFObjC::didEncounterErrorDuringParsing): Deleted.
(WebCore::SourceBufferPrivateAVFObjC::didUpdateFormatDescriptionForTrackId): Deleted.
* Source/WebCore/platform/graphics/cocoa/MediaPlayerPrivateWebM.h:
* Source/WebCore/platform/graphics/cocoa/MediaPlayerPrivateWebM.mm:
(WebCore::MediaPlayerPrivateWebM::~MediaPlayerPrivateWebM):
(WebCore::MediaPlayerPrivateWebM::append):
(WebCore::MediaPlayerPrivateWebM::didEncounterErrorDuringParsing): Deleted.
(WebCore::MediaPlayerPrivateWebM::abort): Deleted.
* Source/WebCore/platform/graphics/cocoa/SourceBufferParser.h:
* Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp:
(WebCore::SourceBufferParserWebM::appendData):
* Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h:
(WebCore::SourceBufferParserWebM::appendData): Deleted.
* Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
(WebCore::MediaPlayerPrivateGStreamerMSE::doSeek):
* Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.cpp:
(WebCore::MediaSourcePrivateGStreamer::waitForTarget):
(WebCore::MediaSourcePrivateGStreamer::seekToTime):
* Source/WebCore/platform/graphics/gstreamer/mse/MediaSourcePrivateGStreamer.h:
* Source/WebCore/platform/graphics/gstreamer/mse/SourceBufferPrivateGStreamer.cpp:
(WebCore::SourceBufferPrivateGStreamer::appendInternal):
(WebCore::SourceBufferPrivateGStreamer::didReceiveInitializationSegment):
(WebCore::SourceBufferPrivateGStreamer::precheckInitialisationSegment):
(WebCore::SourceBufferPrivateGStreamer::processInitialisationSegment):
(WebCore::SourceBufferPrivateGStreamer::didReceiveAllPendingSamples):
(WebCore::SourceBufferPrivateGStreamer::appendParsingFailed):
* Source/WebCore/platform/graphics/gstreamer/mse/SourceBufferPrivateGStreamer.h:
* Source/WebCore/platform/mock/mediasource/MockMediaPlayerMediaSource.cpp:
(WebCore::MockMediaPlayerMediaSource::seekToTarget):
* Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.cpp:
(WebCore::MockMediaSourcePrivate::waitForTarget):
(WebCore::MockMediaSourcePrivate::seekToTime):
* Source/WebCore/platform/mock/mediasource/MockMediaSourcePrivate.h:
* Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.cpp:
(WebCore::MockSourceBufferPrivate::appendInternal):
(WebCore::MockSourceBufferPrivate::didReceiveInitializationSegment):
* Source/WebCore/platform/mock/mediasource/MockSourceBufferPrivate.h:
* Source/WebKit/GPUProcess/media/RemoteMediaSourceProxy.cpp:
(WebKit::RemoteMediaSourceProxy::waitForTarget):
(WebKit::RemoteMediaSourceProxy::seekToTime):
* Source/WebKit/GPUProcess/media/RemoteMediaSourceProxy.h:
* Source/WebKit/GPUProcess/media/RemoteSourceBufferProxy.cpp:
(WebKit::RemoteSourceBufferProxy::sourceBufferPrivateDidReceiveInitializationSegment):
(WebKit::RemoteSourceBufferProxy::sourceBufferPrivateDurationChanged):
(WebKit::RemoteSourceBufferProxy::sourceBufferPrivateBufferedChanged):
(WebKit::RemoteSourceBufferProxy::computeSeekTime):
* Source/WebKit/GPUProcess/media/RemoteSourceBufferProxy.h:
* Source/WebKit/GPUProcess/media/RemoteSourceBufferProxy.messages.in:
* Source/WebKit/WebProcess/GPU/media/MediaSourcePrivateRemote.cpp:
(WebKit::MediaSourcePrivateRemote::waitForTarget):
(WebKit::MediaSourcePrivateRemote::proxyWaitForTarget):
(WebKit::MediaSourcePrivateRemote::seekToTime):
(WebKit::MediaSourcePrivateRemote::proxySeekToTime):
* Source/WebKit/WebProcess/GPU/media/MediaSourcePrivateRemote.h:
* Source/WebKit/WebProcess/GPU/media/MediaSourcePrivateRemote.messages.in:
* Source/WebKit/WebProcess/GPU/media/SourceBufferPrivateRemote.cpp:
(WebKit::SourceBufferPrivateRemote::appendInternal):
(WebKit::SourceBufferPrivateRemote::removeCodedFrames):
(WebKit::SourceBufferPrivateRemote::computeSeekTime):
(WebKit::SourceBufferPrivateRemote::sourceBufferPrivateDidReceiveInitializationSegment):
(WebKit::SourceBufferPrivateRemote::sourceBufferPrivateDurationChanged):
(WebKit::SourceBufferPrivateRemote::sourceBufferPrivateBufferedChanged):
* Source/WebKit/WebProcess/GPU/media/SourceBufferPrivateRemote.h:
* Source/WebKit/WebProcess/GPU/media/SourceBufferPrivateRemote.messages.in:

Canonical link: https://commits.webkit.org/270788@main
  • Loading branch information
jyavenard committed Nov 15, 2023
1 parent f075e7c commit f15fc78
Show file tree
Hide file tree
Showing 45 changed files with 475 additions and 582 deletions.
4 changes: 2 additions & 2 deletions LayoutTests/media/media-source/media-source-restrictions.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
initSegment = makeAInit(8, [makeATrack(1, 'mock', TRACK_KIND.AUDIO)]);
run('sourceBuffer.appendBuffer(initSegment)');

waitForEvent('pause', handlePause);
waitFor(video, 'pause', false).then(handlePause);
video.play().catch(function(error) {
failTest();
});
Expand All @@ -53,7 +53,7 @@
makeASample(7, 7, 1, 1, 1, SAMPLE_FLAG.SYNC),
]);

waitForEventOn(sourceBuffer, 'updateend', updateEnd, false, true);
waitFor(sourceBuffer, 'updateend', false).then(updateEnd);
run('sourceBuffer.appendBuffer(samples)');
}

Expand Down
99 changes: 41 additions & 58 deletions Source/WebCore/Modules/mediasource/MediaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
#include "VideoTrack.h"
#include "VideoTrackList.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/NativePromise.h>
#include <wtf/RunLoop.h>
#include <wtf/Scope.h>

namespace WebCore {
Expand Down Expand Up @@ -186,23 +188,21 @@ const PlatformTimeRanges& MediaSource::buffered() const
return m_buffered;
}

void MediaSource::waitForTarget(const SeekTarget& target, CompletionHandler<void(const MediaTime&)>&& completionHandler)
Ref<MediaSource::MediaTimePromise> MediaSource::waitForTarget(const SeekTarget& target)
{
if (isClosed()) {
completionHandler(MediaTime::invalidTime());
return;
}
if (isClosed())
return MediaTimePromise::createAndReject(-1);

ALWAYS_LOG(LOGIDENTIFIER, target.time);

// 2.4.3 Seeking
// https://rawgit.com/w3c/media-source/45627646344eea0170dd1cbc5a3d508ca751abb8/media-source-respec.html#mediasource-seeking

if (m_seekCompletedHandler) {
if (m_seekTargetPromise) {
ALWAYS_LOG(LOGIDENTIFIER, "Previous seeking to ", m_pendingSeekTarget->time, "pending, cancelling it");
m_seekCompletedHandler(MediaTime::invalidTime());
m_seekTargetPromise->reject(-1);
}
m_seekCompletedHandler = WTFMove(completionHandler);
m_seekTargetPromise.emplace();
m_pendingSeekTarget = target;

// Run the following steps as part of the "Wait until the user agent has established whether or not the
Expand All @@ -220,11 +220,13 @@ void MediaSource::waitForTarget(const SeekTarget& target, CompletionHandler<void
// than HAVE_METADATA.
monitorSourceBuffers();

return;
return *m_seekTargetPromise;
}
// ↳ Otherwise
// Continue
auto promise = static_cast<Ref<MediaTimePromise>>(*m_seekTargetPromise);
completeSeek();
return promise;
}

void MediaSource::completeSeek()
Expand All @@ -234,7 +236,7 @@ void MediaSource::completeSeek()
// 2.4.3 Seeking, ctd.
// https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource-seeking

ASSERT(m_pendingSeekTarget && m_seekCompletedHandler);
ASSERT(m_pendingSeekTarget && m_seekTargetPromise);

ALWAYS_LOG(LOGIDENTIFIER, m_pendingSeekTarget->time);

Expand All @@ -245,56 +247,33 @@ void MediaSource::completeSeek()
auto seekTarget = *m_pendingSeekTarget;
m_pendingSeekTarget.reset();

struct SeeksCallbackAggregator final : public RefCounted<SeeksCallbackAggregator> {
SeeksCallbackAggregator(MediaTime target, MediaSource& source, CompletionHandler<void(const MediaTime&)>&& completionHandler)
: time(target)
, mediaSource(source)
, completionHandler(WTFMove(completionHandler))
{
ASSERT(this->completionHandler);
}

~SeeksCallbackAggregator()
{
auto seekTime = time;
for (auto& result : seekResults) {
if (result.isInvalid()) {
completionHandler(MediaTime::invalidTime());
return;
}
if (abs(time - result) > abs(time - seekTime))
seekTime = result;
}
completionHandler(seekTime);

// 4. Resume the seek algorithm at the "Await a stable state" step.
mediaSource->monitorSourceBuffers();
Ref<MediaTimePromise> promise = SourceBuffer::ComputeSeekPromise::all(RunLoop::current(), WTF::map(*m_activeSourceBuffers, [&](auto&& sourceBuffer) {
return sourceBuffer->computeSeekTime(seekTarget);
}))->whenSettled(RunLoop::current(), [time = seekTarget.time, protectedThis = Ref { *this }] (auto&& results) mutable {
if (!results)
return MediaTimePromise::createAndReject(-1);
auto seekTime = time;
for (auto& result : *results) {
if (abs(time - result) > abs(time - seekTime))
seekTime = result;
}

MediaTime time;
Ref<MediaSource> mediaSource;
CompletionHandler<void(const MediaTime&)> completionHandler;
Vector<MediaTime> seekResults;
};

auto callbackAggregator = adoptRef(*new SeeksCallbackAggregator(seekTarget.time, *this, WTFMove(m_seekCompletedHandler)));
// 4. Resume the seek algorithm at the "Await a stable state" step.
protectedThis->monitorSourceBuffers();

for (auto& sourceBuffer : *m_activeSourceBuffers) {
sourceBuffer->computeSeekTime(seekTarget, [callbackAggregator](const MediaTime& seekTime) {
callbackAggregator->seekResults.append(seekTime);
});
}
return MediaTimePromise::createAndResolve(seekTime);
});
promise->chainTo(WTFMove(*m_seekTargetPromise));
m_seekTargetPromise.reset();
}

void MediaSource::seekToTime(const MediaTime& time, CompletionHandler<void()>&& completionHandler)
Ref<GenericPromise> MediaSource::seekToTime(const MediaTime& time)
{
if (isClosed()) {
completionHandler();
return;
}
if (isClosed())
return GenericPromise::createAndReject(-1);
for (auto& sourceBuffer : *m_activeSourceBuffers)
sourceBuffer->seekToTime(time);
completionHandler();
return GenericPromise::createAndResolve();
}

Ref<TimeRanges> MediaSource::seekable()
Expand Down Expand Up @@ -1020,8 +999,10 @@ void MediaSource::detachFromElement(HTMLMediaElement& element)
m_private = nullptr;
m_mediaElement = nullptr;

if (m_seekCompletedHandler)
m_seekCompletedHandler(MediaTime::invalidTime());
if (m_seekTargetPromise) {
m_seekTargetPromise->reject(-1);
m_seekTargetPromise.reset();
}
}

void MediaSource::sourceBufferDidChangeActiveState(SourceBuffer&, bool)
Expand Down Expand Up @@ -1087,8 +1068,9 @@ void MediaSource::stop()

if (m_mediaElement)
m_mediaElement->detachMediaSource();
if (m_seekCompletedHandler)
m_seekCompletedHandler(MediaTime::invalidTime());
if (m_seekTargetPromise)
m_seekTargetPromise->reject(-1);
m_seekTargetPromise.reset();
m_readyState = ReadyState::Closed;
m_private = nullptr;
}
Expand Down Expand Up @@ -1130,8 +1112,9 @@ void MediaSource::onReadyStateChange(ReadyState oldState, ReadyState newState)
updateBufferedIfNeeded(true /* force */);
} else {
ASSERT(isClosed());
if (m_seekCompletedHandler)
m_seekCompletedHandler(MediaTime::invalidTime());
if (m_seekTargetPromise)
m_seekTargetPromise->reject(-1);
m_seekTargetPromise.reset();
scheduleEvent(eventNames().sourcecloseEvent);
}

Expand Down
9 changes: 6 additions & 3 deletions Source/WebCore/Modules/mediasource/MediaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@
#include "HTMLMediaElement.h"
#include "MediaSourcePrivateClient.h"
#include "URLRegistry.h"
#include <optional>
#include <wtf/LoggerHelper.h>
#include <wtf/NativePromise.h>
#include <wtf/RefCounted.h>
#include <wtf/UniqueRef.h>
#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>

namespace WebCore {
Expand Down Expand Up @@ -155,8 +158,8 @@ class MediaSource
static bool isTypeSupported(ScriptExecutionContext&, const String& type, Vector<ContentType>&& contentTypesRequiringHardwareSupport);

void setPrivateAndOpen(Ref<MediaSourcePrivate>&&) final;
void waitForTarget(const SeekTarget&, CompletionHandler<void(const MediaTime&)>&&) final;
void seekToTime(const MediaTime&, CompletionHandler<void()>&&) final;
Ref<MediaTimePromise> waitForTarget(const SeekTarget&) final;
Ref<GenericPromise> seekToTime(const MediaTime&) final;

void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
Expand Down Expand Up @@ -185,7 +188,7 @@ class MediaSource
WeakPtr<HTMLMediaElement, WeakPtrImplWithEventTargetData> m_mediaElement;
MediaTime m_duration;
std::optional<SeekTarget> m_pendingSeekTarget;
CompletionHandler<void(const MediaTime&)> m_seekCompletedHandler;
std::optional<MediaTimePromise::Producer> m_seekTargetPromise;
ReadyState m_readyState { ReadyState::Closed };
bool m_openDeferred { false };
bool m_sourceopenPending { false };
Expand Down
47 changes: 18 additions & 29 deletions Source/WebCore/Modules/mediasource/SourceBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,11 +443,10 @@ void SourceBuffer::removedFromMediaSource()
m_source = nullptr;
}

void SourceBuffer::computeSeekTime(const SeekTarget& target, CompletionHandler<void(const MediaTime&)>&& completionHandler)

Ref<SourceBuffer::ComputeSeekPromise> SourceBuffer::computeSeekTime(const SeekTarget& target)
{
ALWAYS_LOG(LOGIDENTIFIER, target);
m_private->computeSeekTime(target, WTFMove(completionHandler));
return m_private->computeSeekTime(target);
}

void SourceBuffer::seekToTime(const MediaTime& time)
Expand Down Expand Up @@ -697,12 +696,10 @@ void SourceBuffer::setActive(bool active)
m_source->sourceBufferDidChangeActiveState(*this, active);
}

void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(InitializationSegment&& segment, CompletionHandler<void(ReceiveResult)>&& completionHandler)
Ref<SourceBufferPrivateClient::ReceiveResultPromise> SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(InitializationSegment&& segment)
{
if (isRemoved()) {
completionHandler(ReceiveResult::BufferRemoved);
return;
}
if (isRemoved())
return ReceiveResultPromise::createAndReject(ReceiveResult::BufferRemoved);

ALWAYS_LOG(LOGIDENTIFIER);

Expand All @@ -725,8 +722,7 @@ void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(Initializa
// with the decode error parameter set to true and abort these steps.
if (segment.audioTracks.isEmpty() && segment.videoTracks.isEmpty() && segment.textTracks.isEmpty()) {
// appendError will be called once sourceBufferPrivateAppendComplete gets called once the completionHandler is run.
completionHandler(ReceiveResult::AppendError);
return;
return ReceiveResultPromise::createAndReject(ReceiveResult::AppendError);
}

// 3. If the first initialization segment flag is true, then run the following steps:
Expand All @@ -735,8 +731,7 @@ void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(Initializa
// with the decode error parameter set to true and abort these steps.
if (!validateInitializationSegment(segment)) {
// appendError will be called once sourceBufferPrivateAppendComplete gets called once the completionHandler is run.
completionHandler(ReceiveResult::AppendError);
return;
return ReceiveResultPromise::createAndReject(ReceiveResult::AppendError);
}

Vector<std::pair<AtomString, AtomString>> trackIdPairs;
Expand Down Expand Up @@ -813,17 +808,15 @@ void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(Initializa
for (auto& audioTrackInfo : segment.audioTracks) {
if (audioTrackInfo.description && allowedMediaAudioCodecIDs->contains(FourCC::fromString(audioTrackInfo.description->codec())))
continue;
completionHandler(ReceiveResult::AppendError);
return;
return ReceiveResultPromise::createAndReject(ReceiveResult::AppendError);
}
}

if (auto& allowedMediaVideoCodecIDs = document().settings().allowedMediaVideoCodecIDs()) {
for (auto& videoTrackInfo : segment.videoTracks) {
if (videoTrackInfo.description && allowedMediaVideoCodecIDs->contains(FourCC::fromString(videoTrackInfo.description->codec())))
continue;
completionHandler(ReceiveResult::AppendError);
return;
return ReceiveResultPromise::createAndReject(ReceiveResult::AppendError);
}
}

Expand Down Expand Up @@ -951,10 +944,8 @@ void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(Initializa
if (m_private->readyState() == MediaPlayer::ReadyState::HaveNothing) {
// 6.1 If one or more objects in sourceBuffers have first initialization segment flag set to false, then abort these steps.
for (auto& sourceBuffer : *m_source->sourceBuffers()) {
if (!sourceBuffer->m_receivedFirstInitializationSegment) {
completionHandler(ReceiveResult::Succeeded);
return;
}
if (!sourceBuffer->m_receivedFirstInitializationSegment)
return ReceiveResultPromise::createAndResolve();
}

// 6.2 Set the HTMLMediaElement.readyState attribute to HAVE_METADATA.
Expand All @@ -968,7 +959,7 @@ void SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment(Initializa
if (activeTrackFlag && m_private->readyState() > MediaPlayer::ReadyState::HaveCurrentData)
m_private->setReadyState(MediaPlayer::ReadyState::HaveMetadata);

completionHandler(ReceiveResult::Succeeded);
return ReceiveResultPromise::createAndResolve();
}

bool SourceBuffer::validateInitializationSegment(const InitializationSegment& segment)
Expand Down Expand Up @@ -1180,17 +1171,15 @@ void SourceBuffer::sourceBufferPrivateDidParseSample(double frameDuration)
m_bufferedSinceLastMonitor += frameDuration;
}

void SourceBuffer::sourceBufferPrivateDurationChanged(const MediaTime& duration, CompletionHandler<void()>&& completionHandler)
Ref<GenericPromise> SourceBuffer::sourceBufferPrivateDurationChanged(const MediaTime& duration)
{
if (isRemoved()) {
completionHandler();
return;
}
if (isRemoved())
return GenericPromise::createAndReject(-1);

m_source->setDurationInternal(duration);
if (m_textTracks)
m_textTracks->setDuration(duration);
completionHandler();
return GenericPromise::createAndResolve();
}

void SourceBuffer::sourceBufferPrivateHighestPresentationTimestampChanged(const MediaTime& timestamp)
Expand Down Expand Up @@ -1351,7 +1340,7 @@ void SourceBuffer::setShouldGenerateTimestamps(bool flag)
m_private->setShouldGenerateTimestamps(flag);
}

void SourceBuffer::sourceBufferPrivateBufferedChanged(const PlatformTimeRanges& ranges, CompletionHandler<void()>&& completionHandler)
Ref<GenericPromise> SourceBuffer::sourceBufferPrivateBufferedChanged(const PlatformTimeRanges& ranges)
{
ASSERT(ranges != m_buffered->ranges(), "sourceBufferPrivateBufferedChanged should only be called if the ranges did change");
#if ENABLE(MANAGED_MEDIA_SOURCE)
Expand All @@ -1369,7 +1358,7 @@ void SourceBuffer::sourceBufferPrivateBufferedChanged(const PlatformTimeRanges&
#endif
m_buffered = TimeRanges::create(ranges);
setBufferedDirty(true);
completionHandler();
return GenericPromise::createAndResolve();
}

bool SourceBuffer::isBufferedDirty() const
Expand Down
9 changes: 5 additions & 4 deletions Source/WebCore/Modules/mediasource/SourceBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ class SourceBuffer

void abortIfUpdating();
void removedFromMediaSource();
void computeSeekTime(const SeekTarget&, CompletionHandler<void(const MediaTime&)>&&);
using ComputeSeekPromise = SourceBufferPrivate::ComputeSeekPromise;
Ref<ComputeSeekPromise> computeSeekTime(const SeekTarget&);
void seekToTime(const MediaTime&);

bool canPlayThroughRange(const PlatformTimeRanges&);
Expand Down Expand Up @@ -163,11 +164,11 @@ class SourceBuffer
bool virtualHasPendingActivity() const final;

// SourceBufferPrivateClient
void sourceBufferPrivateDidReceiveInitializationSegment(InitializationSegment&&, CompletionHandler<void(ReceiveResult)>&&) final;
Ref<ReceiveResultPromise> sourceBufferPrivateDidReceiveInitializationSegment(InitializationSegment&&) final;
void sourceBufferPrivateAppendComplete(AppendResult) final;
void sourceBufferPrivateBufferedChanged(const PlatformTimeRanges&, CompletionHandler<void()>&&) final;
Ref<GenericPromise> sourceBufferPrivateBufferedChanged(const PlatformTimeRanges&) final;
void sourceBufferPrivateHighestPresentationTimestampChanged(const MediaTime&) final;
void sourceBufferPrivateDurationChanged(const MediaTime& duration, CompletionHandler<void()>&&) final;
Ref<GenericPromise> sourceBufferPrivateDurationChanged(const MediaTime& duration) final;
void sourceBufferPrivateDidParseSample(double sampleDuration) final;
void sourceBufferPrivateDidDropSample() final;
void sourceBufferPrivateDidReceiveRenderingError(int64_t errorCode) final;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/Modules/webaudio/BaseAudioContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ void BaseAudioContext::decodeAudioData(Ref<ArrayBuffer>&& audioData, RefPtr<Audi
m_audioDecoder = makeUnique<AsyncAudioDecoder>();

auto p = m_audioDecoder->decodeAsync(WTFMove(audioData), sampleRate());
p->whenSettled(RunLoop::main(), [this, activity = makePendingActivity(*this), successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), promise = WTFMove(promise)] (DecodingTaskPromise::Result&& result) mutable {
p->whenSettled(RunLoop::current(), [this, activity = makePendingActivity(*this), successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), promise = WTFMove(promise)] (DecodingTaskPromise::Result&& result) mutable {
queueTaskKeepingObjectAlive(*this, TaskSource::InternalAsyncTask, [successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback), promise = WTFMove(promise), result = WTFMove(result)]() mutable {
if (!result) {
promise->reject(WTFMove(result.error()));
Expand Down
Loading

0 comments on commit f15fc78

Please sign in to comment.