Bug 1346498 part 9 - move all policy codes into MediaDecoder::UpdateVideoDecodeMode(); r?jwwang draft
authorKaku Kuo <kaku@mozilla.com>
Sat, 11 Mar 2017 19:56:17 +0800
changeset 497408 ab664369c19c3e3969006ab3a1742d30aa62ee74
parent 497407 c2530d9fe592b4fe82bf1c8bdfd36fa990c16012
child 497409 0b7abd405150916ed4ae8b95630b73f43a568112
push id48888
push userbmo:kaku@mozilla.com
push dateMon, 13 Mar 2017 08:46:01 +0000
reviewersjwwang
bugs1346498
milestone55.0a1
Bug 1346498 part 9 - move all policy codes into MediaDecoder::UpdateVideoDecodeMode(); r?jwwang Make HTMLMediaElement no longer has logic of deciding visibility, it just passes all information into MediaDecoder. MozReview-Commit-ID: ApVcEQfboO
dom/html/HTMLMediaElement.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -7395,22 +7395,19 @@ HTMLMediaElement::GetEMEInfo(nsString& a
   aEMEInfo.Append(keySystem);
   aEMEInfo.AppendLiteral(" SessionsInfo=");
   aEMEInfo.Append(sessionsInfo);
 }
 
 void
 HTMLMediaElement::NotifyDecoderActivityChanges() const
 {
-  // A element is visible only if its document is visible and the element
-  // itself is visible.
-  const bool visible = !IsHidden() &&
-                       mVisibilityState == Visibility::APPROXIMATELY_VISIBLE;
   if (mDecoder) {
-    mDecoder->NotifyOwnerActivityChanged(visible);
+    mDecoder->NotifyOwnerActivityChanged(!IsHidden(),
+                                         mVisibilityState == Visibility::APPROXIMATELY_VISIBLE);
   }
 }
 
 bool HasDebuggerPrivilege(JSContext* aCx, JSObject* aObj)
 {
   return nsContentUtils::CallerHasPermission(aCx,
                                              NS_LITERAL_STRING("debugger"));
  }
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -292,21 +292,22 @@ MediaDecoder::ResourceCallback::NotifyBy
     if (self->mDecoder) {
       self->mDecoder->NotifyBytesConsumed(aBytes, aOffset);
     }
   });
   mAbstractMainThread->Dispatch(r.forget());
 }
 
 void
-MediaDecoder::NotifyOwnerActivityChanged(bool aIsVisible)
+MediaDecoder::NotifyOwnerActivityChanged(bool aIsDocumentVisible,
+                                         bool aIsElementVisible)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
-  SetElementVisibility(aIsVisible);
+  SetElementVisibility(aIsDocumentVisible, aIsElementVisible);
 
   NotifyCompositor();
 }
 
 void
 MediaDecoder::Pause()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -389,17 +390,18 @@ MediaDecoder::MediaDecoder(MediaDecoderO
   , mAbstractMainThread(aOwner->AbstractMainThread())
   , mFrameStats(new FrameStatistics())
   , mVideoFrameContainer(aOwner->GetVideoFrameContainer())
   , mPlaybackStatistics(new MediaChannelStatistics())
   , mPinnedForSeek(false)
   , mMinimizePreroll(false)
   , mMediaTracksConstructed(false)
   , mFiredMetadataLoaded(false)
-  , mElementVisible(!aOwner->IsHidden())
+  , mIsDocumentVisible(!aOwner->IsHidden())
+  , mIsElementVisible(!aOwner->IsHidden())
   , mForcedHidden(false)
   , mHasSuspendTaint(false)
   , INIT_MIRROR(mStateMachineIsShutdown, true)
   , INIT_MIRROR(mBuffered, TimeIntervals())
   , INIT_MIRROR(mNextFrameStatus, MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE)
   , INIT_MIRROR(mCurrentPosition, 0)
   , INIT_MIRROR(mStateMachineDuration, NullableTimeUnit())
   , INIT_MIRROR(mPlaybackPosition, 0)
@@ -1300,20 +1302,22 @@ MediaDecoder::NotifyCompositor()
     nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
   if (layerManager) {
     RefPtr<KnowsCompositor> knowsCompositor = layerManager->AsShadowForwarder();
     mCompositorUpdatedEvent.Notify(knowsCompositor);
   }
 }
 
 void
-MediaDecoder::SetElementVisibility(bool aIsVisible)
+MediaDecoder::SetElementVisibility(bool aIsDocumentVisible,
+                                   bool aIsElementVisible)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  mElementVisible = aIsVisible;
+  mIsDocumentVisible = aIsDocumentVisible;
+  mIsElementVisible = aIsElementVisible;
   UpdateVideoDecodeMode();
 }
 
 void
 MediaDecoder::SetForcedHidden(bool aForcedHidden)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mForcedHidden = aForcedHidden;
@@ -1338,18 +1342,25 @@ MediaDecoder::UpdateVideoDecodeMode()
 
   // If mHasSuspendTaint is set, never suspend the video decoder.
   if (mHasSuspendTaint) {
     mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
     return;
   }
 
   // If mForcedHidden is set, suspend the video decoder anyway.
+  if (mForcedHidden) {
+    mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Suspend);
+    return;
+  }
+
   // Otherwise, depends on the owner's visibility state.
-  if (!mForcedHidden && mElementVisible) {
+  // A element is visible only if its document is visible and the element
+  // itself is visible.
+  if (mIsDocumentVisible && mIsElementVisible) {
     mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
   } else {
     mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Suspend);
   }
 }
 
 bool
 MediaDecoder::HasSuspendTaint() const
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -184,17 +184,18 @@ public:
   // Initialize state machine and schedule it.
   nsresult InitializeStateMachine();
 
   // Start playback of a video. 'Load' must have previously been
   // called.
   virtual nsresult Play();
 
   // Notify activity of the decoder owner is changed.
-  virtual void NotifyOwnerActivityChanged(bool aIsVisible);
+  virtual void NotifyOwnerActivityChanged(bool aIsDocumentVisible,
+                                          bool aIsElementVisible);
 
   // Pause video playback.
   virtual void Pause();
   // Adjust the speed of the playback, optionally with pitch correction,
   virtual void SetVolume(double aVolume);
 
   virtual void SetPlaybackRate(double aPlaybackRate);
   void SetPreservesPitch(bool aPreservesPitch);
@@ -366,17 +367,18 @@ private:
   // Returns true if we can play the entire media through without stopping
   // to buffer, given the current download and playback rates.
   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);
+  virtual void SetElementVisibility(bool aIsDocumentVisible,
+                                    bool aIsElementVisible);
 
   // Force override the visible state to hidden.
   // Called from HTMLMediaElement when testing of video decode suspend from mochitests.
   void SetForcedHidden(bool aForcedHidden);
 
   // Mark the decoder as tainted, meaning suspend-video-decoder is disabled.
   void SetSuspendTaint(bool aTaint);
 
@@ -711,18 +713,21 @@ protected:
   // True if the media is only seekable within its buffered ranges
   // like WebMs with no cues.
   bool mMediaSeekableOnlyInBufferedRanges = false;
 
   // 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;
+  // Tracks the visibility status of owner element's document.
+  bool mIsDocumentVisible;
+
+  // Tracks the visibliity status of owner element.
+  bool mIsElementVisible;
 
   // If true, forces the decoder to be considered hidden.
   bool mForcedHidden;
 
   // True if the decoder has a suspend taint - meaning suspend-video-decoder is
   // disabled.
   bool mHasSuspendTaint;