Bug 1313635 part 1 - don't go through MediaDecoderReaderWrapper to set start time; r=jwwang,jya
authorKaku Kuo <kaku@mozilla.com>
Fri, 25 Nov 2016 16:47:02 +0800
changeset 324610 0459bc465abc1a9acdb5906b1eb3d57cc8ba685e
parent 324609 6c23e6d1cd60cb911ecd7673276a65e9b9505f54
child 324611 965fded52ad68fb6faccbf39653b97d1b8e0e649
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersjwwang, jya
bugs1313635
milestone53.0a1
Bug 1313635 part 1 - don't go through MediaDecoderReaderWrapper to set start time; r=jwwang,jya MozReview-Commit-ID: KXz1veb7x1i
dom/media/MediaDecoderReader.cpp
dom/media/MediaDecoderReader.h
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
--- 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