From 93f2cee949fc230fd33b8b08495b18bbb63cd3a9 Mon Sep 17 00:00:00 2001 From: Kaku Kuo Date: Wed, 8 Mar 2017 19:41:08 +0800 Subject: [PATCH] Bug 1345403 part 2 - Mark element tainted when DrawImage is used; r=jwwang,mattwoodrow Mark video element as tainted (stored on the decoder owned by video element) when the video is used as source to drawImage() on canvas. MozReview-Commit-ID: HdciVwhqPu3 --HG-- extra : rebase_source : 79e1bbdc671abb8555d68f7fb6106929c45fd528 extra : intermediate-source : 47fbcedbed69a5434b1cb25b8f72f862e9cefeac extra : source : 149234329b62015dfd2e954030c23bf9c6b1d55e --- dom/html/HTMLMediaElement.cpp | 23 +++++++++++++++++++++++ dom/html/HTMLMediaElement.h | 12 ++++++++++++ layout/base/nsLayoutUtils.cpp | 7 +------ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index b3e1d32f4f1e..3844057dbfe4 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -1527,6 +1527,26 @@ HTMLMediaElement::SetVisible(bool aVisible) mDecoder->SetForcedHidden(!aVisible); } +layers::Image* +HTMLMediaElement::GetCurrentImage() +{ + // Mark the decoder owned by the element as tainted so that the + // suspend-vide-decoder is suspended. + mHasSuspendTaint = true; + if (mDecoder) { + mDecoder->SetSuspendTaint(true); + } + + // TODO: In bug 1345404, handle case when video decoder is already suspended. + ImageContainer* container = GetImageContainer(); + if (!container) { + return nullptr; + } + + AutoLockImage lockImage(container); + return lockImage.GetImage(); +} + already_AddRefed HTMLMediaElement::GetSrcObject() const { @@ -3692,6 +3712,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNo mFirstFrameLoaded(false), mDefaultPlaybackStartPosition(0.0), mIsAudioTrackAudible(false), + mHasSuspendTaint(false), mVisibilityState(Visibility::APPROXIMATELY_NONVISIBLE), mErrorSink(new ErrorSink(this)), mAudioChannelWrapper(new AudioChannelAgentCallback(this, mAudioChannel)) @@ -4689,6 +4710,8 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder, if (mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) { mDecoder->SetMinimizePrerollUntilPlaybackStarts(); } + // Notify the decoder of suspend taint. + mDecoder->SetSuspendTaint(mHasSuspendTaint); // Update decoder principal before we start decoding, since it // can affect how we feed data to MediaStreams diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index 8fcc16c7ce78..0673ba78cc60 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -619,6 +619,14 @@ public: void SetVisible(bool aVisible); + // Synchronously, return the next video frame and mark the element unable to + // participate in decode suspending. + // + // This function is synchronous for cases where decoding has been suspended + // and JS needs a frame to use in, eg., nsLayoutUtils::SurfaceFromElement() + // via drawImage(). + layers::Image* GetCurrentImage(); + already_AddRefed GetSrcObject() const; void SetSrcObject(DOMMediaStream& aValue); void SetSrcObject(DOMMediaStream* aValue); @@ -1714,6 +1722,10 @@ private: // True if the audio track is not silent. bool mIsAudioTrackAudible; + // True if media element has been marked as 'tainted' and can't + // participate in video decoder suspending. + bool mHasSuspendTaint; + Visibility mVisibilityState; UniquePtr mErrorSink; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 5d29e78ed46e..e4dcc4669bcd 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -7364,13 +7364,8 @@ nsLayoutUtils::SurfaceFromElement(HTMLVideoElement* aElement, if (!principal) return result; - ImageContainer* container = aElement->GetImageContainer(); - if (!container) - return result; + result.mLayersImage = aElement->GetCurrentImage(); - AutoLockImage lockImage(container); - - result.mLayersImage = lockImage.GetImage(); if (!result.mLayersImage) return result;