Bug 1257013 - Part 3: Stop checking for corrupt frames in MediaDecoderStateMachine since we no longer produce them. r=ajones
authorMatt Woodrow <mwoodrow@mozilla.com>
Mon, 21 Mar 2016 18:50:41 +1300
changeset 289682 ad78daa8b4b4d12b1c243f16b5a659f35343600a
parent 289681 60abff0e797681b1a49f11058f4ddec2e0339c36
child 289683 ad57442dddb68b4dd53dd28f370be15035021240
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajones
bugs1257013
milestone48.0a1
Bug 1257013 - Part 3: Stop checking for corrupt frames in MediaDecoderStateMachine since we no longer produce them. r=ajones
dom/media/FrameStatistics.h
dom/media/MediaDecoderReader.h
dom/media/MediaDecoderStateMachine.cpp
dom/media/MediaDecoderStateMachine.h
dom/media/MediaFormatReader.cpp
dom/media/MediaFormatReader.h
--- a/dom/media/FrameStatistics.h
+++ b/dom/media/FrameStatistics.h
@@ -15,18 +15,17 @@ class FrameStatistics {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameStatistics);
 
   FrameStatistics() :
       mReentrantMonitor("FrameStats"),
       mParsedFrames(0),
       mDecodedFrames(0),
       mPresentedFrames(0),
-      mDroppedFrames(0),
-      mCorruptFrames(0) {}
+      mDroppedFrames(0) {}
 
   // Returns number of frames which have been parsed from the media.
   // Can be called on any thread.
   uint32_t GetParsedFrames() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mParsedFrames;
   }
 
@@ -44,22 +43,17 @@ public:
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mPresentedFrames;
   }
 
   // Number of frames that have been skipped because they have missed their
   // compoisition deadline.
   uint32_t GetDroppedFrames() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-    return mDroppedFrames + mCorruptFrames;
-  }
-
-  uint32_t GetCorruptedFrames() {
-    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-    return mCorruptFrames;
+    return mDroppedFrames;
   }
 
   // Increments the parsed and decoded frame counters by the passed in counts.
   // Can be called on any thread.
   void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
                            uint32_t aDropped) {
     if (aParsed == 0 && aDecoded == 0 && aDropped == 0)
       return;
@@ -71,21 +65,16 @@ public:
 
   // Increments the presented frame counters.
   // Can be called on any thread.
   void NotifyPresentedFrame() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     ++mPresentedFrames;
   }
 
-  void NotifyCorruptFrame() {
-    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-    ++mCorruptFrames;
-  }
-
 private:
   ~FrameStatistics() {}
 
   // ReentrantMonitor to protect access of playback statistics.
   ReentrantMonitor mReentrantMonitor;
 
   // Number of frames parsed and demuxed from media.
   // Access protected by mReentrantMonitor.
@@ -95,15 +84,13 @@ private:
   // Access protected by mReentrantMonitor.
   uint32_t mDecodedFrames;
 
   // Number of decoded frames which were actually sent down the rendering
   // pipeline to be painted ("presented"). Access protected by mReentrantMonitor.
   uint32_t mPresentedFrames;
 
   uint32_t mDroppedFrames;
-
-  uint32_t mCorruptFrames;
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -276,18 +276,16 @@ public:
   // implementation in this class to adapt the old synchronous to
   // the newer async model.
   virtual bool IsAsync() const { return false; }
 
   // Returns true if this decoder reader uses hardware accelerated video
   // decoding.
   virtual bool VideoIsHardwareAccelerated() const { return false; }
 
-  virtual void DisableHardwareAcceleration() {}
-
   TimedMetadataEventSource& TimedMetadataEvent()
   {
     return mTimedMetadataEvent;
   }
 
   // Notified by the OggReader during playback when chained ogg is detected.
   MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -233,17 +233,16 @@ MediaDecoderStateMachine::MediaDecoderSt
   mNotifyMetadataBeforeFirstFrame(false),
   mDispatchedEventToDecode(false),
   mQuickBuffering(false),
   mMinimizePreroll(false),
   mDecodeThreadWaiting(false),
   mDropAudioUntilNextDiscontinuity(false),
   mDropVideoUntilNextDiscontinuity(false),
   mCurrentTimeBeforeSeek(0),
-  mCorruptFrames(60),
   mDecodingFirstFrame(true),
   mSentLoadedMetadataEvent(false),
   mSentFirstFrameLoadedEvent(false),
   mSentPlaybackEndedEvent(false),
   mOutputStreamManager(new OutputStreamManager()),
   mResource(aDecoder->GetResource()),
   mAudioOffloading(false),
   mSilentDataDuration(0),
@@ -889,20 +888,16 @@ MediaDecoderStateMachine::OnVideoDecoded
   // Handle abnormal or negative timestamps.
   mDecodedVideoEndTime = std::max(mDecodedVideoEndTime, video->GetEndTime());
 
   SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d",
              (video ? video->mTime : -1),
              (video ? video->GetEndTime() : -1),
              (video ? video->mDiscontinuity : 0));
 
-  // Check frame validity here for every decoded frame in order to have a
-  // better chance to make the decision of turning off HW acceleration.
-  CheckFrameValidity(aVideoSample->As<VideoData>());
-
   switch (mState) {
     case DECODER_STATE_BUFFERING: {
       // If we're buffering, this may be the sample we need to stop buffering.
       // Save it and schedule the state machine.
       Push(video, MediaData::VIDEO_DATA);
       ScheduleStateMachine();
       return;
     }
@@ -2414,43 +2409,16 @@ MediaDecoderStateMachine::Reset()
 
   mPlaybackOffset = 0;
 
   nsCOMPtr<nsIRunnable> resetTask =
     NS_NewRunnableMethod(mReader, &MediaDecoderReader::ResetDecode);
   DecodeTaskQueue()->Dispatch(resetTask.forget());
 }
 
-void
-MediaDecoderStateMachine::CheckFrameValidity(VideoData* aData)
-{
-  MOZ_ASSERT(OnTaskQueue());
-
-  // Update corrupt-frames statistics
-  if (aData->mImage && !aData->mImage->IsValid() && !gfxPrefs::HardwareVideoDecodingForceEnabled()) {
-    FrameStatistics& frameStats = *mFrameStats;
-    frameStats.NotifyCorruptFrame();
-    // If more than 10% of the last 30 frames have been corrupted, then try disabling
-    // hardware acceleration. We use 10 as the corrupt value because RollingMean<>
-    // only supports integer types.
-    mCorruptFrames.insert(10);
-    if (mReader->VideoIsHardwareAccelerated() &&
-        frameStats.GetPresentedFrames() > 60 &&
-        mCorruptFrames.mean() >= 2 /* 20% */) {
-        nsCOMPtr<nsIRunnable> task =
-          NS_NewRunnableMethod(mReader, &MediaDecoderReader::DisableHardwareAcceleration);
-        DecodeTaskQueue()->Dispatch(task.forget());
-        mCorruptFrames.clear();
-      gfxCriticalNote << "Too many dropped/corrupted frames, disabling DXVA";
-    }
-  } else {
-    mCorruptFrames.insert(0);
-  }
-}
-
 int64_t
 MediaDecoderStateMachine::GetClock(TimeStamp* aTimeStamp) const
 {
   MOZ_ASSERT(OnTaskQueue());
   int64_t clockTime = mMediaSink->GetPosition(aTimeStamp);
   NS_ASSERTION(GetMediaTime() <= clockTime, "Clock should go forwards.");
   return clockTime;
 }
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -79,17 +79,16 @@ audio data off the queue and plays it wi
 hardware (via AudioStream).
 
 */
 #if !defined(MediaDecoderStateMachine_h__)
 #define MediaDecoderStateMachine_h__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ReentrantMonitor.h"
-#include "mozilla/RollingMean.h"
 #include "mozilla/StateMirroring.h"
 
 #include "nsThreadUtils.h"
 #include "MediaDecoder.h"
 #include "MediaDecoderReader.h"
 #include "MediaDecoderOwner.h"
 #include "MediaEventSource.h"
 #include "MediaMetadataManager.h"
@@ -449,20 +448,16 @@ protected:
   void SetStartTime(int64_t aStartTimeUsecs);
 
   // Update only the state machine's current playback position (and duration,
   // if unknown).  Does not update the playback position on the decoder or
   // media element -- use UpdatePlaybackPosition for that.  Called on the state
   // machine thread, caller must hold the decoder lock.
   void UpdatePlaybackPositionInternal(int64_t aTime);
 
-  // Decode monitor must be held. To determine if MDSM needs to turn off HW
-  // acceleration.
-  void CheckFrameValidity(VideoData* aData);
-
   // Update playback position and trigger next update by default time period.
   // Called on the state machine thread.
   void UpdatePlaybackPositionPeriodically();
 
   media::MediaSink* CreateAudioSink();
 
   // Always create mediasink which contains an AudioSink or StreamSink inside.
   already_AddRefed<media::MediaSink> CreateMediaSink(bool aAudioCaptured);
@@ -1126,18 +1121,16 @@ private:
   // Stores presentation info required for playback. The decoder monitor
   // must be held when accessing this.
   MediaInfo mInfo;
 
   nsAutoPtr<MetadataTags> mMetadataTags;
 
   mozilla::MediaMetadataManager mMetadataManager;
 
-  mozilla::RollingMean<uint32_t, uint32_t> mCorruptFrames;
-
   // Track our request to update the buffered ranges
   MozPromiseRequestHolder<MediaDecoderReader::BufferedUpdatePromise> mBufferedUpdateRequest;
 
   // True if we need to call FinishDecodeFirstFrame() upon frame decoding
   // successeeding.
   bool mDecodingFirstFrame;
 
   // True if we are back from DECODER_STATE_DORMANT state and
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -63,17 +63,16 @@ MediaFormatReader::MediaFormatReader(Abs
   , mVideo(this, MediaData::VIDEO_DATA, Preferences::GetUint("media.video-decode-ahead", 2))
   , mDemuxer(aDemuxer)
   , mDemuxerInitDone(false)
   , mLastReportedNumDecodedFrames(0)
   , mLayersBackendType(aLayersBackend)
   , mInitDone(false)
   , mIsEncrypted(false)
   , mTrackDemuxersMayBlock(false)
-  , mHardwareAccelerationDisabled(false)
   , mDemuxOnly(false)
   , mVideoFrameContainer(aVideoFrameContainer)
 {
   MOZ_ASSERT(aDemuxer);
   MOZ_COUNT_CTOR(MediaFormatReader);
 }
 
 MediaFormatReader::~MediaFormatReader()
@@ -401,17 +400,16 @@ MediaFormatReader::EnsureDecoderCreated(
       // Decoders use the layers backend to decide if they can use hardware decoding,
       // so specify LAYERS_NONE if we want to forcibly disable it.
       decoder.mDecoder =
         mPlatform->CreateDecoder(mVideo.mInfo ?
                                    *mVideo.mInfo->GetAsVideoInfo() :
                                    mInfo.mVideo,
                                  decoder.mTaskQueue,
                                  decoder.mCallback,
-                                 mHardwareAccelerationDisabled ? LayersBackend::LAYERS_NONE :
                                  mLayersBackendType,
                                  GetImageContainer());
       break;
     default:
       break;
   }
   if (decoder.mDecoder ) {
     decoder.mDescription = decoder.mDecoder->GetDescriptionName();
@@ -466,33 +464,16 @@ MediaFormatReader::GetDecoderData(TrackT
   MOZ_ASSERT(aTrack == TrackInfo::kAudioTrack ||
              aTrack == TrackInfo::kVideoTrack);
   if (aTrack == TrackInfo::kAudioTrack) {
     return mAudio;
   }
   return mVideo;
 }
 
-void
-MediaFormatReader::DisableHardwareAcceleration()
-{
-  MOZ_ASSERT(OnTaskQueue());
-  if (HasVideo() && !mHardwareAccelerationDisabled) {
-    mHardwareAccelerationDisabled = true;
-    Flush(TrackInfo::kVideoTrack);
-    mVideo.ShutdownDecoder();
-    if (!EnsureDecoderCreated(TrackType::kVideoTrack)) {
-      LOG("Unable to re-create decoder, aborting");
-      NotifyError(TrackInfo::kVideoTrack);
-      return;
-    }
-    ScheduleUpdate(TrackInfo::kVideoTrack);
-  }
-}
-
 bool
 MediaFormatReader::ShouldSkip(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold)
 {
   MOZ_ASSERT(HasVideo());
   media::TimeUnit nextKeyframe;
   nsresult rv = mVideo.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe);
   if (NS_FAILED(rv)) {
     return aSkipToNextKeyframe;
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -65,18 +65,16 @@ public:
   nsresult ResetDecode() override;
 
   RefPtr<ShutdownPromise> Shutdown() override;
 
   bool IsAsync() const override { return true; }
 
   bool VideoIsHardwareAccelerated() const override;
 
-  void DisableHardwareAcceleration() override;
-
   bool IsWaitForDataSupported() override { return true; }
   RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType) override;
 
   // MediaFormatReader supports demuxed-only mode.
   bool IsDemuxOnlySupported() const override { return true; }
 
   void SetDemuxOnly(bool aDemuxedOnly) override
   {
@@ -444,18 +442,16 @@ private:
   {
     return mIsEncrypted;
   }
   bool mIsEncrypted;
 
   // Set to true if any of our track buffers may be blocking.
   bool mTrackDemuxersMayBlock;
 
-  bool mHardwareAccelerationDisabled;
-
   // Set the demuxed-only flag.
   Atomic<bool> mDemuxOnly;
 
   // Seeking objects.
   bool IsSeeking() const { return mPendingSeekTime.isSome(); }
   void AttemptSeek();
   void OnSeekFailed(TrackType aTrack, DemuxerFailureReason aFailure);
   void DoVideoSeek();