Bug 1163223 - Use AwaitStartTime to handle metadata end time. r=jww
☠☠ backed out by 3fe20c75349b ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Sat, 06 Jun 2015 14:48:07 -0700
changeset 249173 20e25e93ed5f
parent 249172 5193508738f8
child 249174 9e7651567cad
push id61158
push userbobbyholley@gmail.com
push date2015-06-16 20:00 +0000
treeherdermozilla-inbound@c1b33c43f0c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjww
bugs1163223
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1163223 - Use AwaitStartTime to handle metadata end time. r=jww
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaInfo.h
dom/media/ogg/OggReader.cpp
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -1418,18 +1418,16 @@ void MediaDecoderStateMachine::Recompute
     // We don't fire duration changed for this case because it should have
     // already been fired on the main thread when the explicit duration was set.
     duration = TimeUnit::FromSeconds(d);
   } else if (mEstimatedDuration.Ref().isSome()) {
     duration = mEstimatedDuration.Ref().ref();
     fireDurationChanged = true;
   } else if (mInfo.mMetadataDuration.isSome()) {
     duration = mInfo.mMetadataDuration.ref();
-  } else if (mInfo.mMetadataEndTime.isSome() && mStartTime >= 0) {
-    duration = mInfo.mMetadataEndTime.ref() - TimeUnit::FromMicroseconds(mStartTime);
   } else {
     return;
   }
 
   if (duration < mObservedDuration.Ref()) {
     duration = mObservedDuration;
     fireDurationChanged = true;
   }
@@ -2167,26 +2165,37 @@ MediaDecoderStateMachine::OnMetadataRead
   MOZ_ASSERT(OnTaskQueue());
   MOZ_ASSERT(mState == DECODER_STATE_DECODING_METADATA);
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   mMetadataRequest.Complete();
 
   mDecoder->SetMediaSeekable(mReader->IsMediaSeekable());
   mInfo = aMetadata->mInfo;
   mMetadataTags = aMetadata->mTags.forget();
+  nsRefPtr<MediaDecoderStateMachine> self = this;
 
   // Set up the start time rendezvous if it doesn't already exist (which is
   // generally the case, unless we're coming out of dormant mode).
   if (!mStartTimeRendezvous) {
     mStartTimeRendezvous = new StartTimeRendezvous(TaskQueue(), HasAudio(), HasVideo(),
                                                    mReader->ForceZeroStartTime() || IsRealTime());
   }
 
-  if (mInfo.mMetadataDuration.isSome() || mInfo.mMetadataEndTime.isSome()) {
+  if (mInfo.mMetadataDuration.isSome()) {
     RecomputeDuration();
+  } else if (mInfo.mUnadjustedMetadataEndTime.isSome()) {
+    mStartTimeRendezvous->AwaitStartTime()->Then(TaskQueue(), __func__,
+      [self] () -> void {
+        NS_ENSURE_TRUE_VOID(!self->IsShutdown());
+        TimeUnit unadjusted = self->mInfo.mUnadjustedMetadataEndTime.ref();
+        TimeUnit adjustment = TimeUnit::FromMicroseconds(self->StartTime());
+        self->mInfo.mMetadataDuration.emplace(unadjusted - adjustment);
+        self->RecomputeDuration();
+      }, [] () -> void { NS_WARNING("Adjusting metadata end time failed"); }
+    );
   }
 
   if (HasVideo()) {
     DECODER_LOG("Video decode isAsync=%d HWAccel=%d videoQueueSize=%d",
                 mReader->IsAsync(),
                 mReader->VideoIsHardwareAccelerated(),
                 GetAmpleVideoFrames());
   }
@@ -3172,18 +3181,16 @@ void MediaDecoderStateMachine::SetStartT
   mReader->SetStartTime(mStartTime);
 
   // Set the audio start time to be start of media. If this lies before the
   // first actual audio frame we have, we'll inject silence during playback
   // to ensure the audio starts at the correct time.
   mAudioStartTime = mStartTime;
   mStreamStartTime = mStartTime;
   DECODER_LOG("Set media start time to %lld", mStartTime);
-
-  RecomputeDuration();
 }
 
 void MediaDecoderStateMachine::UpdateNextFrameStatus()
 {
   MOZ_ASSERT(OnTaskQueue());
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   MediaDecoderOwner::NextFrameStatus status;
@@ -3365,17 +3372,16 @@ void MediaDecoderStateMachine::Preserves
 
   if (mAudioSink) {
     mAudioSink->SetPreservesPitch(mPreservesPitch);
   }
 }
 
 bool MediaDecoderStateMachine::IsShutdown()
 {
-  AssertCurrentThreadInMonitor();
   return mState == DECODER_STATE_ERROR ||
          mState == DECODER_STATE_SHUTDOWN;
 }
 
 void MediaDecoderStateMachine::QueueMetadata(int64_t aPublishTime,
                                              nsAutoPtr<MediaInfo> aInfo,
                                              nsAutoPtr<MetadataTags> aTags)
 {
--- a/dom/media/MediaInfo.h
+++ b/dom/media/MediaInfo.h
@@ -350,16 +350,16 @@ public:
   AudioInfo mAudio;
 
   // If the metadata includes a duration, we store it here.
   media::NullableTimeUnit mMetadataDuration;
 
   // The Ogg reader tries to kinda-sorta compute the duration by seeking to the
   // end and determining the timestamp of the last frame. This isn't useful as
   // a duration until we know the start time, so we need to track it separately.
-  media::NullableTimeUnit mMetadataEndTime;
+  media::NullableTimeUnit mUnadjustedMetadataEndTime;
 
   EncryptionInfo mCrypto;
 };
 
 } // namespace mozilla
 
 #endif // MediaInfo_h
--- a/dom/media/ogg/OggReader.cpp
+++ b/dom/media/ogg/OggReader.cpp
@@ -484,17 +484,17 @@ nsresult OggReader::ReadMetadata(MediaIn
       NS_ASSERTION(length > 0, "Must have a content length to get end time");
 
       int64_t endTime = 0;
       {
         ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
         endTime = RangeEndTime(length);
       }
       if (endTime != -1) {
-        mInfo.mMetadataEndTime.emplace(TimeUnit::FromMicroseconds(endTime));
+        mInfo.mUnadjustedMetadataEndTime.emplace(TimeUnit::FromMicroseconds(endTime));
         LOG(LogLevel::Debug, ("Got Ogg duration from seeking to end %lld", endTime));
       }
     }
   } else {
     return NS_ERROR_FAILURE;
   }
   *aInfo = mInfo;