diff --git a/dom/media/mediasource/MediaSourceDecoder.cpp b/dom/media/mediasource/MediaSourceDecoder.cpp index c35b1f35e74..09f8520a731 100644 --- a/dom/media/mediasource/MediaSourceDecoder.cpp +++ b/dom/media/mediasource/MediaSourceDecoder.cpp @@ -240,6 +240,9 @@ MediaSourceDecoder::DoSetMediaSourceDuration(double aDuration) mDecoderStateMachine->SetDuration(INT64_MAX); mMediaSourceDuration = PositiveInfinity(); } + if (mReader) { + mReader->SetMediaSourceDuration(mMediaSourceDuration); + } } void diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index 5b56f84f610..7effd07174b 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -56,6 +56,7 @@ MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder) , mDropAudioBeforeThreshold(false) , mDropVideoBeforeThreshold(false) , mEnded(false) + , mMediaSourceDuration(0) , mHasEssentialTrackBuffers(false) #ifdef MOZ_FMP4 , mSharedDecoderManager(new SharedDecoderManager()) @@ -133,7 +134,7 @@ MediaSourceReader::RequestAudioData() break; case READER_ERROR: if (mLastAudioTime) { - CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA); + CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime); break; } // Fallback to using current reader @@ -238,7 +239,7 @@ MediaSourceReader::OnAudioNotDecoded(NotDecodedReason aReason) return; } - CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA); + CheckForWaitOrEndOfStream(MediaData::AUDIO_DATA, mLastAudioTime); } @@ -273,7 +274,7 @@ MediaSourceReader::RequestVideoData(bool aSkipToNextKeyframe, int64_t aTimeThres break; case READER_ERROR: if (mLastVideoTime) { - CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA); + CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA, mLastVideoTime); break; } // Fallback to using current reader. @@ -355,14 +356,14 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason) return; } - CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA); + CheckForWaitOrEndOfStream(MediaData::VIDEO_DATA, mLastVideoTime); } void -MediaSourceReader::CheckForWaitOrEndOfStream(MediaData::Type aType) +MediaSourceReader::CheckForWaitOrEndOfStream(MediaData::Type aType, int64_t aTime) { // If the entire MediaSource is done, generate an EndOfStream. - if (IsEnded()) { + if (IsNearEnd(aTime)) { if (aType == MediaData::AUDIO_DATA) { mAudioPromise.Reject(END_OF_STREAM, __func__); } else { @@ -946,6 +947,20 @@ MediaSourceReader::IsEnded() return mEnded; } +bool +MediaSourceReader::IsNearEnd(int64_t aTime) +{ + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); + return mEnded && aTime >= (mMediaSourceDuration * USECS_PER_S - EOS_FUZZ_US); +} + +void +MediaSourceReader::SetMediaSourceDuration(double aDuration) +{ + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); + mMediaSourceDuration = aDuration; +} + #ifdef MOZ_EME nsresult MediaSourceReader::SetCDMProxy(CDMProxy* aProxy) diff --git a/dom/media/mediasource/MediaSourceReader.h b/dom/media/mediasource/MediaSourceReader.h index 5d6322d6438..8d547af9194 100644 --- a/dom/media/mediasource/MediaSourceReader.h +++ b/dom/media/mediasource/MediaSourceReader.h @@ -129,6 +129,10 @@ public: // Return true if the Ended method has been called bool IsEnded(); + bool IsNearEnd(int64_t aTime /* microseconds */); + + // Set the duration of the attached mediasource element. + void SetMediaSourceDuration(double aDuration /* seconds */); #ifdef MOZ_EME nsresult SetCDMProxy(CDMProxy* aProxy); @@ -159,7 +163,7 @@ private: 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); + void CheckForWaitOrEndOfStream(MediaData::Type aType, int64_t aTime /* microseconds */); // Return a reader from the set available in aTrackDecoders that has data // available in the range requested by aTarget. @@ -210,6 +214,7 @@ private: bool mDropVideoBeforeThreshold; bool mEnded; + double mMediaSourceDuration; bool mHasEssentialTrackBuffers;