Bug 1295884 - Fix video suspend intermittent failures. r?jwwang draft
authorDan Glastonbury <dglastonbury@mozilla.com>
Thu, 25 Aug 2016 12:10:05 +1000
changeset 405187 17eeb9d0752f680560445296616eca85541a2c0c
parent 404651 bd7645928990649c84609d3f531e803c2d41f269
child 529385 81324e3e9e2acc869d5d11c596f11339f6153ec1
push id27429
push userbmo:dglastonbury@mozilla.com
push dateThu, 25 Aug 2016 02:16:24 +0000
reviewersjwwang
bugs1295884
milestone51.0a1
Bug 1295884 - Fix video suspend intermittent failures. r?jwwang On Linux x64 PGO try, HTMLMediaElement was reliably invoking decoder->NotifyOwnerActivityChanged() after SetVisible(false) was called. This caused the pending suspend to be cancelled and the test waits for an event that never arrives. Fixed by adding 'forced hidden' to MediaDecoder that overrides the element visibility that comes from HTMLMediaElement. MozReview-Commit-ID: 5aRhxxZ5cZd
dom/html/HTMLMediaElement.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -793,18 +793,17 @@ HTMLMediaElement::MozDumpDebugInfo()
 
 void
 HTMLMediaElement::SetVisible(bool aVisible)
 {
   if (!mDecoder) {
     return;
   }
 
-  mDecoder->NotifyOwnerActivityChanged(aVisible);
-
+  mDecoder->SetForcedHidden(!aVisible);
 }
 
 already_AddRefed<DOMMediaStream>
 HTMLMediaElement::GetSrcObject() const
 {
   NS_ASSERTION(!mSrcAttrStream || mSrcAttrStream->GetPlaybackStream(),
                "MediaStream should have been set up properly");
   RefPtr<DOMMediaStream> stream = mSrcAttrStream;
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -503,16 +503,18 @@ MediaDecoder::MediaDecoder(MediaDecoderO
   , mFrameStats(new FrameStatistics())
   , mVideoFrameContainer(aOwner->GetVideoFrameContainer())
   , mPlaybackStatistics(new MediaChannelStatistics())
   , mPinnedForSeek(false)
   , mPausedForPlaybackRateNull(false)
   , mMinimizePreroll(false)
   , mMediaTracksConstructed(false)
   , mFiredMetadataLoaded(false)
+  , mElementVisible(true)
+  , mForcedHidden(false)
   , mIsDormant(false)
   , mIsHeuristicDormantSupported(
       Preferences::GetBool("media.decoder.heuristic.dormant.enabled", false))
   , mHeuristicDormantTimeout(
       Preferences::GetInt("media.decoder.heuristic.dormant.timeout",
                           DEFAULT_HEURISTIC_DORMANT_TIMEOUT_MSECS))
   , mIsHeuristicDormant(false)
   , INIT_MIRROR(mStateMachineIsShutdown, true)
@@ -1358,17 +1360,26 @@ MediaDecoder::DurationChanged()
     Seek(mDuration, SeekTarget::Accurate);
   }
 }
 
 void
 MediaDecoder::SetElementVisibility(bool aIsVisible)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  mIsVisible = aIsVisible;
+  mElementVisible = aIsVisible;
+  mIsVisible = !mForcedHidden && mElementVisible;
+}
+
+void
+MediaDecoder::SetForcedHidden(bool aForcedHidden)
+{
+    MOZ_ASSERT(NS_IsMainThread());
+    mForcedHidden = aForcedHidden;
+    SetElementVisibility(mElementVisible);
 }
 
 void
 MediaDecoder::UpdateEstimatedMediaDuration(int64_t aDuration)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mPlayState <= PLAY_STATE_LOADING) {
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -373,16 +373,20 @@ private:
   virtual bool CanPlayThrough();
 
   void SetAudioChannel(dom::AudioChannel aChannel) { mAudioChannel = aChannel; }
   dom::AudioChannel GetAudioChannel() { return mAudioChannel; }
 
   // Called from HTMLMediaElement when owner document activity changes
   virtual void SetElementVisibility(bool aIsVisible);
 
+  // Force override the visible state to hidden.
+  // Called from HTMLMediaElement when testing of video decode suspend from mochitests.
+  void SetForcedHidden(bool aForcedHidden);
+
   /******
    * The following methods must only be called on the main
    * thread.
    ******/
 
   // Change to a new play state. This updates the mState variable and
   // notifies any thread blocking on this object's monitor of the
   // change. Call on the main thread only.
@@ -698,16 +702,22 @@ protected:
 
   // True if we've already fired metadataloaded.
   bool mFiredMetadataLoaded;
 
   // Stores media info, including info of audio tracks and video tracks, should
   // only be accessed from main thread.
   nsAutoPtr<MediaInfo> mInfo;
 
+  // Tracks the visiblity status from HTMLMediaElement
+  bool mElementVisible;
+
+  // If true, forces the decoder to be considered hidden.
+  bool mForcedHidden;
+
   // True if MediaDecoder is in dormant state.
   bool mIsDormant;
 
   // True if heuristic dormant is supported.
   const bool mIsHeuristicDormantSupported;
 
   // Timeout ms of heuristic dormant timer.
   const int mHeuristicDormantTimeout;