diff --git a/dom/media/MediaDecoder.h b/dom/media/MediaDecoder.h index b99a077ebf26..db6f3721f1d1 100644 --- a/dom/media/MediaDecoder.h +++ b/dom/media/MediaDecoder.h @@ -577,7 +577,7 @@ private: // Returns true if we can play the entire media through without stopping // to buffer, given the current download and playback rates. - bool CanPlayThrough(); + virtual bool CanPlayThrough(); void SetAudioChannel(dom::AudioChannel aChannel) { mAudioChannel = aChannel; } dom::AudioChannel GetAudioChannel() { return mAudioChannel; } diff --git a/dom/media/mediasource/MediaSourceDecoder.cpp b/dom/media/mediasource/MediaSourceDecoder.cpp index d57c9bff5eb3..67a4ac41533b 100644 --- a/dom/media/mediasource/MediaSourceDecoder.cpp +++ b/dom/media/mediasource/MediaSourceDecoder.cpp @@ -16,6 +16,7 @@ #include "MediaFormatReader.h" #include "MediaSourceDemuxer.h" #include "SourceBufferList.h" +#include extern mozilla::LogModule* GetMediaSourceLog(); @@ -265,6 +266,32 @@ MediaSourceDecoder::NextFrameBufferedStatus() : MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE; } +bool +MediaSourceDecoder::CanPlayThrough() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (IsNaN(mMediaSource->Duration())) { + // Don't have any data yet. + return false; + } + TimeUnit duration = TimeUnit::FromSeconds(mMediaSource->Duration()); + TimeUnit currentPosition = TimeUnit::FromMicroseconds(CurrentPosition()); + if (duration.IsInfinite()) { + // We can't make an informed decision and just assume that it's a live stream + return true; + } else if (duration <= currentPosition) { + return true; + } + // If we have data up to the mediasource's duration or 30s ahead, we can + // assume that we can play without interruption. + TimeUnit timeAhead = + std::min(duration, currentPosition + TimeUnit::FromSeconds(30)); + TimeInterval interval(currentPosition, + timeAhead, + MediaSourceDemuxer::EOS_FUZZ); + return GetBuffered().Contains(interval); +} + #undef MSE_DEBUG #undef MSE_DEBUGV diff --git a/dom/media/mediasource/MediaSourceDecoder.h b/dom/media/mediasource/MediaSourceDecoder.h index 3235c682bb37..3e66dab2f191 100644 --- a/dom/media/mediasource/MediaSourceDecoder.h +++ b/dom/media/mediasource/MediaSourceDecoder.h @@ -78,6 +78,7 @@ public: void AddSizeOfResources(ResourceSizes* aSizes) override; MediaDecoderOwner::NextFrameStatus NextFrameBufferedStatus() override; + bool CanPlayThrough() override; private: void DoSetMediaSourceDuration(double aDuration);