Bug 1521964 - Don't suspend the video decoder when cloning a video visually. r=jya
authorMike Conley <mconley@mozilla.com>
Fri, 01 Mar 2019 22:36:53 +0000
changeset 519922 e5e08269a5467ad0d8653645318a9d7a04954073
parent 519921 45807d96ca7f5378567115595b98db0d2f3cd0bc
child 519923 122c7fc5d9c5517b168345e36a822bf5c17d6d3d
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1521964
milestone67.0a1
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
Bug 1521964 - Don't suspend the video decoder when cloning a video visually. r=jya Differential Revision: https://phabricator.services.mozilla.com/D20674
dom/html/HTMLVideoElement.cpp
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
--- a/dom/html/HTMLVideoElement.cpp
+++ b/dom/html/HTMLVideoElement.cpp
@@ -466,16 +466,17 @@ void HTMLVideoElement::MaybeBeginCloning
   }
 
   if (mDecoder) {
     MediaDecoderStateMachine* mdsm = mDecoder->GetStateMachine();
     VideoFrameContainer* container =
         mVisualCloneTarget->GetVideoFrameContainer();
     if (mdsm && container) {
       mdsm->SetSecondaryVideoContainer(container);
+      mDecoder->SetCloningVisually(true);
     }
   } else if (mSrcStream) {
     VideoFrameContainer* container =
         mVisualCloneTarget->GetVideoFrameContainer();
     if (container && mSelectedVideoStreamTrack) {
       mSelectedVideoStreamTrack->AddVideoOutput(container);
     }
   }
@@ -483,16 +484,17 @@ void HTMLVideoElement::MaybeBeginCloning
 
 void HTMLVideoElement::EndCloningVisually() {
   MOZ_ASSERT(mVisualCloneTarget);
 
   if (mDecoder) {
     MediaDecoderStateMachine* mdsm = mDecoder->GetStateMachine();
     if (mdsm) {
       mdsm->SetSecondaryVideoContainer(nullptr);
+      mDecoder->SetCloningVisually(false);
     }
   } else if (mSrcStream) {
     VideoFrameContainer* container =
         mVisualCloneTarget->GetVideoFrameContainer();
     if (container && mVisualCloneTarget->mSelectedVideoStreamTrack) {
       mVisualCloneTarget->mSelectedVideoStreamTrack->RemoveVideoOutput(
           container);
     }
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -300,16 +300,17 @@ MediaDecoder::MediaDecoder(MediaDecoderI
       mVideoFrameContainer(aInit.mOwner->GetVideoFrameContainer()),
       mMinimizePreroll(aInit.mMinimizePreroll),
       mFiredMetadataLoaded(false),
       mIsDocumentVisible(false),
       mElementVisibility(Visibility::UNTRACKED),
       mIsElementInTree(false),
       mForcedHidden(false),
       mHasSuspendTaint(aInit.mHasSuspendTaint),
+      mIsCloningVisually(false),
       mPlaybackRate(aInit.mPlaybackRate),
       mLogicallySeeking(false, "MediaDecoder::mLogicallySeeking"),
       INIT_MIRROR(mBuffered, TimeIntervals()),
       INIT_MIRROR(mCurrentPosition, TimeUnit::Zero()),
       INIT_MIRROR(mStateMachineDuration, NullableTimeUnit()),
       INIT_MIRROR(mIsAudioDataAudible, false),
       INIT_CANONICAL(mVolume, aInit.mVolume),
       INIT_CANONICAL(mPreservesPitch, aInit.mPreservesPitch),
@@ -983,16 +984,24 @@ void MediaDecoder::UpdateVideoDecodeMode
   // If mHasSuspendTaint is set, never suspend the video decoder.
   if (mHasSuspendTaint) {
     LOG("UpdateVideoDecodeMode(), set Normal because the element has been "
         "tainted.");
     mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
     return;
   }
 
+  // If mIsCloningVisually is set, never suspend the video decoder.
+  if (mIsCloningVisually) {
+    LOG("UpdateVideoDecodeMode(), set Normal because the element is cloning "
+        "itself visually to another video container.");
+    mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
+    return;
+  }
+
   // Don't suspend elements that is not in tree.
   if (!mIsElementInTree) {
     LOG("UpdateVideoDecodeMode(), set Normal because the element is not in "
         "tree.");
     mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
     return;
   }
 
@@ -1041,16 +1050,23 @@ void MediaDecoder::SetIsBackgroundVideoD
   UpdateVideoDecodeMode();
 }
 
 bool MediaDecoder::HasSuspendTaint() const {
   MOZ_ASSERT(NS_IsMainThread());
   return mHasSuspendTaint;
 }
 
+void MediaDecoder::SetCloningVisually(bool aIsCloningVisually) {
+  if (mIsCloningVisually != aIsCloningVisually) {
+    mIsCloningVisually = aIsCloningVisually;
+    UpdateVideoDecodeMode();
+  }
+}
+
 bool MediaDecoder::IsMediaSeekable() {
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE(GetStateMachine(), false);
   return mMediaSeekable;
 }
 
 media::TimeIntervals MediaDecoder::GetSeekable() {
   MOZ_ASSERT(NS_IsMainThread());
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -303,16 +303,18 @@ class MediaDecoder : public DecoderDocto
   void SetForcedHidden(bool aForcedHidden);
 
   // Mark the decoder as tainted, meaning suspend-video-decoder is disabled.
   void SetSuspendTaint(bool aTaint);
 
   // Returns true if the decoder can't participate in suspend-video-decoder.
   bool HasSuspendTaint() const;
 
+  void SetCloningVisually(bool aIsCloningVisually);
+
   void UpdateVideoDecodeMode();
 
   void SetIsBackgroundVideoDecodingAllowed(bool aAllowed);
 
   bool IsVideoDecodingSuspended() const;
 
   /******
    * The following methods must only be called on the main
@@ -557,16 +559,20 @@ class MediaDecoder : public DecoderDocto
 
   // 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;
 
+  // True if the decoder is sending video to a secondary container, and should
+  // not suspend the decoder.
+  bool mIsCloningVisually;
+
   MediaDecoderOwner::NextFrameStatus mNextFrameStatus =
       MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
 
   // A listener to receive metadata updates from MDSM.
   MediaEventListener mTimedMetadataListener;
 
   MediaEventListener mMetadataLoadedListener;
   MediaEventListener mFirstFrameLoadedListener;