Back out 4 changesets (bug 1229987) for ASan e10s timeout in test_playback.html, Mac timeouts in test_BufferingWait_mp4.html, and Win8 failures in test_WaitingToEndedTransition_mp4.html
authorPhil Ringnalda <philringnalda@gmail.com>
Thu, 10 Dec 2015 23:10:20 -0800
changeset 276153 672a8b656e19
parent 276152 95608418cba5
child 276154 279f56c0f49e
child 276209 754b4805a65c
push id69062
push userphilringnalda@gmail.com
push dateFri, 11 Dec 2015 07:22:16 +0000
treeherdermozilla-inbound@672a8b656e19 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1229987
milestone45.0a1
backs out707a87454058
37003d495f20
c8f4e1eaf884
42ca05d8546d
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
Back out 4 changesets (bug 1229987) for ASan e10s timeout in test_playback.html, Mac timeouts in test_BufferingWait_mp4.html, and Win8 failures in test_WaitingToEndedTransition_mp4.html Backed out changeset 707a87454058 (bug 1229987) Backed out changeset 37003d495f20 (bug 1229987) Backed out changeset c8f4e1eaf884 (bug 1229987) Backed out changeset 42ca05d8546d (bug 1229987)
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
dom/media/mediasource/MediaSourceDemuxer.cpp
dom/media/mediasource/MediaSourceDemuxer.h
dom/media/mediasource/test/mochitest.ini
dom/media/mediasource/test/test_BufferingWait_mp4.html
dom/media/mediasource/test/test_DrainOnMissingData_mp4.html
dom/media/mediasource/test/test_PlayEvents.html
dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html
dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -778,27 +778,16 @@ MediaDecoderStateMachine::OnNotDecoded(M
              [self] (MediaData::Type aType) -> void {
                self->WaitRequestRef(aType).Complete();
                self->DispatchDecodeTasksIfNeeded();
              },
              [self] (WaitForDataRejectValue aRejection) -> void {
                self->WaitRequestRef(aRejection.mType).Complete();
              }));
 
-    // We are out of data to decode and will enter buffering mode soon.
-    // We want to play the frames we have already decoded, so we stop pre-rolling
-    // and ensure that loadeddata is fired as required.
-    if (isAudio) {
-      StopPrerollingAudio();
-    } else {
-      StopPrerollingVideo();
-    }
-    if (mState == DECODER_STATE_BUFFERING || mState == DECODER_STATE_DECODING) {
-        MaybeFinishDecodeFirstFrame();
-    }
     return;
   }
 
   if (aReason == MediaDecoderReader::CANCELED) {
     DispatchDecodeTasksIfNeeded();
     return;
   }
 
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -686,17 +686,16 @@ MediaFormatReader::NotifyError(TrackType
 }
 
 void
 MediaFormatReader::NotifyWaitingForData(TrackType aTrack)
 {
   MOZ_ASSERT(OnTaskQueue());
   auto& decoder = GetDecoderData(aTrack);
   decoder.mWaitingForData = true;
-  decoder.mNeedDraining = true;
   ScheduleUpdate(aTrack);
 }
 
 void
 MediaFormatReader::NotifyEndOfStream(TrackType aTrack)
 {
   MOZ_ASSERT(OnTaskQueue());
   auto& decoder = GetDecoderData(aTrack);
@@ -879,31 +878,57 @@ MediaFormatReader::HandleDemuxedSamples(
         return;
       }
 
       LOG("%s stream id has changed from:%d to:%d, recreating decoder.",
           TrackTypeToStr(aTrack), decoder.mLastStreamSourceID,
           info->GetID());
       decoder.mInfo = info;
       decoder.mLastStreamSourceID = info->GetID();
-      decoder.mNextStreamSourceID.reset();
       // Flush will clear our array of queued samples. So make a copy now.
       nsTArray<RefPtr<MediaRawData>> samples{decoder.mQueuedSamples};
       Flush(aTrack);
       decoder.mDecoder->Shutdown();
       decoder.mDecoder = nullptr;
       if (sample->mKeyframe) {
         decoder.mQueuedSamples.AppendElements(Move(samples));
         NotifyDecodingRequested(aTrack);
       } else {
-        TimeUnit seekTime =
-          decoder.mTimeThreshold.refOr(TimeUnit::FromMicroseconds(sample->mTime));
+        MOZ_ASSERT(decoder.mTimeThreshold.isNothing());
         LOG("Stream change occurred on a non-keyframe. Seeking to:%lld",
-            seekTime.ToMicroseconds());
-        InternalSeek(aTrack, seekTime);
+            sample->mTime);
+        decoder.mTimeThreshold = Some(TimeUnit::FromMicroseconds(sample->mTime));
+        RefPtr<MediaFormatReader> self = this;
+        decoder.ResetDemuxer();
+        decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref())
+                   ->Then(OwnerThread(), __func__,
+                          [self, aTrack] (media::TimeUnit aTime) {
+                            auto& decoder = self->GetDecoderData(aTrack);
+                            decoder.mSeekRequest.Complete();
+                            self->NotifyDecodingRequested(aTrack);
+                          },
+                          [self, aTrack] (DemuxerFailureReason aResult) {
+                            auto& decoder = self->GetDecoderData(aTrack);
+                            decoder.mSeekRequest.Complete();
+                            switch (aResult) {
+                              case DemuxerFailureReason::WAITING_FOR_DATA:
+                                self->NotifyWaitingForData(aTrack);
+                                break;
+                              case DemuxerFailureReason::END_OF_STREAM:
+                                self->NotifyEndOfStream(aTrack);
+                                break;
+                              case DemuxerFailureReason::CANCELED:
+                              case DemuxerFailureReason::SHUTDOWN:
+                                break;
+                              default:
+                                self->NotifyError(aTrack);
+                                break;
+                            }
+                            decoder.mTimeThreshold.reset();
+                          }));
       }
       return;
     }
 
     LOGV("Input:%lld (dts:%lld kf:%d)",
          sample->mTime, sample->mTimecode, sample->mKeyframe);
     decoder.mOutputRequested = true;
     decoder.mNumSamplesInput++;
@@ -928,52 +953,16 @@ MediaFormatReader::HandleDemuxedSamples(
     samplesPending = true;
   }
 
   // We have serviced the decoder's request for more data.
   decoder.mInputExhausted = false;
 }
 
 void
-MediaFormatReader::InternalSeek(TrackType aTrack, const media::TimeUnit& aTime)
-{
-  MOZ_ASSERT(OnTaskQueue());
-  auto& decoder = GetDecoderData(aTrack);
-  decoder.mTimeThreshold = Some(aTime);
-  RefPtr<MediaFormatReader> self = this;
-  decoder.ResetDemuxer();
-  decoder.mSeekRequest.Begin(decoder.mTrackDemuxer->Seek(decoder.mTimeThreshold.ref())
-             ->Then(OwnerThread(), __func__,
-                    [self, aTrack] (media::TimeUnit aTime) {
-                      auto& decoder = self->GetDecoderData(aTrack);
-                      decoder.mSeekRequest.Complete();
-                      self->NotifyDecodingRequested(aTrack);
-                    },
-                    [self, aTrack] (DemuxerFailureReason aResult) {
-                      auto& decoder = self->GetDecoderData(aTrack);
-                      decoder.mSeekRequest.Complete();
-                      switch (aResult) {
-                        case DemuxerFailureReason::WAITING_FOR_DATA:
-                          self->NotifyWaitingForData(aTrack);
-                          break;
-                        case DemuxerFailureReason::END_OF_STREAM:
-                          self->NotifyEndOfStream(aTrack);
-                          break;
-                        case DemuxerFailureReason::CANCELED:
-                        case DemuxerFailureReason::SHUTDOWN:
-                          break;
-                        default:
-                          self->NotifyError(aTrack);
-                          break;
-                      }
-                      decoder.mTimeThreshold.reset();
-                    }));
-}
-
-void
 MediaFormatReader::DrainDecoder(TrackType aTrack)
 {
   MOZ_ASSERT(OnTaskQueue());
 
   auto& decoder = GetDecoderData(aTrack);
   if (!decoder.mNeedDraining || decoder.mDraining) {
     return;
   }
@@ -1012,18 +1001,17 @@ MediaFormatReader::Update(TrackType aTra
     return;
   }
 
   if (UpdateReceivedNewData(aTrack)) {
     LOGV("Nothing more to do");
     return;
   }
 
-  if (!decoder.HasPromise() && decoder.mWaitingForData &&
-      !decoder.mDraining && !decoder.mNeedDraining) {
+  if (!decoder.HasPromise() && decoder.mWaitingForData) {
     // Nothing more we can do at present.
     LOGV("Still waiting for data.");
     return;
   }
 
   // Record number of frames decoded and parsed. Automatically update the
   // stats counters using the AutoNotifyDecoded stack-based class.
   AbstractMediaDecoder::AutoNotifyDecoded a(mDecoder);
@@ -1043,57 +1031,42 @@ MediaFormatReader::Update(TrackType aTra
         nsCString error;
         mVideo.mIsHardwareAccelerated =
           mVideo.mDecoder && mVideo.mDecoder->IsHardwareAccelerated(error);
       }
       while (decoder.mOutput.Length()) {
         RefPtr<MediaData> output = decoder.mOutput[0];
         decoder.mOutput.RemoveElementAt(0);
         decoder.mSizeOfQueue -= 1;
-        decoder.mLastSampleTime =
-          Some(media::TimeUnit::FromMicroseconds(output->GetEndTime()));
         if (decoder.mTimeThreshold.isNothing() ||
             media::TimeUnit::FromMicroseconds(output->mTime) >= decoder.mTimeThreshold.ref()) {
           ReturnOutput(output, aTrack);
           decoder.mTimeThreshold.reset();
           break;
         } else {
-          LOGV("Internal Seeking: Dropping %s frame time:%f wanted:%f (kf:%d)",
-               TrackTypeToStr(aTrack),
+          LOGV("Internal Seeking: Dropping frame time:%f wanted:%f (kf:%d)",
                media::TimeUnit::FromMicroseconds(output->mTime).ToSeconds(),
                decoder.mTimeThreshold.ref().ToSeconds(),
                output->mKeyframe);
         }
       }
-    }
-  }
-  if (decoder.HasPromise() && decoder.mOutput.IsEmpty()) {
-    if (decoder.mError) {
-      decoder.RejectPromise(DECODE_ERROR, __func__);
-      return;
-    }
-    if (decoder.mDrainComplete) {
-      bool wasDraining = decoder.mDraining;
+    } else if (decoder.mDrainComplete) {
       decoder.mDrainComplete = false;
       decoder.mDraining = false;
-      if (decoder.mDemuxEOS) {
+      if (decoder.mError) {
+        LOG("Decoding Error");
+        decoder.RejectPromise(DECODE_ERROR, __func__);
+        return;
+      } else if (decoder.mDemuxEOS) {
         decoder.RejectPromise(END_OF_STREAM, __func__);
-        // We reached the end of the data stream. Nothing more to do.
-        return;
       }
-      if (wasDraining && decoder.mLastSampleTime && !decoder.mNextStreamSourceID) {
-        // We have completed draining the decoder following WaitingForData.
-        // Set up the internal seek machinery to be able to resume from the
-        // last sample decoded.
-        LOG("Seeking to last sample time: %lld",
-            decoder.mLastSampleTime.ref().ToMicroseconds());
-        InternalSeek(aTrack, decoder.mLastSampleTime.ref());
-      }
-    }
-    if (decoder.mWaitingForData && !decoder.mDraining && !decoder.mNeedDraining) {
+    } else if (decoder.mError) {
+      decoder.RejectPromise(DECODE_ERROR, __func__);
+      return;
+    } else if (decoder.mWaitingForData) {
       LOG("Waiting For Data");
       decoder.RejectPromise(WAITING_FOR_DATA, __func__);
       return;
     }
   }
 
   if (decoder.mNeedDraining) {
     DrainDecoder(aTrack);
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -122,18 +122,16 @@ private:
   // Called when new samples need to be demuxed.
   void RequestDemuxSamples(TrackType aTrack);
   // Handle demuxed samples by the input behavior.
   void HandleDemuxedSamples(TrackType aTrack,
                             AbstractMediaDecoder::AutoNotifyDecoded& aA);
   // Decode any pending already demuxed samples.
   bool DecodeDemuxedSamples(TrackType aTrack,
                             MediaRawData* aSample);
-  void InternalSeek(TrackType aTrack, const media::TimeUnit& aTime);
-
   // Drain the current decoder.
   void DrainDecoder(TrackType aTrack);
   void NotifyNewOutput(TrackType aTrack, MediaData* aSample);
   void NotifyInputExhausted(TrackType aTrack);
   void NotifyDrainComplete(TrackType aTrack);
   void NotifyError(TrackType aTrack);
   void NotifyWaitingForData(TrackType aTrack);
   void NotifyEndOfStream(TrackType aTrack);
@@ -258,21 +256,18 @@ private:
     bool mDecodingRequested;
     bool mOutputRequested;
     bool mInputExhausted;
     bool mError;
     bool mNeedDraining;
     bool mDraining;
     bool mDrainComplete;
     // If set, all decoded samples prior mTimeThreshold will be dropped.
-    // Used for internal seeking when a change of stream is detected or when
-    // encountering data discontinuity.
+    // Used for internal seeking when a change of stream is detected.
     Maybe<media::TimeUnit> mTimeThreshold;
-    // End time of last sample output.
-    Maybe<media::TimeUnit> mLastSampleTime;
 
     // Decoded samples returned my mDecoder awaiting being returned to
     // state machine upon request.
     nsTArray<RefPtr<MediaData>> mOutput;
     uint64_t mNumSamplesInput;
     uint64_t mNumSamplesOutput;
     uint64_t mNumSamplesOutputTotal;
 
@@ -300,17 +295,16 @@ private:
       mQueuedSamples.Clear();
       mDecodingRequested = false;
       mOutputRequested = false;
       mInputExhausted = false;
       mNeedDraining = false;
       mDraining = false;
       mDrainComplete = false;
       mTimeThreshold.reset();
-      mLastSampleTime.reset();
       mOutput.Clear();
       mNumSamplesInput = 0;
       mNumSamplesOutput = 0;
       mSizeOfQueue = 0;
       mNextStreamSourceID.reset();
     }
 
     // Used by the MDSM for logging purposes.
--- a/dom/media/mediasource/MediaSourceDemuxer.cpp
+++ b/dom/media/mediasource/MediaSourceDemuxer.cpp
@@ -290,17 +290,17 @@ MediaSourceDemuxer::GetMozDebugReaderDat
 
 MediaSourceTrackDemuxer::MediaSourceTrackDemuxer(MediaSourceDemuxer* aParent,
                                                  TrackInfo::TrackType aType,
                                                  TrackBuffersManager* aManager)
   : mParent(aParent)
   , mManager(aManager)
   , mType(aType)
   , mMonitor("MediaSourceTrackDemuxer")
-  , mReset(true)
+  , mLastSeek(Some(TimeUnit()))
 {
 }
 
 UniquePtr<TrackInfo>
 MediaSourceTrackDemuxer::GetInfo() const
 {
   return mParent->GetTrackInfo(mType)->Clone();
 }
@@ -323,18 +323,17 @@ MediaSourceTrackDemuxer::GetSamples(int3
 
 void
 MediaSourceTrackDemuxer::Reset()
 {
   MOZ_ASSERT(mParent, "Called after BreackCycle()");
   RefPtr<MediaSourceTrackDemuxer> self = this;
   nsCOMPtr<nsIRunnable> task =
     NS_NewRunnableFunction([self] () {
-      self->mNextSample.reset();
-      self->mReset = true;
+      self->mLastSeek = Some(TimeUnit());
       self->mManager->Seek(self->mType, TimeUnit(), TimeUnit());
       {
         MonitorAutoLock mon(self->mMonitor);
         self->mNextRandomAccessPoint =
           self->mManager->GetNextRandomAccessPoint(self->mType);
       }
     });
   mParent->GetTaskQueue()->Dispatch(task.forget());
@@ -376,68 +375,59 @@ MediaSourceTrackDemuxer::BreakCycles()
 
 RefPtr<MediaSourceTrackDemuxer::SeekPromise>
 MediaSourceTrackDemuxer::DoSeek(media::TimeUnit aTime)
 {
   TimeIntervals buffered = mManager->Buffered(mType);
   buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
 
   if (!buffered.Contains(aTime)) {
+    mLastSeek = Some(aTime);
     // We don't have the data to seek to.
     return SeekPromise::CreateAndReject(DemuxerFailureReason::WAITING_FOR_DATA,
                                         __func__);
   }
   TimeUnit seekTime =
     mManager->Seek(mType, aTime, MediaSourceDemuxer::EOS_FUZZ);
-  bool error;
-  RefPtr<MediaRawData> sample =
-    mManager->GetSample(mType,
-                        media::TimeUnit(),
-                        error);
-  MOZ_ASSERT(!error && sample);
-  mNextSample = Some(sample);
-  mReset = false;
   {
     MonitorAutoLock mon(mMonitor);
     mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);
   }
+  mLastSeek = Some(aTime);
   return SeekPromise::CreateAndResolve(seekTime, __func__);
 }
 
 RefPtr<MediaSourceTrackDemuxer::SamplesPromise>
 MediaSourceTrackDemuxer::DoGetSamples(int32_t aNumSamples)
 {
-  if (mReset) {
+  if (mLastSeek) {
     // If a seek (or reset) was recently performed, we ensure that the data
     // we are about to retrieve is still available.
     TimeIntervals buffered = mManager->Buffered(mType);
     buffered.SetFuzz(MediaSourceDemuxer::EOS_FUZZ);
 
-    if (!buffered.Contains(TimeUnit::FromMicroseconds(0))) {
+    if (!buffered.Contains(mLastSeek.ref())) {
       return SamplesPromise::CreateAndReject(
         mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
                               DemuxerFailureReason::WAITING_FOR_DATA, __func__);
     }
-    mReset = false;
+    mLastSeek.reset();
   }
-  bool error = false;
-  RefPtr<MediaRawData> sample;
-  if (mNextSample) {
-    sample = mNextSample.ref();
-    mNextSample.reset();
-  } else {
-    sample = mManager->GetSample(mType, MediaSourceDemuxer::EOS_FUZZ, error);
-    if (!sample) {
-      if (error) {
-        return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
-      }
-      return SamplesPromise::CreateAndReject(
-        mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
-                              DemuxerFailureReason::WAITING_FOR_DATA, __func__);
+  bool error;
+  RefPtr<MediaRawData> sample =
+    mManager->GetSample(mType,
+                        MediaSourceDemuxer::EOS_FUZZ,
+                        error);
+  if (!sample) {
+    if (error) {
+      return SamplesPromise::CreateAndReject(DemuxerFailureReason::DEMUXER_ERROR, __func__);
     }
+    return SamplesPromise::CreateAndReject(
+      mManager->IsEnded() ? DemuxerFailureReason::END_OF_STREAM :
+                            DemuxerFailureReason::WAITING_FOR_DATA, __func__);
   }
   RefPtr<SamplesHolder> samples = new SamplesHolder;
   samples->mSamples.AppendElement(sample);
   if (mNextRandomAccessPoint.ToMicroseconds() <= sample->mTime) {
     MonitorAutoLock mon(mMonitor);
     mNextRandomAccessPoint = mManager->GetNextRandomAccessPoint(mType);
   }
   return SamplesPromise::CreateAndResolve(samples, __func__);
--- a/dom/media/mediasource/MediaSourceDemuxer.h
+++ b/dom/media/mediasource/MediaSourceDemuxer.h
@@ -124,17 +124,14 @@ private:
   media::TimeUnit GetNextRandomAccessPoint();
 
   RefPtr<MediaSourceDemuxer> mParent;
   RefPtr<TrackBuffersManager> mManager;
   TrackInfo::TrackType mType;
   // Monitor protecting members below accessed from multiple threads.
   Monitor mMonitor;
   media::TimeUnit mNextRandomAccessPoint;
-  Maybe<RefPtr<MediaRawData>> mNextSample;
-  // Set to true following a reset. Ensure that the next sample demuxed
-  // is available at position 0.
-  bool mReset;
+  Maybe<media::TimeUnit> mLastSeek;
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/media/mediasource/test/mochitest.ini
+++ b/dom/media/mediasource/test/mochitest.ini
@@ -35,30 +35,28 @@ support-files =
   bipbop/bipbop13.m4s^headers^ bipbop/bipbop_video13.m4s^headers^
 
 [test_BufferedSeek.html]
 [test_BufferedSeek_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_BufferingWait.html]
 skip-if = toolkit == 'android' #timeout android bug 1199531
 [test_BufferingWait_mp4.html]
-skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
-[test_DrainOnMissingData_mp4.html]
-skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
+skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
 [test_EndOfStream.html]
 skip-if = (true || toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet only bug 1101187 and bug 1182946
 [test_EndOfStream_mp4.html]
 skip-if = (toolkit == 'android' || buildapp == 'mulet') || ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_DurationUpdated.html]
 [test_DurationUpdated_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_FrameSelection.html]
 [test_HaveMetadataUnbufferedSeek.html]
 [test_HaveMetadataUnbufferedSeek_mp4.html]
-skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
+skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
 [test_LoadedDataFired_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_LoadedMetadataFired.html]
 [test_LoadedMetadataFired_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_MediaSource.html]
 [test_MediaSource_memory_reporting.html]
 [test_MediaSource_mp4.html]
@@ -95,16 +93,16 @@ skip-if = ((os == "win" && os_version ==
 skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_SplitAppend.html]
 [test_SplitAppend_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_TimestampOffset_mp4.html]
 skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
 [test_TruncatedDuration.html]
 [test_TruncatedDuration_mp4.html]
-skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
+skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
 [test_WaitingOnMissingData.html]
 skip-if = true # Disabled due to bug 1124493 and friends. WebM MSE is deprioritized.
 [test_WaitingOnMissingData_mp4.html]
-skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
+skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
 [test_WaitingToEndedTransition_mp4.html]
-skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
+skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac") || (os == "win" && os_version == "6.1")) # Only supported on osx and vista+, disabling on win7 bug 1191138
 
--- a/dom/media/mediasource/test/test_BufferingWait_mp4.html
+++ b/dom/media/mediasource/test/test_BufferingWait_mp4.html
@@ -36,24 +36,28 @@ runWithMSE(function(ms, v) {
     sb.addEventListener('error', (e) => { ok(false, "Got Error: " + e); SimpleTest.finish(); });
     fetchAndLoad(sb, 'bipbop/bipbop', ['init'], '.mp4')
     .then(fetchAndLoad.bind(null, sb, 'bipbop/bipbop', ['1'], '.m4s'))
     .then(fetchAndLoad.bind(null, sb, 'bipbop/bipbop', ['2'], '.m4s'))
     /* Note - Missing |bipbop3| segment here corresponding to (1.62, 2.41] */
     /* Note - Missing |bipbop4| segment here corresponding to (2.41, 3.20]  */
     .then(fetchAndLoad.bind(null, sb, 'bipbop/bipbop', ['5'], '.m4s'))
     .then(function() {
-        var promise = waitUntilTime(1.62-1/30);
+        // Some decoders (Windows in particular) may keep up to 25 frames queued
+        // before returning a sample. 0.7 is 1.62s - 25 * 0.03333
+        var promise = waitUntilTime(0.7);
         info("Playing video. It should play for a bit, then fire 'waiting'");
         v.play();
         return promise;
       }).then(function() {
         window.firstStop = Date.now();
         fetchAndLoad(sb, 'bipbop/bipbop', ['3'], '.m4s');
-        return waitUntilTime(2.41-1/30);
+        // Some decoders (Windows in particular) may keep up to 25 frames queued
+        // before returning a sample. 1.5 is 2.41s - 25 * 0.03333
+        return waitUntilTime(1.5);
       }).then(function() {
         var waitDuration = (Date.now() - window.firstStop) / 1000;
         ok(waitDuration < 15, "Should not spend an inordinate amount of time buffering: " + waitDuration);
         once(v, 'ended', SimpleTest.finish.bind(SimpleTest));
         return fetchAndLoad(sb, 'bipbop/bipbop', ['4'], '.m4s');
       }).then(function() {
         ms.endOfStream();
       });;
deleted file mode 100644
--- a/dom/media/mediasource/test/test_DrainOnMissingData_mp4.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<html><head>
-<meta http-equiv="content-type" content="text/html; charset=windows-1252">
-  <title>MSE: |waiting| event when source data is missing</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="text/javascript" src="mediasource.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-<pre id="test"><script class="testbody" type="text/javascript">
-
-SimpleTest.waitForExplicitFinish();
-
-runWithMSE(function(ms, el) {
-  el.controls = true;
-  once(ms, 'sourceopen').then(function() {
-    ok(true, "Receive a sourceopen event");
-    var videosb = ms.addSourceBuffer("video/mp4");
-    fetchAndLoad(videosb, 'bipbop/bipbop_video', ['init'], '.mp4')
-    .then(function() {
-      // Set appendWindowEnd to ensure we only have about 6 frames worth.
-      // We must feed at least 6 frames to pass the MDSM pre-roll.
-      videosb.appendWindowEnd = .4;
-      return fetchAndLoad(videosb, 'bipbop/bipbop_video', ['1'], '.m4s');
-    })
-    .then(function() {
-      info("Invoking play()");
-      var promises = [];
-      promises.push(once(el, 'playing'));
-      el.play();
-      return Promise.all(promises);
-    })
-    .then(function() {
-      info("got playing");
-      return once(el, 'waiting');
-    }).then(function() {
-      info("got waiting");
-      info("Loading more data");
-      // Waiting will be fired on the last frame +- 40ms.
-      isfuzzy(el.currentTime, videosb.buffered.end(0) - 1/30,
-              0.04, "Got a waiting event at " + el.currentTime);
-      videosb.appendWindowEnd = 1;
-      var p = once(el, 'ended');
-      var loads = fetchAndLoad(videosb, 'bipbop/bipbop_video', [1], '.m4s');
-      loads.then(() => ms.endOfStream());
-      return p;
-    }).then(function() {
-      // These fuzz factors are bigger than they should be. We should investigate
-      // and fix them in bug 1137574.
-      is(el.duration, 0.801666, "Video has correct duration: " + el.duration);
-      is(el.currentTime, el.duration, "Video has correct currentTime.");
-      SimpleTest.finish();
-    });
-  });
-});
-
-</script>
-</pre>
-</body>
-</html>
--- a/dom/media/mediasource/test/test_PlayEvents.html
+++ b/dom/media/mediasource/test/test_PlayEvents.html
@@ -32,16 +32,19 @@ runWithMSE(function(ms, el) {
     is(el.readyState, el.HAVE_NOTHING, "readyState is HAVE_NOTHING");
     fetchAndLoad(videosb, 'bipbop/bipbop_video', ['init'], '.mp4')
     .then(once.bind(null, el, 'loadedmetadata'))
     .then(function() {
        ok(true, "got loadedmetadata event");
        var promises = [];
        promises.push(once(el, 'loadeddata'));
        promises.push(once(el, 'canplay'));
+       // Load [0, 1.601666). We must ensure that we load over 25 frames as the
+       // windows H264 decoder will not produce a sample until then
+       // (bug 1191138).
        promises.push(fetchAndLoad(videosb, 'bipbop/bipbop_video', range(1, 3), '.m4s'));
        return Promise.all(promises);
     })
     .then(function() {
       ok(true, "got canplay event");
       // set element duration to 3.203333s. We do so in order to guarantee that
       // the end of the buffered range will be equal to duration, causing
       // canplaythrough to be fired later.
--- a/dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html
+++ b/dom/media/mediasource/test/test_WaitingOnMissingData_mp4.html
@@ -35,18 +35,19 @@ runWithMSE(function(ms, el) {
       ok(true, "Video playing. It should play for a bit, then fire 'waiting'");
       var p = once(el, 'waiting');
       el.play();
       return p;
     }).then(function() {
       // currentTime is based on the current video frame, so if the audio ends just before
       // the next video frame, currentTime can be up to 1 frame's worth earlier than
       // min(audioEnd, videoEnd).
-      isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/30,
-              0.04, "Got a waiting event at " + el.currentTime);
+      // Some decoders (Windows in particular) may keep up to 25 frames queued.
+      isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/60,
+              25 * 1/30, "Got a waiting event at " + el.currentTime);
       info("Loading more data");
       var p = once(el, 'ended');
       var loads = Promise.all([fetchAndLoad(audiosb, 'bipbop/bipbop_audio', [5], '.m4s'),
                                fetchAndLoad(videosb, 'bipbop/bipbop_video', [6], '.m4s')]);
       loads.then(() => ms.endOfStream());
       return p;
     }).then(function() {
       // These fuzz factors are bigger than they should be. We should investigate
--- a/dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html
+++ b/dom/media/mediasource/test/test_WaitingToEndedTransition_mp4.html
@@ -34,18 +34,19 @@ runWithMSE(function(ms, el) {
       var p = once(el, 'waiting');
       el.play();
       return p;
     }).then(function() {
       // currentTime is based on the current video frame, so if the audio ends just before
       // the next video frame, currentTime can be up to 1 frame's worth earlier than
       // min(audioEnd, videoEnd).
       // Some decoders (Windows in particular) may keep up to 25 frames queued.
-      isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/30,
-              0.04, "Got a waiting event at " + el.currentTime);
+      isfuzzy(el.currentTime, Math.min(audiosb.buffered.end(0), videosb.buffered.end(0)) - 1/60,
+              25 * 1/30, "Got a waiting event at " + el.currentTime);
+    }).then(function() {
       var p = once(el, 'ended');
       ms.endOfStream();
       return p;
     }).then(function() {
       is(el.duration, 4.005, "Video has correct duration: " + el.duration);
       is(el.currentTime, el.duration, "Video has correct currentTime.");
       SimpleTest.finish();
     });