Bug 1440555 - P1: Allow setVisible to take effect before decoder creation. r?cpearce draft
authorDan Glastonbury <dan.glastonbury@gmail.com>
Tue, 27 Feb 2018 14:33:41 +1000
changeset 760241 782f3cab6fa67dca678d2b0a17028c8fcade2cd6
parent 758791 f7c5598e45c323547dc6d030bf8442850c15813b
child 760242 547719acfb9f87c5a8c5dc0f9c248a957d38e011
push id100580
push userbmo:dglastonbury@mozilla.com
push dateTue, 27 Feb 2018 04:41:50 +0000
reviewerscpearce
bugs1440555
milestone60.0a1
Bug 1440555 - P1: Allow setVisible to take effect before decoder creation. r?cpearce MozReview-Commit-ID: GSNM6esm0fW
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
dom/media/MediaDecoderStateMachine.cpp
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1640,21 +1640,20 @@ HTMLMediaElement::MozDumpDebugInfo()
     promise->MaybeResolveWithUndefined();
   }
   return promise.forget();
 }
 
 void
 HTMLMediaElement::SetVisible(bool aVisible)
 {
-  if (!mDecoder) {
-    return;
-  }
-
-  mDecoder->SetForcedHidden(!aVisible);
+  mForcedHidden = !aVisible;
+  if (mDecoder) {
+    mDecoder->SetForcedHidden(!aVisible);
+  }
 }
 
 already_AddRefed<layers::Image>
 HTMLMediaElement::GetCurrentImage()
 {
   MarkAsTainted();
 
   // TODO: In bug 1345404, handle case when video decoder is already suspended.
@@ -3876,16 +3875,17 @@ HTMLMediaElement::HTMLMediaElement(alrea
     mMediaSecurityVerified(false),
     mCORSMode(CORS_NONE),
     mIsEncrypted(false),
     mWaitingForKey(NOT_WAITING_FOR_KEY),
     mDisableVideo(false),
     mFirstFrameLoaded(false),
     mDefaultPlaybackStartPosition(0.0),
     mHasSuspendTaint(false),
+    mForcedHidden(false),
     mMediaTracksConstructed(false),
     mVisibilityState(Visibility::UNTRACKED),
     mErrorSink(new ErrorSink(this)),
     mAudioChannelWrapper(new AudioChannelAgentCallback(this))
 {
   MOZ_ASSERT(mMainThreadEventTarget);
   MOZ_ASSERT(mAbstractMainThread);
 
@@ -7328,16 +7328,19 @@ void
 HTMLMediaElement::SetDecoder(MediaDecoder* aDecoder)
 {
   MOZ_ASSERT(aDecoder); // Use ShutdownDecoder() to clear.
   if (mDecoder) {
     ShutdownDecoder();
   }
   mDecoder = aDecoder;
   DDLINKCHILD("decoder", mDecoder.get());
+  if (mDecoder && mForcedHidden) {
+    mDecoder->SetForcedHidden(mForcedHidden);
+  }
 }
 
 float
 HTMLMediaElement::ComputedVolume() const
 {
   return mMuted ? 0.0f : mAudioChannelWrapper ?
     mAudioChannelWrapper->GetEffectiveVolume() : mVolume;
 }
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1816,16 +1816,20 @@ private:
   // initially be set to zero seconds. This time is used to allow the element to
   // be seeked even before the media is loaded.
   double mDefaultPlaybackStartPosition;
 
   // True if media element has been marked as 'tainted' and can't
   // participate in video decoder suspending.
   bool mHasSuspendTaint;
 
+  // True if media element has been forced into being considered 'hidden'.
+  // For use by mochitests. Enabling pref "media.test.video-suspend"
+  bool mForcedHidden;
+
   // True if audio tracks and video tracks are constructed and added into the
   // track list, false if all tracks are removed from the track list.
   bool mMediaTracksConstructed;
 
   Visibility mVisibilityState;
 
   UniquePtr<ErrorSink> mErrorSink;
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -3075,33 +3075,33 @@ void MediaDecoderStateMachine::SetVideoD
     aMode);
   OwnerThread()->DispatchStateChange(r.forget());
 }
 
 void MediaDecoderStateMachine::SetVideoDecodeModeInternal(VideoDecodeMode aMode)
 {
   MOZ_ASSERT(OnTaskQueue());
 
+  LOG("SetVideoDecodeModeInternal(), VideoDecodeMode=(%s->%s), mVideoDecodeSuspended=%c",
+      mVideoDecodeMode == VideoDecodeMode::Normal ? "Normal" : "Suspend",
+      aMode == VideoDecodeMode::Normal ? "Normal" : "Suspend",
+      mVideoDecodeSuspended ? 'T' : 'F');
+
   // Should not suspend decoding if we don't turn on the pref.
   if (!MediaPrefs::MDSMSuspendBackgroundVideoEnabled() &&
       aMode == VideoDecodeMode::Suspend) {
     LOG("SetVideoDecodeModeInternal(), early return because preference off and set to Suspend");
     return;
   }
 
   if (aMode == mVideoDecodeMode) {
     LOG("SetVideoDecodeModeInternal(), early return because the mode does not change");
     return;
   }
 
-  LOG("SetVideoDecodeModeInternal(), VideoDecodeMode=(%s->%s), mVideoDecodeSuspended=%c",
-      mVideoDecodeMode == VideoDecodeMode::Normal ? "Normal" : "Suspend",
-      aMode == VideoDecodeMode::Normal ? "Normal" : "Suspend",
-      mVideoDecodeSuspended ? 'T' : 'F');
-
   // Set new video decode mode.
   mVideoDecodeMode = aMode;
 
   // Start timer to trigger suspended video decoding.
   if (mVideoDecodeMode == VideoDecodeMode::Suspend) {
     TimeStamp target = TimeStamp::Now() + SuspendBackgroundVideoDelay();
 
     RefPtr<MediaDecoderStateMachine> self = this;