--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -747,20 +747,20 @@ MediaDecoder::DiscardOngoingSeekIfExists
void
MediaDecoder::CallSeek(const SeekTarget& aTarget, dom::Promise* aPromise)
{
MOZ_ASSERT(NS_IsMainThread());
DiscardOngoingSeekIfExists();
mSeekDOMPromise = aPromise;
- mSeekRequest.Begin(
- mDecoderStateMachine->InvokeSeek(aTarget)
- ->Then(AbstractThread::MainThread(), __func__, this,
- &MediaDecoder::OnSeekResolved, &MediaDecoder::OnSeekRejected));
+ mDecoderStateMachine->InvokeSeek(aTarget)
+ ->Then(AbstractThread::MainThread(), __func__, this,
+ &MediaDecoder::OnSeekResolved, &MediaDecoder::OnSeekRejected)
+ ->Track(mSeekRequest);
}
double
MediaDecoder::GetCurrentTime()
{
MOZ_ASSERT(NS_IsMainThread());
return mLogicalPosition;
}
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -335,24 +335,25 @@ public:
MOZ_ASSERT(!mMetadataRequest.Exists());
SLOG("Dispatching AsyncReadMetadata");
// Set mode to METADATA since we are about to read metadata.
Resource()->SetReadMode(MediaCacheStream::MODE_METADATA);
// We disconnect mMetadataRequest in Exit() so it is fine to capture
// a raw pointer here.
- mMetadataRequest.Begin(Reader()->ReadMetadata()
+ Reader()->ReadMetadata()
->Then(OwnerThread(), __func__,
[this] (MetadataHolder* aMetadata) {
OnMetadataRead(aMetadata);
},
[this] (const MediaResult& aError) {
OnMetadataNotRead(aError);
- }));
+ })
+ ->Track(mMetadataRequest);
}
void Exit() override
{
mMetadataRequest.DisconnectIfExists();
}
State GetState() const override
@@ -1103,24 +1104,25 @@ public:
RequestVideoData();
}
private:
void DemuxerSeek()
{
// Request the demuxer to perform seek.
- mSeekRequest.Begin(Reader()->Seek(mSeekJob.mTarget.ref())
+ Reader()->Seek(mSeekJob.mTarget.ref())
->Then(OwnerThread(), __func__,
[this] (const media::TimeUnit& aUnit) {
OnSeekResolved(aUnit);
},
[this] (const SeekRejectValue& aReject) {
OnSeekRejected(aReject);
- }));
+ })
+ ->Track(mSeekRequest);
}
void DoSeek() override
{
mDoneAudioSeeking = !Info().HasAudio() || mSeekJob.mTarget->IsVideoOnly();
mDoneVideoSeeking = !Info().HasVideo();
if (mSeekJob.mTarget->IsVideoOnly()) {
@@ -1186,30 +1188,28 @@ private:
if (aReject.mError == NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA) {
SLOG("OnSeekRejected reason=WAITING_FOR_DATA type=%d", aReject.mType);
MOZ_ASSERT(!mMaster->IsRequestingAudioData());
MOZ_ASSERT(!mMaster->IsRequestingVideoData());
MOZ_ASSERT(!mMaster->IsWaitingAudioData());
MOZ_ASSERT(!mMaster->IsWaitingVideoData());
// Fire 'waiting' to notify the player that we are waiting for data.
mMaster->UpdateNextFrameStatus(MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING);
- mWaitRequest.Begin(
- Reader()->WaitForData(aReject.mType)->Then(
- OwnerThread(), __func__,
- [this] (MediaData::Type aType) {
- SLOG("OnSeekRejected wait promise resolved");
- mWaitRequest.Complete();
- DemuxerSeek();
- },
- [this] (const WaitForDataRejectValue& aRejection) {
- SLOG("OnSeekRejected wait promise rejected");
- mWaitRequest.Complete();
- mMaster->DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
- })
- );
+ Reader()->WaitForData(aReject.mType)->Then(
+ OwnerThread(), __func__,
+ [this] (MediaData::Type aType) {
+ SLOG("OnSeekRejected wait promise resolved");
+ mWaitRequest.Complete();
+ DemuxerSeek();
+ },
+ [this] (const WaitForDataRejectValue& aRejection) {
+ SLOG("OnSeekRejected wait promise rejected");
+ mWaitRequest.Complete();
+ mMaster->DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
+ })->Track(mWaitRequest);
return;
}
MOZ_ASSERT(NS_FAILED(aReject.mError), "Cancels should also disconnect mSeekRequest");
mMaster->DecodeError(aReject.mError);
}
void RequestAudioData()
@@ -2723,20 +2723,21 @@ nsresult MediaDecoderStateMachine::Init(
mOnMediaNotSeekable = mReader->OnMediaNotSeekable().Connect(
OwnerThread(), [this] () {
mMediaSeekable = false;
});
mMediaSink = CreateMediaSink(mAudioCaptured);
- mCDMProxyPromise.Begin(aDecoder->RequestCDMProxy()->Then(
+ aDecoder->RequestCDMProxy()->Then(
OwnerThread(), __func__, this,
&MediaDecoderStateMachine::OnCDMProxyReady,
- &MediaDecoderStateMachine::OnCDMProxyNotReady));
+ &MediaDecoderStateMachine::OnCDMProxyNotReady)
+ ->Track(mCDMProxyPromise);
nsresult rv = mReader->Init();
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<MediaDecoderStateMachine> self = this;
OwnerThread()->Dispatch(NS_NewRunnableFunction([self] () {
MOZ_ASSERT(self->mState == DECODER_STATE_DECODING_METADATA);
MOZ_ASSERT(!self->mStateObj);
@@ -3003,149 +3004,143 @@ MediaDecoderStateMachine::RequestAudioDa
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(IsAudioDecoding());
MOZ_ASSERT(!IsRequestingAudioData());
MOZ_ASSERT(!IsWaitingAudioData());
SAMPLE_LOG("Queueing audio task - queued=%i, decoder-queued=%o",
AudioQueue().GetSize(), mReader->SizeOfAudioQueueInFrames());
- mAudioDataRequest.Begin(
- mReader->RequestAudioData()->Then(
- OwnerThread(), __func__,
- [this] (MediaData* aAudio) {
- MOZ_ASSERT(aAudio);
- mAudioDataRequest.Complete();
- // audio->GetEndTime() is not always mono-increasing in chained ogg.
- mDecodedAudioEndTime = std::max(aAudio->GetEndTime(), mDecodedAudioEndTime);
- SAMPLE_LOG("OnAudioDecoded [%lld,%lld]", aAudio->mTime, aAudio->GetEndTime());
- mStateObj->HandleAudioDecoded(aAudio);
- },
- [this] (const MediaResult& aError) {
- SAMPLE_LOG("OnAudioNotDecoded aError=%u", aError.Code());
- mAudioDataRequest.Complete();
- switch (aError.Code()) {
- case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
- mStateObj->HandleWaitingForAudio();
- break;
- case NS_ERROR_DOM_MEDIA_CANCELED:
- mStateObj->HandleAudioCanceled();
- break;
- case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
- mStateObj->HandleEndOfAudio();
- break;
- default:
- DecodeError(aError);
- }
- })
- );
+ mReader->RequestAudioData()->Then(
+ OwnerThread(), __func__,
+ [this] (MediaData* aAudio) {
+ MOZ_ASSERT(aAudio);
+ mAudioDataRequest.Complete();
+ // audio->GetEndTime() is not always mono-increasing in chained ogg.
+ mDecodedAudioEndTime = std::max(aAudio->GetEndTime(), mDecodedAudioEndTime);
+ SAMPLE_LOG("OnAudioDecoded [%lld,%lld]", aAudio->mTime, aAudio->GetEndTime());
+ mStateObj->HandleAudioDecoded(aAudio);
+ },
+ [this] (const MediaResult& aError) {
+ SAMPLE_LOG("OnAudioNotDecoded aError=%u", aError.Code());
+ mAudioDataRequest.Complete();
+ switch (aError.Code()) {
+ case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
+ mStateObj->HandleWaitingForAudio();
+ break;
+ case NS_ERROR_DOM_MEDIA_CANCELED:
+ mStateObj->HandleAudioCanceled();
+ break;
+ case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
+ mStateObj->HandleEndOfAudio();
+ break;
+ default:
+ DecodeError(aError);
+ }
+ })->Track(mAudioDataRequest);
}
void
MediaDecoderStateMachine::RequestVideoData(bool aSkipToNextKeyframe,
const media::TimeUnit& aCurrentTime)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(IsVideoDecoding());
MOZ_ASSERT(!IsRequestingVideoData());
MOZ_ASSERT(!IsWaitingVideoData());
SAMPLE_LOG("Queueing video task - queued=%i, decoder-queued=%o, skip=%i, time=%lld",
VideoQueue().GetSize(), mReader->SizeOfVideoQueueInFrames(), aSkipToNextKeyframe,
aCurrentTime.ToMicroseconds());
TimeStamp videoDecodeStartTime = TimeStamp::Now();
- mVideoDataRequest.Begin(
- mReader->RequestVideoData(aSkipToNextKeyframe, aCurrentTime)->Then(
- OwnerThread(), __func__,
- [this, videoDecodeStartTime] (MediaData* aVideo) {
- MOZ_ASSERT(aVideo);
- mVideoDataRequest.Complete();
- // Handle abnormal or negative timestamps.
- mDecodedVideoEndTime = std::max(mDecodedVideoEndTime, aVideo->GetEndTime());
- SAMPLE_LOG("OnVideoDecoded [%lld,%lld]", aVideo->mTime, aVideo->GetEndTime());
- mStateObj->HandleVideoDecoded(aVideo, videoDecodeStartTime);
- },
- [this] (const MediaResult& aError) {
- SAMPLE_LOG("OnVideoNotDecoded aError=%u", aError.Code());
- mVideoDataRequest.Complete();
- switch (aError.Code()) {
- case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
- mStateObj->HandleWaitingForVideo();
- break;
- case NS_ERROR_DOM_MEDIA_CANCELED:
- mStateObj->HandleVideoCanceled();
- break;
- case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
- mStateObj->HandleEndOfVideo();
- break;
- default:
- DecodeError(aError);
- }
- })
- );
+ mReader->RequestVideoData(aSkipToNextKeyframe, aCurrentTime)->Then(
+ OwnerThread(), __func__,
+ [this, videoDecodeStartTime] (MediaData* aVideo) {
+ MOZ_ASSERT(aVideo);
+ mVideoDataRequest.Complete();
+ // Handle abnormal or negative timestamps.
+ mDecodedVideoEndTime = std::max(mDecodedVideoEndTime, aVideo->GetEndTime());
+ SAMPLE_LOG("OnVideoDecoded [%lld,%lld]", aVideo->mTime, aVideo->GetEndTime());
+ mStateObj->HandleVideoDecoded(aVideo, videoDecodeStartTime);
+ },
+ [this] (const MediaResult& aError) {
+ SAMPLE_LOG("OnVideoNotDecoded aError=%u", aError.Code());
+ mVideoDataRequest.Complete();
+ switch (aError.Code()) {
+ case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
+ mStateObj->HandleWaitingForVideo();
+ break;
+ case NS_ERROR_DOM_MEDIA_CANCELED:
+ mStateObj->HandleVideoCanceled();
+ break;
+ case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
+ mStateObj->HandleEndOfVideo();
+ break;
+ default:
+ DecodeError(aError);
+ }
+ })->Track(mVideoDataRequest);
}
void
MediaDecoderStateMachine::WaitForData(MediaData::Type aType)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_ASSERT(aType == MediaData::AUDIO_DATA || aType == MediaData::VIDEO_DATA);
if (aType == MediaData::AUDIO_DATA) {
- mAudioWaitRequest.Begin(
- mReader->WaitForData(MediaData::AUDIO_DATA)->Then(
- OwnerThread(), __func__,
- [this] (MediaData::Type aType) {
- mAudioWaitRequest.Complete();
- MOZ_ASSERT(aType == MediaData::AUDIO_DATA);
- mStateObj->HandleAudioWaited(aType);
- },
- [this] (const WaitForDataRejectValue& aRejection) {
- mAudioWaitRequest.Complete();
- DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
- })
- );
+ mReader->WaitForData(MediaData::AUDIO_DATA)->Then(
+ OwnerThread(), __func__,
+ [this] (MediaData::Type aType) {
+ mAudioWaitRequest.Complete();
+ MOZ_ASSERT(aType == MediaData::AUDIO_DATA);
+ mStateObj->HandleAudioWaited(aType);
+ },
+ [this] (const WaitForDataRejectValue& aRejection) {
+ mAudioWaitRequest.Complete();
+ DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
+ })->Track(mAudioWaitRequest);
} else {
- mVideoWaitRequest.Begin(
- mReader->WaitForData(MediaData::VIDEO_DATA)->Then(
- OwnerThread(), __func__,
- [this] (MediaData::Type aType) {
- mVideoWaitRequest.Complete();
- MOZ_ASSERT(aType == MediaData::VIDEO_DATA);
- mStateObj->HandleVideoWaited(aType);
- },
- [this] (const WaitForDataRejectValue& aRejection) {
- mVideoWaitRequest.Complete();
- DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
- })
- );
+ mReader->WaitForData(MediaData::VIDEO_DATA)->Then(
+ OwnerThread(), __func__,
+ [this] (MediaData::Type aType) {
+ mVideoWaitRequest.Complete();
+ MOZ_ASSERT(aType == MediaData::VIDEO_DATA);
+ mStateObj->HandleVideoWaited(aType);
+ },
+ [this] (const WaitForDataRejectValue& aRejection) {
+ mVideoWaitRequest.Complete();
+ DecodeError(NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA);
+ })->Track(mVideoWaitRequest);
}
}
void
MediaDecoderStateMachine::StartMediaSink()
{
MOZ_ASSERT(OnTaskQueue());
if (!mMediaSink->IsStarted()) {
mAudioCompleted = false;
mMediaSink->Start(GetMediaTime(), Info());
auto videoPromise = mMediaSink->OnEnded(TrackInfo::kVideoTrack);
auto audioPromise = mMediaSink->OnEnded(TrackInfo::kAudioTrack);
if (audioPromise) {
- mMediaSinkAudioPromise.Begin(audioPromise->Then(
+ audioPromise->Then(
OwnerThread(), __func__, this,
&MediaDecoderStateMachine::OnMediaSinkAudioComplete,
- &MediaDecoderStateMachine::OnMediaSinkAudioError));
+ &MediaDecoderStateMachine::OnMediaSinkAudioError)
+ ->Track(mMediaSinkAudioPromise);
}
if (videoPromise) {
- mMediaSinkVideoPromise.Begin(videoPromise->Then(
+ videoPromise->Then(
OwnerThread(), __func__, this,
&MediaDecoderStateMachine::OnMediaSinkVideoComplete,
- &MediaDecoderStateMachine::OnMediaSinkVideoError));
+ &MediaDecoderStateMachine::OnMediaSinkVideoError)
+ ->Track(mMediaSinkVideoPromise);
}
}
}
bool
MediaDecoderStateMachine::HasLowDecodedAudio()
{
MOZ_ASSERT(OnTaskQueue());
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -285,28 +285,28 @@ private:
void
MediaFormatReader::DecoderFactory::RunStage(TrackType aTrack)
{
auto& data = aTrack == TrackInfo::kAudioTrack ? mAudio : mVideo;
switch (data.mStage) {
case Stage::None: {
MOZ_ASSERT(!data.mToken);
- data.mTokenPromise.Begin(DecoderAllocPolicy::Instance(aTrack).Alloc()->Then(
+ DecoderAllocPolicy::Instance(aTrack).Alloc()->Then(
mOwner->OwnerThread(), __func__,
[this, &data, aTrack] (Token* aToken) {
data.mTokenPromise.Complete();
data.mToken = aToken;
data.mStage = Stage::CreateDecoder;
RunStage(aTrack);
},
[&data] () {
data.mTokenPromise.Complete();
data.mStage = Stage::None;
- }));
+ })->Track(data.mTokenPromise);
data.mStage = Stage::WaitForToken;
break;
}
case Stage::WaitForToken: {
MOZ_ASSERT(!data.mToken);
MOZ_ASSERT(data.mTokenPromise.Exists());
break;
@@ -404,34 +404,34 @@ MediaFormatReader::DecoderFactory::DoCre
}
void
MediaFormatReader::DecoderFactory::DoInitDecoder(TrackType aTrack)
{
auto& ownerData = mOwner->GetDecoderData(aTrack);
auto& data = aTrack == TrackInfo::kAudioTrack ? mAudio : mVideo;
- data.mInitPromise.Begin(data.mDecoder->Init()->Then(
+ data.mDecoder->Init()->Then(
mOwner->OwnerThread(), __func__,
[this, &data, &ownerData] (TrackType aTrack) {
data.mInitPromise.Complete();
data.mStage = Stage::None;
MutexAutoLock lock(ownerData.mMutex);
ownerData.mDecoder = data.mDecoder.forget();
ownerData.mDescription = ownerData.mDecoder->GetDescriptionName();
mOwner->SetVideoDecodeThreshold();
mOwner->ScheduleUpdate(aTrack);
},
[this, &data, aTrack] (MediaResult aError) {
data.mInitPromise.Complete();
data.mStage = Stage::None;
data.mDecoder->Shutdown();
data.mDecoder = nullptr;
mOwner->NotifyError(aTrack, aError);
- }));
+ })->Track(data.mInitPromise);
}
// DemuxerProxy ensures that the original main demuxer is only ever accessed
// via its own dedicated task queue.
// This ensure that the reader's taskqueue will never blocked while a demuxer
// is itself blocked attempting to access the MediaCache or the MediaResource.
class MediaFormatReader::DemuxerProxy
{
@@ -972,20 +972,21 @@ MediaFormatReader::AsyncReadMetadata()
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = nullptr;
return MetadataPromise::CreateAndResolve(metadata, __func__);
}
RefPtr<MetadataPromise> p = mMetadataPromise.Ensure(__func__);
- mDemuxerInitRequest.Begin(mDemuxer->Init()
- ->Then(OwnerThread(), __func__, this,
- &MediaFormatReader::OnDemuxerInitDone,
- &MediaFormatReader::OnDemuxerInitFailed));
+ mDemuxer->Init()
+ ->Then(OwnerThread(), __func__, this,
+ &MediaFormatReader::OnDemuxerInitDone,
+ &MediaFormatReader::OnDemuxerInitFailed)
+ ->Track(mDemuxerInitRequest);
return p;
}
void
MediaFormatReader::OnDemuxerInitDone(nsresult)
{
MOZ_ASSERT(OnTaskQueue());
mDemuxerInitRequest.Complete();
@@ -1272,19 +1273,20 @@ MediaFormatReader::DoDemuxVideo()
[self] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
self->OnFirstDemuxCompleted(TrackInfo::kVideoTrack, aSamples);
},
[self] (const MediaResult& aError) {
self->OnFirstDemuxFailed(TrackInfo::kVideoTrack, aError);
});
}
- mVideo.mDemuxRequest.Begin(p->Then(OwnerThread(), __func__, this,
- &MediaFormatReader::OnVideoDemuxCompleted,
- &MediaFormatReader::OnVideoDemuxFailed));
+ p->Then(OwnerThread(), __func__, this,
+ &MediaFormatReader::OnVideoDemuxCompleted,
+ &MediaFormatReader::OnVideoDemuxFailed)
+ ->Track(mVideo.mDemuxRequest);
}
void
MediaFormatReader::OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples)
{
LOGV("%d video samples demuxed (sid:%d)",
aSamples->mSamples.Length(),
aSamples->mSamples[0]->mTrackInfo ? aSamples->mSamples[0]->mTrackInfo->GetID() : 0);
@@ -1338,19 +1340,20 @@ MediaFormatReader::DoDemuxAudio()
[self] (RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples) {
self->OnFirstDemuxCompleted(TrackInfo::kAudioTrack, aSamples);
},
[self] (const MediaResult& aError) {
self->OnFirstDemuxFailed(TrackInfo::kAudioTrack, aError);
});
}
- mAudio.mDemuxRequest.Begin(p->Then(OwnerThread(), __func__, this,
- &MediaFormatReader::OnAudioDemuxCompleted,
- &MediaFormatReader::OnAudioDemuxFailed));
+ p->Then(OwnerThread(), __func__, this,
+ &MediaFormatReader::OnAudioDemuxCompleted,
+ &MediaFormatReader::OnAudioDemuxFailed)
+ ->Track(mAudio.mDemuxRequest);
}
void
MediaFormatReader::OnAudioDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples)
{
LOGV("%d audio samples demuxed (sid:%d)",
aSamples->mSamples.Length(),
aSamples->mSamples[0]->mTrackInfo ? aSamples->mSamples[0]->mTrackInfo->GetID() : 0);
@@ -1700,47 +1703,48 @@ MediaFormatReader::InternalSeek(TrackTyp
LOG("%s internal seek to %f",
TrackTypeToStr(aTrack), aTarget.Time().ToSeconds());
auto& decoder = GetDecoderData(aTrack);
decoder.Flush();
decoder.ResetDemuxer();
decoder.mTimeThreshold = Some(aTarget);
RefPtr<MediaFormatReader> self = this;
- decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref().Time())
- ->Then(OwnerThread(), __func__,
- [self, aTrack] (media::TimeUnit aTime) {
- auto& decoder = self->GetDecoderData(aTrack);
- decoder.mSeekRequest.Complete();
- MOZ_ASSERT(decoder.mTimeThreshold,
- "Seek promise must be disconnected when timethreshold is reset");
- decoder.mTimeThreshold.ref().mHasSeeked = true;
- self->SetVideoDecodeThreshold();
- self->ScheduleUpdate(aTrack);
- },
- [self, aTrack] (const MediaResult& aError) {
- auto& decoder = self->GetDecoderData(aTrack);
- decoder.mSeekRequest.Complete();
- switch (aError.Code()) {
- case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
- self->NotifyWaitingForData(aTrack);
- break;
- case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
- decoder.mTimeThreshold.reset();
- self->NotifyEndOfStream(aTrack);
- break;
- case NS_ERROR_DOM_MEDIA_CANCELED:
- decoder.mTimeThreshold.reset();
- break;
- default:
- decoder.mTimeThreshold.reset();
- self->NotifyError(aTrack, aError);
- break;
- }
- }));
+ decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref().Time())
+ ->Then(OwnerThread(), __func__,
+ [self, aTrack] (media::TimeUnit aTime) {
+ auto& decoder = self->GetDecoderData(aTrack);
+ decoder.mSeekRequest.Complete();
+ MOZ_ASSERT(decoder.mTimeThreshold,
+ "Seek promise must be disconnected when timethreshold is reset");
+ decoder.mTimeThreshold.ref().mHasSeeked = true;
+ self->SetVideoDecodeThreshold();
+ self->ScheduleUpdate(aTrack);
+ },
+ [self, aTrack] (const MediaResult& aError) {
+ auto& decoder = self->GetDecoderData(aTrack);
+ decoder.mSeekRequest.Complete();
+ switch (aError.Code()) {
+ case NS_ERROR_DOM_MEDIA_WAITING_FOR_DATA:
+ self->NotifyWaitingForData(aTrack);
+ break;
+ case NS_ERROR_DOM_MEDIA_END_OF_STREAM:
+ decoder.mTimeThreshold.reset();
+ self->NotifyEndOfStream(aTrack);
+ break;
+ case NS_ERROR_DOM_MEDIA_CANCELED:
+ decoder.mTimeThreshold.reset();
+ break;
+ default:
+ decoder.mTimeThreshold.reset();
+ self->NotifyError(aTrack, aError);
+ break;
+ }
+ })
+ ->Track(decoder.mSeekRequest);
}
void
MediaFormatReader::DrainDecoder(TrackType aTrack)
{
MOZ_ASSERT(OnTaskQueue());
auto& decoder = GetDecoderData(aTrack);
@@ -2192,20 +2196,21 @@ MediaFormatReader::SkipVideoDemuxToNextK
// As such we can drop all already decoded samples and discard all pending
// samples.
// TODO: Ideally we should set mOutputRequested to false so that all pending
// frames are dropped too. However, we can't do such thing as the code assumes
// that the decoder just got flushed. Once bug 1257107 land, we could set the
// decoder threshold to the value of currentTime.
DropDecodedSamples(TrackInfo::kVideoTrack);
- mSkipRequest.Begin(mVideo.mTrackDemuxer->SkipToNextRandomAccessPoint(aTimeThreshold)
- ->Then(OwnerThread(), __func__, this,
- &MediaFormatReader::OnVideoSkipCompleted,
- &MediaFormatReader::OnVideoSkipFailed));
+ mVideo.mTrackDemuxer->SkipToNextRandomAccessPoint(aTimeThreshold)
+ ->Then(OwnerThread(), __func__, this,
+ &MediaFormatReader::OnVideoSkipCompleted,
+ &MediaFormatReader::OnVideoSkipFailed)
+ ->Track(mSkipRequest);
return;
}
void
MediaFormatReader::VideoSkipReset(uint32_t aSkipped)
{
MOZ_ASSERT(OnTaskQueue());
@@ -2403,20 +2408,21 @@ MediaFormatReader::OnSeekFailed(TrackTyp
}
void
MediaFormatReader::DoVideoSeek()
{
MOZ_ASSERT(mPendingSeekTime.isSome());
LOGV("Seeking video to %lld", mPendingSeekTime.ref().ToMicroseconds());
media::TimeUnit seekTime = mPendingSeekTime.ref();
- mVideo.mSeekRequest.Begin(mVideo.mTrackDemuxer->Seek(seekTime)
- ->Then(OwnerThread(), __func__, this,
- &MediaFormatReader::OnVideoSeekCompleted,
- &MediaFormatReader::OnVideoSeekFailed));
+ mVideo.mTrackDemuxer->Seek(seekTime)
+ ->Then(OwnerThread(), __func__, this,
+ &MediaFormatReader::OnVideoSeekCompleted,
+ &MediaFormatReader::OnVideoSeekFailed)
+ ->Track(mVideo.mSeekRequest);
}
void
MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
{
MOZ_ASSERT(OnTaskQueue());
LOGV("Video seeked to %lld", aTime.ToMicroseconds());
mVideo.mSeekRequest.Complete();
@@ -2485,20 +2491,21 @@ MediaFormatReader::SetVideoDecodeThresho
}
void
MediaFormatReader::DoAudioSeek()
{
MOZ_ASSERT(mPendingSeekTime.isSome());
LOGV("Seeking audio to %lld", mPendingSeekTime.ref().ToMicroseconds());
media::TimeUnit seekTime = mPendingSeekTime.ref();
- mAudio.mSeekRequest.Begin(mAudio.mTrackDemuxer->Seek(seekTime)
- ->Then(OwnerThread(), __func__, this,
- &MediaFormatReader::OnAudioSeekCompleted,
- &MediaFormatReader::OnAudioSeekFailed));
+ mAudio.mTrackDemuxer->Seek(seekTime)
+ ->Then(OwnerThread(), __func__, this,
+ &MediaFormatReader::OnAudioSeekCompleted,
+ &MediaFormatReader::OnAudioSeekFailed)
+ ->Track(mAudio.mSeekRequest);
}
void
MediaFormatReader::OnAudioSeekCompleted(media::TimeUnit aTime)
{
MOZ_ASSERT(OnTaskQueue());
LOGV("Audio seeked to %lld", aTime.ToMicroseconds());
mAudio.mSeekRequest.Complete();
@@ -2559,24 +2566,25 @@ MediaFormatReader::NotifyDataArrived()
// Already one in progress. Reschedule for later.
RefPtr<nsIRunnable> task(
NewRunnableMethod(this, &MediaFormatReader::NotifyDataArrived));
OwnerThread()->Dispatch(task.forget());
return;
}
RefPtr<MediaFormatReader> self = this;
- mNotifyDataArrivedPromise.Begin(mDemuxer->NotifyDataArrived()->Then(
- OwnerThread(), __func__,
- [self]() {
- self->mNotifyDataArrivedPromise.Complete();
- self->UpdateBuffered();
- self->NotifyTrackDemuxers();
- },
- [self]() { self->mNotifyDataArrivedPromise.Complete(); }));
+ mDemuxer->NotifyDataArrived()
+ ->Then(OwnerThread(), __func__,
+ [self]() {
+ self->mNotifyDataArrivedPromise.Complete();
+ self->UpdateBuffered();
+ self->NotifyTrackDemuxers();
+ },
+ [self]() { self->mNotifyDataArrivedPromise.Complete(); })
+ ->Track(mNotifyDataArrivedPromise);
}
void
MediaFormatReader::UpdateBuffered()
{
MOZ_ASSERT(OnTaskQueue());
if (mShutdown) {
--- a/dom/media/MediaTimer.h
+++ b/dom/media/MediaTimer.h
@@ -140,20 +140,21 @@ public:
RejectFunc&& aRejector)
{
MOZ_ASSERT(mTargetThread->IsCurrentThreadIn());
if (IsScheduled() && mTarget <= aTarget) {
return;
}
Reset();
mTarget = aTarget;
- mRequest.Begin(mMediaTimer->WaitUntil(mTarget, __func__)->Then(
+ mMediaTimer->WaitUntil(mTarget, __func__)->Then(
mTargetThread, __func__,
Forward<ResolveFunc>(aResolver),
- Forward<RejectFunc>(aRejector)));
+ Forward<RejectFunc>(aRejector))
+ ->Track(mRequest);
}
void CompleteRequest()
{
MOZ_ASSERT(mTargetThread->IsCurrentThreadIn());
mRequest.Complete();
mTarget = TimeStamp();
}
--- a/dom/media/android/AndroidMediaReader.cpp
+++ b/dom/media/android/AndroidMediaReader.cpp
@@ -325,25 +325,25 @@ AndroidMediaReader::Seek(const SeekTarge
// a sync point, whereas for video there are only keyframes once every few
// seconds. So if we have both audio and video, we must seek the video
// stream to the preceeding keyframe first, get the stream time, and then
// seek the audio stream to match the video stream's time. Otherwise, the
// audio and video streams won't be in sync after the seek.
mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
RefPtr<AndroidMediaReader> self = this;
- mSeekRequest.Begin(DecodeToFirstVideoData()->Then(OwnerThread(), __func__, [self] (MediaData* v) {
+ DecodeToFirstVideoData()->Then(OwnerThread(), __func__, [self] (MediaData* v) {
self->mSeekRequest.Complete();
self->mAudioSeekTimeUs = v->mTime;
self->mSeekPromise.Resolve(media::TimeUnit::FromMicroseconds(self->mAudioSeekTimeUs), __func__);
}, [self, aTarget] () {
self->mSeekRequest.Complete();
self->mAudioSeekTimeUs = aTarget.GetTime().ToMicroseconds();
self->mSeekPromise.Resolve(aTarget.GetTime(), __func__);
- }));
+ })->Track(mSeekRequest);
} else {
mAudioSeekTimeUs = mVideoSeekTimeUs = aTarget.GetTime().ToMicroseconds();
mSeekPromise.Resolve(aTarget.GetTime(), __func__);
}
return p;
}
--- a/dom/media/gtest/TestMozPromise.cpp
+++ b/dom/media/gtest/TestMozPromise.cpp
@@ -275,13 +275,13 @@ TEST(MozPromise, Chaining)
holder.Disconnect();
queue->BeginShutdown();
},
DO_FAIL);
}
}
// We will hit the assertion if we don't disconnect the leaf Request
// in the promise chain.
- holder.Begin(p->Then(queue, __func__, [] () {}, [] () {}));
+ p->Then(queue, __func__, [] () {}, [] () {})->Track(holder);
});
}
#undef DO_FAIL
--- a/dom/media/mediasink/AudioSinkWrapper.cpp
+++ b/dom/media/mediasink/AudioSinkWrapper.cpp
@@ -188,20 +188,21 @@ AudioSinkWrapper::Start(int64_t aStartTi
// no audio is equivalent to audio ended before video starts.
mAudioEnded = !aInfo.HasAudio();
if (aInfo.HasAudio()) {
mAudioSink = mCreator->Create();
mEndPromise = mAudioSink->Init(mParams);
- mAudioSinkPromise.Begin(mEndPromise->Then(
+ mEndPromise->Then(
mOwnerThread.get(), __func__, this,
&AudioSinkWrapper::OnAudioEnded,
- &AudioSinkWrapper::OnAudioEnded));
+ &AudioSinkWrapper::OnAudioEnded
+ )->Track(mAudioSinkPromise);
}
}
void
AudioSinkWrapper::Stop()
{
AssertOwnerThread();
MOZ_ASSERT(mIsStarted, "playback not started.");
--- a/dom/media/mediasink/VideoSink.cpp
+++ b/dom/media/mediasink/VideoSink.cpp
@@ -180,29 +180,30 @@ VideoSink::Start(int64_t aStartTime, con
// If the underlying MediaSink has an end promise for the video track (which
// happens when mAudioSink refers to a DecodedStream), we must wait for it
// to complete before resolving our own end promise. Otherwise, MDSM might
// stop playback before DecodedStream plays to the end and cause
// test_streams_element_capture.html to time out.
RefPtr<GenericPromise> p = mAudioSink->OnEnded(TrackInfo::kVideoTrack);
if (p) {
RefPtr<VideoSink> self = this;
- mVideoSinkEndRequest.Begin(p->Then(mOwnerThread, __func__,
+ p->Then(mOwnerThread, __func__,
[self] () {
self->mVideoSinkEndRequest.Complete();
self->TryUpdateRenderedVideoFrames();
// It is possible the video queue size is 0 and we have no frames to
// render. However, we need to call MaybeResolveEndPromise() to ensure
// mEndPromiseHolder is resolved.
self->MaybeResolveEndPromise();
}, [self] () {
self->mVideoSinkEndRequest.Complete();
self->TryUpdateRenderedVideoFrames();
self->MaybeResolveEndPromise();
- }));
+ })
+ ->Track(mVideoSinkEndRequest);
}
ConnectListener();
// Run the render loop at least once so we can resolve the end promise
// when video duration is 0.
UpdateRenderedVideoFrames();
}
}
--- a/dom/media/mediasource/SourceBuffer.cpp
+++ b/dom/media/mediasource/SourceBuffer.cpp
@@ -253,25 +253,25 @@ SourceBuffer::Remove(double aStart, doub
}
void
SourceBuffer::RangeRemoval(double aStart, double aEnd)
{
StartUpdating();
RefPtr<SourceBuffer> self = this;
- mPendingRemoval.Begin(
mTrackBuffersManager->RangeRemoval(TimeUnit::FromSeconds(aStart),
TimeUnit::FromSeconds(aEnd))
->Then(AbstractThread::MainThread(), __func__,
[self] (bool) {
self->mPendingRemoval.Complete();
self->StopUpdating();
},
- []() { MOZ_ASSERT(false); }));
+ []() { MOZ_ASSERT(false); })
+ ->Track(mPendingRemoval);
}
void
SourceBuffer::Detach()
{
MOZ_ASSERT(NS_IsMainThread());
MSE_DEBUG("Detach");
if (!mMediaSource) {
@@ -410,20 +410,21 @@ SourceBuffer::AppendData(const uint8_t*
MSE_DEBUG("AppendData(aLength=%u)", aLength);
RefPtr<MediaByteBuffer> data = PrepareAppend(aData, aLength, aRv);
if (!data) {
return;
}
StartUpdating();
- mPendingAppend.Begin(mTrackBuffersManager->AppendData(data, mCurrentAttributes)
- ->Then(AbstractThread::MainThread(), __func__, this,
- &SourceBuffer::AppendDataCompletedWithSuccess,
- &SourceBuffer::AppendDataErrored));
+ mTrackBuffersManager->AppendData(data, mCurrentAttributes)
+ ->Then(AbstractThread::MainThread(), __func__, this,
+ &SourceBuffer::AppendDataCompletedWithSuccess,
+ &SourceBuffer::AppendDataErrored)
+ ->Track(mPendingAppend);
}
void
SourceBuffer::AppendDataCompletedWithSuccess(SourceBufferTask::AppendBufferResult aResult)
{
MOZ_ASSERT(mUpdating);
mPendingAppend.Complete();
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -728,30 +728,31 @@ TrackBuffersManager::SegmentParserLoop()
mInputBuffer = nullptr;
NeedMoreData();
return;
}
}
// 3. If the input buffer contains one or more complete coded frames, then run the coded frame processing algorithm.
RefPtr<TrackBuffersManager> self = this;
- mProcessingRequest.Begin(CodedFrameProcessing()
- ->Then(GetTaskQueue(), __func__,
- [self] (bool aNeedMoreData) {
- self->mProcessingRequest.Complete();
- if (aNeedMoreData) {
- self->NeedMoreData();
- } else {
- self->ScheduleSegmentParserLoop();
- }
- },
- [self] (const MediaResult& aRejectValue) {
- self->mProcessingRequest.Complete();
- self->RejectAppend(aRejectValue, __func__);
- }));
+ CodedFrameProcessing()
+ ->Then(GetTaskQueue(), __func__,
+ [self] (bool aNeedMoreData) {
+ self->mProcessingRequest.Complete();
+ if (aNeedMoreData) {
+ self->NeedMoreData();
+ } else {
+ self->ScheduleSegmentParserLoop();
+ }
+ },
+ [self] (const MediaResult& aRejectValue) {
+ self->mProcessingRequest.Complete();
+ self->RejectAppend(aRejectValue, __func__);
+ })
+ ->Track(mProcessingRequest);
return;
}
}
}
void
TrackBuffersManager::NeedMoreData()
{
@@ -837,21 +838,22 @@ TrackBuffersManager::ResetDemuxingState(
// that data has been appended yet ; so we simply append the init segment
// to the resource.
mCurrentInputBuffer->AppendData(mParser->InitData());
CreateDemuxerforMIMEType();
if (!mInputDemuxer) {
RejectAppend(NS_ERROR_FAILURE, __func__);
return;
}
- mDemuxerInitRequest.Begin(mInputDemuxer->Init()
- ->Then(GetTaskQueue(), __func__,
- this,
- &TrackBuffersManager::OnDemuxerResetDone,
- &TrackBuffersManager::OnDemuxerInitFailed));
+ mInputDemuxer->Init()
+ ->Then(GetTaskQueue(), __func__,
+ this,
+ &TrackBuffersManager::OnDemuxerResetDone,
+ &TrackBuffersManager::OnDemuxerInitFailed)
+ ->Track(mDemuxerInitRequest);
}
void
TrackBuffersManager::OnDemuxerResetDone(nsresult)
{
MOZ_ASSERT(OnTaskQueue());
mDemuxerInitRequest.Complete();
// mInputDemuxer shouldn't have been destroyed while a demuxer init/reset
@@ -911,21 +913,22 @@ TrackBuffersManager::InitializationSegme
mInputBuffer->RemoveElementsAt(0, length);
}
CreateDemuxerforMIMEType();
if (!mInputDemuxer) {
NS_WARNING("TODO type not supported");
RejectAppend(NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__);
return;
}
- mDemuxerInitRequest.Begin(mInputDemuxer->Init()
- ->Then(GetTaskQueue(), __func__,
- this,
- &TrackBuffersManager::OnDemuxerInitDone,
- &TrackBuffersManager::OnDemuxerInitFailed));
+ mInputDemuxer->Init()
+ ->Then(GetTaskQueue(), __func__,
+ this,
+ &TrackBuffersManager::OnDemuxerInitDone,
+ &TrackBuffersManager::OnDemuxerInitFailed)
+ ->Track(mDemuxerInitRequest);
}
void
TrackBuffersManager::OnDemuxerInitDone(nsresult)
{
MOZ_ASSERT(OnTaskQueue());
MOZ_DIAGNOSTIC_ASSERT(mInputDemuxer, "mInputDemuxer has been destroyed");
@@ -1195,20 +1198,21 @@ TrackBuffersManager::OnDemuxFailed(Track
void
TrackBuffersManager::DoDemuxVideo()
{
MOZ_ASSERT(OnTaskQueue());
if (!HasVideo()) {
DoDemuxAudio();
return;
}
- mVideoTracks.mDemuxRequest.Begin(mVideoTracks.mDemuxer->GetSamples(-1)
- ->Then(GetTaskQueue(), __func__, this,
- &TrackBuffersManager::OnVideoDemuxCompleted,
- &TrackBuffersManager::OnVideoDemuxFailed));
+ mVideoTracks.mDemuxer->GetSamples(-1)
+ ->Then(GetTaskQueue(), __func__, this,
+ &TrackBuffersManager::OnVideoDemuxCompleted,
+ &TrackBuffersManager::OnVideoDemuxFailed)
+ ->Track(mVideoTracks.mDemuxRequest);
}
void
TrackBuffersManager::OnVideoDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples)
{
MOZ_ASSERT(OnTaskQueue());
MSE_DEBUG("%d video samples demuxed", aSamples->mSamples.Length());
mVideoTracks.mDemuxRequest.Complete();
@@ -1219,20 +1223,21 @@ TrackBuffersManager::OnVideoDemuxComplet
void
TrackBuffersManager::DoDemuxAudio()
{
MOZ_ASSERT(OnTaskQueue());
if (!HasAudio()) {
CompleteCodedFrameProcessing();
return;
}
- mAudioTracks.mDemuxRequest.Begin(mAudioTracks.mDemuxer->GetSamples(-1)
- ->Then(GetTaskQueue(), __func__, this,
- &TrackBuffersManager::OnAudioDemuxCompleted,
- &TrackBuffersManager::OnAudioDemuxFailed));
+ mAudioTracks.mDemuxer->GetSamples(-1)
+ ->Then(GetTaskQueue(), __func__, this,
+ &TrackBuffersManager::OnAudioDemuxCompleted,
+ &TrackBuffersManager::OnAudioDemuxFailed)
+ ->Track(mAudioTracks.mDemuxRequest);
}
void
TrackBuffersManager::OnAudioDemuxCompleted(RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples)
{
MOZ_ASSERT(OnTaskQueue());
MSE_DEBUG("%d audio samples demuxed", aSamples->mSamples.Length());
mAudioTracks.mDemuxRequest.Complete();
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -55,20 +55,21 @@ public:
return;
}
nsAutoPtr<MediaRawDataWriter> writer(aSample->CreateWriter());
mProxy->GetSessionIdsForKeyId(aSample->mCrypto.mKeyId,
writer->mCrypto.mSessionIds);
mDecrypts.Put(aSample, new DecryptPromiseRequestHolder());
- mDecrypts.Get(aSample)->Begin(mProxy->Decrypt(aSample)->Then(
+ mProxy->Decrypt(aSample)->Then(
mTaskQueue, __func__, this,
&EMEDecryptor::Decrypted,
- &EMEDecryptor::Decrypted));
+ &EMEDecryptor::Decrypted)
+ ->Track(*mDecrypts.Get(aSample));
return;
}
void Decrypted(const DecryptResult& aDecrypted) {
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
MOZ_ASSERT(aDecrypted.mSample);
nsAutoPtr<DecryptPromiseRequestHolder> holder;
--- a/dom/media/platforms/wrappers/FuzzingWrapper.cpp
+++ b/dom/media/platforms/wrappers/FuzzingWrapper.cpp
@@ -237,33 +237,33 @@ void
DecoderCallbackFuzzingWrapper::ScheduleOutputDelayedFrame()
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mDelayedOutputRequest.Exists()) {
// A delayed output is already scheduled, no need for more than one timer.
return;
}
RefPtr<DecoderCallbackFuzzingWrapper> self = this;
- mDelayedOutputRequest.Begin(
- mDelayedOutputTimer->WaitUntil(
- mPreviousOutput + mFrameOutputMinimumInterval,
- __func__)
- ->Then(mTaskQueue, __func__,
- [self] () -> void {
- if (self->mDelayedOutputRequest.Exists()) {
- self->mDelayedOutputRequest.Complete();
- self->OutputDelayedFrame();
- }
- },
- [self] () -> void {
- if (self->mDelayedOutputRequest.Exists()) {
- self->mDelayedOutputRequest.Complete();
- self->ClearDelayedOutput();
- }
- }));
+ mDelayedOutputTimer->WaitUntil(
+ mPreviousOutput + mFrameOutputMinimumInterval,
+ __func__)
+ ->Then(mTaskQueue, __func__,
+ [self] () -> void {
+ if (self->mDelayedOutputRequest.Exists()) {
+ self->mDelayedOutputRequest.Complete();
+ self->OutputDelayedFrame();
+ }
+ },
+ [self] () -> void {
+ if (self->mDelayedOutputRequest.Exists()) {
+ self->mDelayedOutputRequest.Complete();
+ self->ClearDelayedOutput();
+ }
+ })
+ ->Track(mDelayedOutputRequest);
}
void
DecoderCallbackFuzzingWrapper::OutputDelayedFrame()
{
MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());
if (mDelayedOutput.empty()) {
if (mDraining) {
--- a/dom/media/platforms/wrappers/H264Converter.cpp
+++ b/dom/media/platforms/wrappers/H264Converter.cpp
@@ -226,20 +226,21 @@ H264Converter::CreateDecoderAndInit(Medi
UpdateConfigFromExtraData(extra_data);
nsresult rv = CreateDecoder(/* DecoderDoctorDiagnostics* */ nullptr);
if (NS_SUCCEEDED(rv)) {
// Queue the incoming sample.
mMediaRawSamples.AppendElement(aSample);
- mInitPromiseRequest.Begin(mDecoder->Init()
+ mDecoder->Init()
->Then(AbstractThread::GetCurrent()->AsTaskQueue(), __func__, this,
&H264Converter::OnDecoderInitDone,
- &H264Converter::OnDecoderInitFailed));
+ &H264Converter::OnDecoderInitFailed)
+ ->Track(mInitPromiseRequest);
return NS_ERROR_NOT_INITIALIZED;
}
return rv;
}
void
H264Converter::OnDecoderInitDone(const TrackType aTrackType)
{
--- a/xpcom/threads/MozPromise.h
+++ b/xpcom/threads/MozPromise.h
@@ -1055,28 +1055,16 @@ private:
*/
template<typename PromiseType>
class MozPromiseRequestHolder
{
public:
MozPromiseRequestHolder() {}
~MozPromiseRequestHolder() { MOZ_ASSERT(!mRequest); }
- void Begin(RefPtr<typename PromiseType::Request>&& aRequest)
- {
- MOZ_DIAGNOSTIC_ASSERT(!Exists());
- mRequest = Move(aRequest);
- }
-
- void Begin(typename PromiseType::Request* aRequest)
- {
- MOZ_DIAGNOSTIC_ASSERT(!Exists());
- mRequest = aRequest;
- }
-
void Track(RefPtr<typename PromiseType::Request>&& aRequest)
{
MOZ_DIAGNOSTIC_ASSERT(!Exists());
mRequest = Move(aRequest);
}
void Complete()
{