Bug 1313635 part 1 - don't go through MediaDecoderReaderWrapper to set start time; r?jya, jwwang
MozReview-Commit-ID: KXz1veb7x1i
--- a/dom/media/MediaDecoderReader.cpp
+++ b/dom/media/MediaDecoderReader.cpp
@@ -189,19 +189,17 @@ MediaDecoderReader::UpdateBuffered()
void
MediaDecoderReader::VisibilityChanged()
{}
media::TimeIntervals
MediaDecoderReader::GetBuffered()
{
MOZ_ASSERT(OnTaskQueue());
- if (!HaveStartTime()) {
- return media::TimeIntervals();
- }
+
AutoPinned<MediaResource> stream(mDecoder->GetResource());
if (!mDuration.Ref().isSome()) {
return TimeIntervals();
}
return GetEstimatedBufferedTimeRanges(stream, mDuration.Ref().ref().ToMicroseconds());
}
@@ -212,16 +210,19 @@ MediaDecoderReader::AsyncReadMetadata()
MOZ_ASSERT(OnTaskQueue());
DECODER_LOG("MediaDecoderReader::AsyncReadMetadata");
// Attempt to read the metadata.
RefPtr<MetadataHolder> metadata = new MetadataHolder();
nsresult rv = ReadMetadata(&metadata->mInfo, getter_Transfers(metadata->mTags));
metadata->mInfo.AssertValid();
+ // Update the buffer ranges before resolving the metadata promise. Bug 1320258.
+ UpdateBuffered();
+
// We're not waiting for anything. If we didn't get the metadata, that's an
// error.
if (NS_FAILED(rv) || !metadata->mInfo.HasValidMedia()) {
DECODER_WARN("ReadMetadata failed, rv=%x HasValidMedia=%d", rv, metadata->mInfo.HasValidMedia());
return MetadataPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_METADATA_ERR, __func__);
}
// Success!
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -272,16 +272,19 @@ public:
// Switch the video decoder to BlankDecoderModule. It might takes effective
// since a few samples later depends on how much demuxed samples are already
// queued in the original video decoder.
virtual void SetVideoBlankDecode(bool aIsBlankDecode) {}
protected:
virtual ~MediaDecoderReader();
+ // Recomputes mBuffered.
+ virtual void UpdateBuffered();
+
// Populates aBuffered with the time ranges which are buffered. This may only
// be called on the decode task queue, and should only be used internally by
// UpdateBuffered - mBuffered (or mirrors of it) should be used for everything
// else.
//
// This base implementation in MediaDecoderReader estimates the time ranges
// buffered by interpolating the cached byte ranges with the duration
// of the media. Reader subclasses should override this method if they
@@ -378,19 +381,16 @@ private:
// the data required to present the media, and optionally fills *aTags
// with tag metadata from the file.
// Returns NS_OK on success, or NS_ERROR_FAILURE on failure.
virtual nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
{
MOZ_CRASH();
}
- // Recomputes mBuffered.
- virtual void UpdateBuffered();
-
virtual void VisibilityChanged();
virtual void NotifyDataArrivedInternal() {}
// Overrides of this function should decodes an unspecified amount of
// audio data, enqueuing the audio data in mAudioQueue. Returns true
// when there's more audio to decode, false if the audio is finished,
// end of file has been reached, or an un-recoverable read error has
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -785,16 +785,19 @@ MediaFormatReader::MaybeResolveMetadataP
TimeUnit startTime =
std::min(mAudio.mFirstDemuxedSampleTime.refOr(TimeUnit::FromInfinity()),
mVideo.mFirstDemuxedSampleTime.refOr(TimeUnit::FromInfinity()));
if (!startTime.IsInfinite()) {
mInfo.mStartTime = startTime; // mInfo.mStartTime is initialized to 0.
}
+ mHasStartTime = true;
+ UpdateBuffered();
+
RefPtr<MetadataHolder> metadata = new MetadataHolder();
metadata->mInfo = mInfo;
metadata->mTags = mTags->Count() ? mTags.release() : nullptr;
mMetadataPromise.Resolve(metadata, __func__);
}
bool
MediaFormatReader::IsEncrypted() const
@@ -2172,26 +2175,20 @@ MediaFormatReader::OnAudioSeekFailed(con
media::TimeIntervals
MediaFormatReader::GetBuffered()
{
MOZ_ASSERT(OnTaskQueue());
media::TimeIntervals videoti;
media::TimeIntervals audioti;
media::TimeIntervals intervals;
- if (!mInitDone) {
+ if (!mInitDone || !mHasStartTime) {
return intervals;
}
- int64_t startTime = 0;
- if (!ForceZeroStartTime()) {
- if (!HaveStartTime()) {
- return intervals;
- }
- startTime = StartTime();
- }
+
// Ensure we have up to date buffered time range.
if (HasVideo()) {
UpdateReceivedNewData(TrackType::kVideoTrack);
}
if (HasAudio()) {
UpdateReceivedNewData(TrackType::kAudioTrack);
}
if (HasVideo()) {
@@ -2208,17 +2205,17 @@ MediaFormatReader::GetBuffered()
intervals = Move(videoti);
}
if (!intervals.Length() ||
intervals.GetStart() == media::TimeUnit::FromMicroseconds(0)) {
// IntervalSet already starts at 0 or is empty, nothing to shift.
return intervals;
}
- return intervals.Shift(media::TimeUnit::FromMicroseconds(-startTime));
+ return intervals.Shift(media::TimeUnit() - mInfo.mStartTime);
}
// For the MediaFormatReader override we need to force an update to the
// buffered ranges, so we call NotifyDataArrive
RefPtr<MediaDecoderReader::BufferedUpdatePromise>
MediaFormatReader::UpdateBufferedWithPromise() {
MOZ_ASSERT(OnTaskQueue());
// Call NotifyDataArrive to force a recalculation of the buffered
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -581,13 +581,16 @@ private:
void OnFirstDemuxCompleted(TrackInfo::TrackType aType,
RefPtr<MediaTrackDemuxer::SamplesHolder> aSamples);
void OnFirstDemuxFailed(TrackInfo::TrackType aType, const MediaResult& aError);
void MaybeResolveMetadataPromise();
UniquePtr<MetadataTags> mTags;
+
+ // A flag indicating if the start time is known or not.
+ bool mHasStartTime = false;
};
} // namespace mozilla
#endif