diff --git a/dom/media/MediaPromise.cpp b/dom/media/MediaPromise.cpp index d9c44bf6a3e..57b1bb7c5c2 100644 --- a/dom/media/MediaPromise.cpp +++ b/dom/media/MediaPromise.cpp @@ -23,18 +23,5 @@ DispatchMediaPromiseRunnable(nsIEventTarget* aEventTarget, nsIRunnable* aRunnabl return aEventTarget->Dispatch(aRunnable, NS_DISPATCH_NORMAL); } -void -AssertOnThread(MediaTaskQueue* aQueue) -{ - MOZ_ASSERT(aQueue->IsCurrentThreadIn()); -} - -void AssertOnThread(nsIEventTarget* aTarget) -{ - nsCOMPtr targetThread = do_QueryInterface(aTarget); - MOZ_ASSERT(targetThread, "Don't know how to deal with threadpools etc here"); - MOZ_ASSERT(NS_GetCurrentThread() == targetThread); -} - } } // namespace mozilla diff --git a/dom/media/MediaPromise.h b/dom/media/MediaPromise.h index f7711236793..89d37247c89 100644 --- a/dom/media/MediaPromise.h +++ b/dom/media/MediaPromise.h @@ -37,11 +37,6 @@ namespace detail { nsresult DispatchMediaPromiseRunnable(MediaTaskQueue* aQueue, nsIRunnable* aRunnable); nsresult DispatchMediaPromiseRunnable(nsIEventTarget* aTarget, nsIRunnable* aRunnable); -#ifdef DEBUG -void AssertOnThread(MediaTaskQueue* aQueue); -void AssertOnThread(nsIEventTarget* aTarget); -#endif - } // namespace detail /* @@ -86,32 +81,6 @@ public: return p; } - class Consumer - { - public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Consumer) - - void Disconnect() - { - AssertOnDispatchThread(); - MOZ_RELEASE_ASSERT(!mComplete); - mDisconnected = true; - } - -#ifdef DEBUG - virtual void AssertOnDispatchThread() = 0; -#else - void AssertOnDispatchThread() {} -#endif - - protected: - Consumer() : mComplete(false), mDisconnected(false) {} - virtual ~Consumer() {} - - bool mComplete; - bool mDisconnected; - }; - protected: /* @@ -120,7 +89,7 @@ protected: * resolved or rejected, a {Resolve,Reject}Runnable is dispatched, which * invokes the resolve/reject method and then deletes the ThenValue. */ - class ThenValueBase : public Consumer + class ThenValueBase { public: class ResolveRunnable : public nsRunnable @@ -139,12 +108,14 @@ protected: { PROMISE_LOG("ResolveRunnable::Run() [this=%p]", this); mThenValue->DoResolve(mResolveValue); + + delete mThenValue; mThenValue = nullptr; return NS_OK; } private: - nsRefPtr mThenValue; + ThenValueBase* mThenValue; ResolveValueType mResolveValue; }; @@ -164,20 +135,28 @@ protected: { PROMISE_LOG("RejectRunnable::Run() [this=%p]", this); mThenValue->DoReject(mRejectValue); + + delete mThenValue; mThenValue = nullptr; return NS_OK; } private: - nsRefPtr mThenValue; + ThenValueBase* mThenValue; RejectValueType mRejectValue; }; - explicit ThenValueBase(const char* aCallSite) : mCallSite(aCallSite) {} + explicit ThenValueBase(const char* aCallSite) : mCallSite(aCallSite) + { + MOZ_COUNT_CTOR(ThenValueBase); + } virtual void Dispatch(MediaPromise *aPromise) = 0; protected: + // This may only be deleted by {Resolve,Reject}Runnable::Run. + virtual ~ThenValueBase() { MOZ_COUNT_DTOR(ThenValueBase); } + virtual void DoResolve(ResolveValueType aResolveValue) = 0; virtual void DoReject(RejectValueType aRejectValue) = 0; @@ -239,48 +218,19 @@ protected: MOZ_ASSERT(NS_SUCCEEDED(rv)); } -#ifdef DEBUG - void AssertOnDispatchThread() MOZ_OVERRIDE - { - detail::AssertOnThread(mResponseTarget); - } -#endif - protected: virtual void DoResolve(ResolveValueType aResolveValue) MOZ_OVERRIDE { - Consumer::mComplete = true; - if (Consumer::mDisconnected) { - PROMISE_LOG("ThenValue::DoResolve disconnected - bailing out [this=%p]", this); - return; - } InvokeCallbackMethod(mThisVal.get(), mResolveMethod, aResolveValue); - - // Null these out after invoking the callback so that any references are - // released predictably on the target thread. Otherwise, they would be - // released on whatever thread last drops its reference to the ThenValue, - // which may or may not be ok. - mResponseTarget = nullptr; - mThisVal = nullptr; } virtual void DoReject(RejectValueType aRejectValue) MOZ_OVERRIDE { - Consumer::mComplete = true; - if (Consumer::mDisconnected) { - PROMISE_LOG("ThenValue::DoReject disconnected - bailing out [this=%p]", this); - return; - } InvokeCallbackMethod(mThisVal.get(), mRejectMethod, aRejectValue); - - // Null these out after invoking the callback so that any references are - // released predictably on the target thread. Otherwise, they would be - // released on whatever thread last drops its reference to the ThenValue, - // which may or may not be ok. - mResponseTarget = nullptr; - mThisVal = nullptr; } + virtual ~ThenValue() {} + private: nsRefPtr mResponseTarget; nsRefPtr mThisVal; @@ -291,35 +241,23 @@ public: template - already_AddRefed RefableThen(TargetType* aResponseTarget, const char* aCallSite, ThisType* aThisVal, - ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod) + void Then(TargetType* aResponseTarget, const char* aCallSite, ThisType* aThisVal, + ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod) { MutexAutoLock lock(mMutex); MOZ_RELEASE_ASSERT(!IsExclusive || !mHaveConsumer); mHaveConsumer = true; - nsRefPtr thenValue = new ThenValue(aResponseTarget, aThisVal, - aResolveMethod, aRejectMethod, - aCallSite); + ThenValueBase* thenValue = new ThenValue(aResponseTarget, aThisVal, + aResolveMethod, aRejectMethod, + aCallSite); PROMISE_LOG("%s invoking Then() [this=%p, thenValue=%p, aThisVal=%p, isPending=%d]", - aCallSite, this, thenValue.get(), aThisVal, (int) IsPending()); + aCallSite, this, thenValue, aThisVal, (int) IsPending()); if (!IsPending()) { thenValue->Dispatch(this); } else { mThenValues.AppendElement(thenValue); } - - return thenValue.forget(); - } - - template - void Then(TargetType* aResponseTarget, const char* aCallSite, ThisType* aThisVal, - ResolveMethodType aResolveMethod, RejectMethodType aRejectMethod) - { - nsRefPtr c = - RefableThen(aResponseTarget, aCallSite, aThisVal, aResolveMethod, aRejectMethod); - return; } void ChainTo(already_AddRefed aChainedPromise, const char* aCallSite) @@ -393,7 +331,7 @@ protected: Mutex mMutex; Maybe mResolveValue; Maybe mRejectValue; - nsTArray> mThenValues; + nsTArray mThenValues; nsTArray> mChainedPromises; bool mHaveConsumer; }; @@ -487,49 +425,6 @@ private: nsRefPtr mPromise; }; -/* - * Class to encapsulate a MediaPromise::Consumer reference. Use this as the member - * variable for a class waiting on a media promise. - */ -template -class MediaPromiseConsumerHolder -{ -public: - MediaPromiseConsumerHolder() {} - ~MediaPromiseConsumerHolder() { MOZ_ASSERT(!mConsumer); } - - void Begin(already_AddRefed aConsumer) - { - MOZ_RELEASE_ASSERT(!Exists()); - mConsumer = aConsumer; - } - - void Complete() - { - MOZ_RELEASE_ASSERT(Exists()); - mConsumer = nullptr; - } - - // Disconnects and forgets an outstanding promise. The resolve/reject methods - // will never be called. - void Disconnect() { - MOZ_ASSERT(Exists()); - mConsumer->Disconnect(); - mConsumer = nullptr; - } - - void DisconnectIfExists() { - if (Exists()) { - Disconnect(); - } - } - - bool Exists() { return !!mConsumer; } - -private: - nsRefPtr mConsumer; -}; - #undef PROMISE_LOG } // namespace mozilla diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index 22cacebc5b6..fb889b581a3 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -50,7 +50,9 @@ MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder) , mLastVideoTime(0) , mPendingSeekTime(-1) , mWaitingForSeekData(false) - , mTimeThreshold(0) + , mAudioIsSeeking(false) + , mVideoIsSeeking(false) + , mTimeThreshold(-1) , mDropAudioBeforeThreshold(false) , mDropVideoBeforeThreshold(false) , mEnded(false) @@ -117,20 +119,18 @@ MediaSourceReader::RequestAudioData() mAudioPromise.Reject(DECODE_ERROR, __func__); return p; } - if (IsSeeking()) { + if (mAudioIsSeeking) { MSE_DEBUG("MediaSourceReader(%p)::RequestAudioData called mid-seek. Rejecting.", this); mAudioPromise.Reject(CANCELED, __func__); return p; } - MOZ_RELEASE_ASSERT(!mSeekRequest.Exists()); - SwitchReaderResult ret = SwitchAudioReader(mLastAudioTime); switch (ret) { case READER_NEW: - mSeekRequest.Begin(mAudioReader->Seek(mLastAudioTime, 0) - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::CompleteSeekAndDoAudioRequest, - &MediaSourceReader::CompleteSeekAndRejectAudioPromise)); + mAudioReader->Seek(mLastAudioTime, 0) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::RequestAudioDataComplete, + &MediaSourceReader::RequestAudioDataFailed); break; case READER_ERROR: if (mLastAudioTime) { @@ -139,42 +139,49 @@ MediaSourceReader::RequestAudioData() } // Fallback to using current reader default: - DoAudioRequest(); + RequestAudioDataComplete(0); break; } return p; } -void MediaSourceReader::DoAudioRequest() +void +MediaSourceReader::RequestAudioDataComplete(int64_t aTime) { - mAudioRequest.Begin(mAudioReader->RequestAudioData() - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::OnAudioDecoded, - &MediaSourceReader::OnAudioNotDecoded)); + mAudioReader->RequestAudioData()->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::OnAudioDecoded, + &MediaSourceReader::OnAudioNotDecoded); +} + +void +MediaSourceReader::RequestAudioDataFailed(nsresult aResult) +{ + OnAudioNotDecoded(DECODE_ERROR); } void MediaSourceReader::OnAudioDecoded(AudioData* aSample) { - MOZ_RELEASE_ASSERT(!IsSeeking()); - mAudioRequest.Complete(); - MSE_DEBUGV("MediaSourceReader(%p)::OnAudioDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]", this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity); if (mDropAudioBeforeThreshold) { if (aSample->mTime < mTimeThreshold) { MSE_DEBUG("MediaSourceReader(%p)::OnAudioDecoded mTime=%lld < mTimeThreshold=%lld", this, aSample->mTime, mTimeThreshold); - mAudioRequest.Begin(mAudioReader->RequestAudioData() - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::OnAudioDecoded, - &MediaSourceReader::OnAudioNotDecoded)); + mAudioReader->RequestAudioData()->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::OnAudioDecoded, + &MediaSourceReader::OnAudioNotDecoded); return; } mDropAudioBeforeThreshold = false; } - mLastAudioTime = aSample->mTime + aSample->mDuration; + // Any OnAudioDecoded callbacks received while mAudioIsSeeking must be not + // update our last used timestamp, as these are emitted by the reader we're + // switching away from. + if (!mAudioIsSeeking) { + mLastAudioTime = aSample->mTime + aSample->mDuration; + } mAudioPromise.Resolve(aSample, __func__); } @@ -208,9 +215,6 @@ AdjustEndTime(int64_t* aEndTime, MediaDecoderReader* aReader) void MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason) { - MOZ_RELEASE_ASSERT(!IsSeeking()); - mAudioRequest.Complete(); - MSE_DEBUG("MediaSourceReader(%p)::OnAudioNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded()); if (aReason == DECODE_ERROR || aReason == CANCELED) { mAudioPromise.Reject(aReason, __func__); @@ -228,10 +232,10 @@ MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason) // EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug // 1065207. if (SwitchAudioReader(mLastAudioTime, EOS_FUZZ_US) == READER_NEW) { - mSeekRequest.Begin(mAudioReader->Seek(mLastAudioTime, 0) - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::CompleteSeekAndDoAudioRequest, - &MediaSourceReader::CompleteSeekAndRejectAudioPromise)); + mAudioReader->Seek(mLastAudioTime, 0) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::RequestAudioDataComplete, + &MediaSourceReader::RequestAudioDataFailed); return; } @@ -255,20 +259,18 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres mDropAudioBeforeThreshold = true; mDropVideoBeforeThreshold = true; } - if (IsSeeking()) { + if (mVideoIsSeeking) { MSE_DEBUG("MediaSourceReader(%p)::RequestVideoData called mid-seek. Rejecting.", this); mVideoPromise.Reject(CANCELED, __func__); return p; } - MOZ_RELEASE_ASSERT(!mSeekRequest.Exists()); - SwitchReaderResult ret = SwitchVideoReader(mLastVideoTime); switch (ret) { case READER_NEW: - mSeekRequest.Begin(mVideoReader->Seek(mLastVideoTime, 0) - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::CompleteSeekAndDoVideoRequest, - &MediaSourceReader::CompleteSeekAndRejectVideoPromise)); + mVideoReader->Seek(mLastVideoTime, 0) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::RequestVideoDataComplete, + &MediaSourceReader::RequestVideoDataFailed); break; case READER_ERROR: if (mLastVideoTime) { @@ -277,7 +279,9 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres } // Fallback to using current reader. default: - DoVideoRequest(); + mVideoReader->RequestVideoData(aSkipToNextKeyframe, aTimeThreshold) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::OnVideoDecoded, &MediaSourceReader::OnVideoNotDecoded); break; } @@ -285,34 +289,42 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres } void -MediaSourceReader::DoVideoRequest() +MediaSourceReader::RequestVideoDataComplete(int64_t aTime) { - mVideoRequest.Begin(mVideoReader->RequestVideoData(mDropVideoBeforeThreshold, mTimeThreshold) - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::OnVideoDecoded, - &MediaSourceReader::OnVideoNotDecoded)); + mVideoReader->RequestVideoData(false, 0) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::OnVideoDecoded, &MediaSourceReader::OnVideoNotDecoded); +} + +void +MediaSourceReader::RequestVideoDataFailed(nsresult aResult) +{ + OnVideoNotDecoded(DECODE_ERROR); } void MediaSourceReader::OnVideoDecoded(VideoData* aSample) { - MOZ_RELEASE_ASSERT(!IsSeeking()); - mVideoRequest.Complete(); - MSE_DEBUGV("MediaSourceReader(%p)::OnVideoDecoded [mTime=%lld mDuration=%lld mDiscontinuity=%d]", this, aSample->mTime, aSample->mDuration, aSample->mDiscontinuity); if (mDropVideoBeforeThreshold) { if (aSample->mTime < mTimeThreshold) { MSE_DEBUG("MediaSourceReader(%p)::OnVideoDecoded mTime=%lld < mTimeThreshold=%lld", this, aSample->mTime, mTimeThreshold); - DoVideoRequest(); + mVideoReader->RequestVideoData(false, 0)->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::OnVideoDecoded, + &MediaSourceReader::OnVideoNotDecoded); return; } mDropVideoBeforeThreshold = false; - mTimeThreshold = 0; } - mLastVideoTime = aSample->mTime + aSample->mDuration; + // Any OnVideoDecoded callbacks received while mVideoIsSeeking must be not + // update our last used timestamp, as these are emitted by the reader we're + // switching away from. + if (!mVideoIsSeeking) { + mLastVideoTime = aSample->mTime + aSample->mDuration; + } mVideoPromise.Resolve(aSample, __func__); } @@ -320,9 +332,6 @@ MediaSourceReader::OnVideoDecoded(VideoData* aSample) void MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason) { - MOZ_RELEASE_ASSERT(!IsSeeking()); - mVideoRequest.Complete(); - MSE_DEBUG("MediaSourceReader(%p)::OnVideoNotDecoded aReason=%u IsEnded: %d", this, aReason, IsEnded()); if (aReason == DECODE_ERROR || aReason == CANCELED) { mVideoPromise.Reject(aReason, __func__); @@ -340,10 +349,10 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason) // EOS_FUZZ_US to allow for the fact that our end time can be inaccurate due to bug // 1065207. if (SwitchVideoReader(mLastVideoTime, EOS_FUZZ_US) == READER_NEW) { - mSeekRequest.Begin(mVideoReader->Seek(mLastVideoTime, 0) - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::CompleteSeekAndDoVideoRequest, - &MediaSourceReader::CompleteSeekAndRejectVideoPromise)); + mVideoReader->Seek(mLastVideoTime, 0) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::RequestVideoDataComplete, + &MediaSourceReader::RequestVideoDataFailed); return; } @@ -661,19 +670,6 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aIgnored /* Used only for ogg whi return p; } - // Any previous requests we've been waiting on are now unwanted. - mAudioRequest.DisconnectIfExists(); - mVideoRequest.DisconnectIfExists(); - - // Additionally, reject any outstanding promises _we_ made that we might have - // been waiting on the above to fulfill. - mAudioPromise.RejectIfExists(CANCELED, __func__); - mVideoPromise.RejectIfExists(CANCELED, __func__); - - // Finally, if we were midway seeking a new reader to find a sample, abandon - // that too. - mSeekRequest.DisconnectIfExists(); - // Store pending seek target in case the track buffers don't contain // the desired time and we delay doing the seek. mPendingSeekTime = aTime; @@ -692,55 +688,69 @@ MediaSourceReader::CancelSeek() { MOZ_ASSERT(OnDecodeThread()); ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); - mWaitingForSeekData = false; - mPendingSeekTime = -1; - mSeekRequest.DisconnectIfExists(); - if (mAudioReader) { - mAudioReader->CancelSeek(); - } - if (mVideoReader) { + if (mWaitingForSeekData) { + mSeekPromise.Reject(NS_OK, __func__); + mWaitingForSeekData = false; + mPendingSeekTime = -1; + } else if (mVideoIsSeeking) { + // NB: Currently all readers have sync Seeks(), so this is a no-op. mVideoReader->CancelSeek(); + } else if (mAudioIsSeeking) { + // NB: Currently all readers have sync Seeks(), so this is a no-op. + mAudioReader->CancelSeek(); + } else { + MOZ_ASSERT(mSeekPromise.IsEmpty()); } - mSeekPromise.RejectIfExists(NS_OK, __func__); } void MediaSourceReader::OnVideoSeekCompleted(int64_t aTime) { - mSeekRequest.Complete(); + mPendingSeekTime = aTime; + MOZ_ASSERT(mVideoIsSeeking); + MOZ_ASSERT(!mAudioIsSeeking); + mVideoIsSeeking = false; if (mAudioTrack) { - mPendingSeekTime = aTime; - DoAudioSeek(); - } else { - mPendingSeekTime = -1; - mSeekPromise.Resolve(aTime, __func__); - } -} - -void -MediaSourceReader::DoAudioSeek() -{ + mAudioIsSeeking = true; SwitchAudioReader(mPendingSeekTime); - mSeekRequest.Begin(mAudioReader->Seek(mPendingSeekTime, 0) - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::OnAudioSeekCompleted, - &MediaSourceReader::OnSeekFailed)); - MSE_DEBUG("MediaSourceReader(%p)::DoAudioSeek reader=%p", this, mAudioReader.get()); + mAudioReader->Seek(mPendingSeekTime, 0) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::OnAudioSeekCompleted, + &MediaSourceReader::OnSeekFailed); + MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p", this, mAudioReader.get()); + return; + } + mSeekPromise.Resolve(mPendingSeekTime, __func__); } void MediaSourceReader::OnAudioSeekCompleted(int64_t aTime) { - mSeekRequest.Complete(); + mPendingSeekTime = aTime; + MOZ_ASSERT(mAudioIsSeeking); + MOZ_ASSERT(!mVideoIsSeeking); + mAudioIsSeeking = false; + + mSeekPromise.Resolve(mPendingSeekTime, __func__); mPendingSeekTime = -1; - mSeekPromise.Resolve(aTime, __func__); } void MediaSourceReader::OnSeekFailed(nsresult aResult) { - mSeekRequest.Complete(); + MOZ_ASSERT(mVideoIsSeeking || mAudioIsSeeking); + + if (mVideoIsSeeking) { + MOZ_ASSERT(!mAudioIsSeeking); + mVideoIsSeeking = false; + } + + if (mAudioIsSeeking) { + MOZ_ASSERT(!mVideoIsSeeking); + mAudioIsSeeking = false; + } + mPendingSeekTime = -1; mSeekPromise.Reject(aResult, __func__); } @@ -768,25 +778,18 @@ MediaSourceReader::AttemptSeek() mLastVideoTime = mPendingSeekTime; if (mVideoTrack) { - DoVideoSeek(); - } else if (mAudioTrack) { - DoAudioSeek(); + mVideoIsSeeking = true; + SwitchVideoReader(mPendingSeekTime); + mVideoReader->Seek(mPendingSeekTime, 0) + ->Then(GetTaskQueue(), __func__, this, + &MediaSourceReader::OnVideoSeekCompleted, + &MediaSourceReader::OnSeekFailed); + MSE_DEBUG("MediaSourceReader(%p)::Seek video reader=%p", this, mVideoReader.get()); } else { - MOZ_CRASH(); + OnVideoSeekCompleted(mPendingSeekTime); } } -void -MediaSourceReader::DoVideoSeek() -{ - SwitchVideoReader(mPendingSeekTime); - mSeekRequest.Begin(mVideoReader->Seek(mPendingSeekTime, 0) - ->RefableThen(GetTaskQueue(), __func__, this, - &MediaSourceReader::OnVideoSeekCompleted, - &MediaSourceReader::OnSeekFailed)); - MSE_DEBUG("MediaSourceReader(%p)::DoVideoSeek reader=%p", this, mVideoReader.get()); -} - nsresult MediaSourceReader::GetBuffered(dom::TimeRanges* aBuffered) { @@ -841,11 +844,11 @@ MediaSourceReader::MaybeNotifyHaveData() { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); bool haveAudio = false, haveVideo = false; - if (!IsSeeking() && mAudioTrack && HaveData(mLastAudioTime, MediaData::AUDIO_DATA)) { + if (!mAudioIsSeeking && mAudioTrack && HaveData(mLastAudioTime, MediaData::AUDIO_DATA)) { haveAudio = true; WaitPromise(MediaData::AUDIO_DATA).ResolveIfExists(MediaData::AUDIO_DATA, __func__); } - if (!IsSeeking() && mVideoTrack && HaveData(mLastVideoTime, MediaData::VIDEO_DATA)) { + if (!mVideoIsSeeking && mVideoTrack && HaveData(mLastVideoTime, MediaData::VIDEO_DATA)) { haveVideo = true; WaitPromise(MediaData::VIDEO_DATA).ResolveIfExists(MediaData::VIDEO_DATA, __func__); } diff --git a/dom/media/mediasource/MediaSourceReader.h b/dom/media/mediasource/MediaSourceReader.h index 8087d1fbd1f..8d547af9194 100644 --- a/dom/media/mediasource/MediaSourceReader.h +++ b/dom/media/mediasource/MediaSourceReader.h @@ -61,8 +61,6 @@ public: void OnVideoDecoded(VideoData* aSample); void OnVideoNotDecoded(NotDecodedReason aReason); - void DoVideoSeek(); - void DoAudioSeek(); void OnVideoSeekCompleted(int64_t aTime); void OnAudioSeekCompleted(int64_t aTime); void OnSeekFailed(nsresult aResult); @@ -159,34 +157,10 @@ private: }; SwitchReaderResult SwitchAudioReader(int64_t aTarget, int64_t aError = 0); SwitchReaderResult SwitchVideoReader(int64_t aTarget, int64_t aError = 0); - - void DoAudioRequest(); - void DoVideoRequest(); - - void CompleteSeekAndDoAudioRequest() - { - mSeekRequest.Complete(); - DoAudioRequest(); - } - - void CompleteSeekAndDoVideoRequest() - { - mSeekRequest.Complete(); - DoVideoRequest(); - } - - void CompleteSeekAndRejectAudioPromise() - { - mSeekRequest.Complete(); - mAudioPromise.Reject(DECODE_ERROR, __func__); - } - - void CompleteSeekAndRejectVideoPromise() - { - mSeekRequest.Complete(); - mVideoPromise.Reject(DECODE_ERROR, __func__); - } - + void RequestAudioDataComplete(int64_t aTime); + void RequestAudioDataFailed(nsresult aResult); + void RequestVideoDataComplete(int64_t aTime); + void RequestVideoDataFailed(nsresult aResult); // Will reject the MediaPromise with END_OF_STREAM if mediasource has ended // or with WAIT_FOR_DATA otherwise. void CheckForWaitOrEndOfStream(MediaData::Type aType, int64_t aTime /* microseconds */); @@ -199,7 +173,6 @@ private: bool HaveData(int64_t aTarget, MediaData::Type aType); void AttemptSeek(); - bool IsSeeking() { return mPendingSeekTime != -1; } nsRefPtr mAudioReader; nsRefPtr mVideoReader; @@ -210,9 +183,6 @@ private: nsRefPtr mAudioTrack; nsRefPtr mVideoTrack; - MediaPromiseConsumerHolder mAudioRequest; - MediaPromiseConsumerHolder mVideoRequest; - MediaPromiseHolder mAudioPromise; MediaPromiseHolder mVideoPromise; @@ -231,13 +201,13 @@ private: int64_t mLastAudioTime; int64_t mLastVideoTime; - MediaPromiseConsumerHolder mSeekRequest; - MediaPromiseHolder mSeekPromise; - // Temporary seek information while we wait for the data // to be added to the track buffer. + MediaPromiseHolder mSeekPromise; int64_t mPendingSeekTime; bool mWaitingForSeekData; + bool mAudioIsSeeking; + bool mVideoIsSeeking; int64_t mTimeThreshold; bool mDropAudioBeforeThreshold;