Bug 1521964 - Add privileged HTMLVideoElement.cloneElementVisually WebIDL method. r=jya,Ehsan,smaug

Differential Revision: https://phabricator.services.mozilla.com/D20023

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mike Conley 2019-03-01 22:36:40 +00:00
Родитель 38db7d8e61
Коммит 59c1141de6
5 изменённых файлов: 131 добавлений и 3 удалений

Просмотреть файл

@ -2056,6 +2056,7 @@ void HTMLMediaElement::ResetState() {
void HTMLMediaElement::SelectResourceWrapper() {
SelectResource();
MaybeBeginCloningVisually();
mIsRunningSelectResource = false;
mHaveQueuedSelectResource = false;
mIsDoingExplicitLoad = false;
@ -2183,6 +2184,7 @@ void HTMLMediaElement::NotifyMediaTrackEnabled(MediaTrack* aTrack) {
VideoFrameContainer* container = GetVideoFrameContainer();
if (mSrcStreamIsPlaying && container) {
mSelectedVideoStreamTrack->AddVideoOutput(container);
MaybeBeginCloningVisually();
}
HTMLVideoElement* self = static_cast<HTMLVideoElement*>(this);
if (self->VideoWidth() <= 1 && self->VideoHeight() <= 1) {
@ -4591,6 +4593,8 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder) {
}
}
MaybeBeginCloningVisually();
return NS_OK;
}
@ -4681,6 +4685,7 @@ void HTMLMediaElement::UpdateSrcMediaStreamPlaying(uint32_t aFlags) {
VideoFrameContainer* container = GetVideoFrameContainer();
if (mSelectedVideoStreamTrack && container) {
mSelectedVideoStreamTrack->AddVideoOutput(container);
MaybeBeginCloningVisually();
}
SetCapturedOutputStreamsEnabled(true); // Unmute

Просмотреть файл

@ -298,7 +298,7 @@ class HTMLMediaElement : public nsGenericHTMLElement,
// Update the visual size of the media. Called from the decoder on the
// main thread when/if the size changes.
void UpdateMediaSize(const nsIntSize& aSize);
virtual void UpdateMediaSize(const nsIntSize& aSize);
// Like UpdateMediaSize, but only updates the size if no size has yet
// been set.
void UpdateInitialMediaSize(const nsIntSize& aSize);
@ -1720,6 +1720,8 @@ class HTMLMediaElement : public nsGenericHTMLElement,
void UpdateHadAudibleAutoplayState();
virtual void MaybeBeginCloningVisually(){};
/**
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
* It will not be called if the value is being unset.

Просмотреть файл

@ -25,12 +25,14 @@
#include "FrameStatistics.h"
#include "MediaError.h"
#include "MediaDecoder.h"
#include "MediaDecoderStateMachine.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/TimeRanges.h"
#include "mozilla/dom/VideoPlaybackQuality.h"
#include "mozilla/dom/VideoStreamTrack.h"
#include <algorithm>
#include <limits>
@ -66,8 +68,22 @@ nsresult HTMLVideoElement::Clone(mozilla::dom::NodeInfo* aNodeInfo,
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(HTMLVideoElement,
HTMLMediaElement)
NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLVideoElement, HTMLMediaElement,
mVisualCloneTarget, mVisualCloneSource)
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLVideoElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLVideoElement,
HTMLMediaElement)
if (tmp->mVisualCloneTarget) {
tmp->EndCloningVisually();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVisualCloneTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVisualCloneSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLVideoElement,
HTMLMediaElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVisualCloneTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVisualCloneSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
HTMLVideoElement::HTMLVideoElement(already_AddRefed<NodeInfo>&& aNodeInfo)
: HTMLMediaElement(std::move(aNodeInfo)), mIsOrientationLocked(false) {
@ -78,6 +94,15 @@ HTMLVideoElement::~HTMLVideoElement() {
DecoderDoctorLogger::LogDestruction(this);
}
void HTMLVideoElement::UpdateMediaSize(const nsIntSize& aSize) {
HTMLMediaElement::UpdateMediaSize(aSize);
// If we have a clone target, we should update its size as well.
if (mVisualCloneTarget) {
Maybe<nsIntSize> newSize = Some(aSize);
mVisualCloneTarget->Invalidate(true, newSize, true);
}
}
nsresult HTMLVideoElement::GetVideoSize(nsIntSize* size) {
if (!mMediaInfo.HasVideo()) {
return NS_ERROR_FAILURE;
@ -139,6 +164,18 @@ nsMapRuleToAttributesFunc HTMLVideoElement::GetAttributeMappingFunction()
return &MapAttributesIntoRule;
}
void HTMLVideoElement::UnbindFromTree(bool aDeep, bool aNullParent) {
if (mVisualCloneSource) {
mVisualCloneSource->EndCloningVisually();
SetVisualCloneSource(nullptr);
} else if (mVisualCloneTarget) {
mVisualCloneTarget->SetVisualCloneSource(nullptr);
EndCloningVisually();
}
HTMLMediaElement::UnbindFromTree(aDeep, aNullParent);
}
nsresult HTMLVideoElement::SetAcceptHeader(nsIHttpChannel* aChannel) {
nsAutoCString value(
"video/webm,"
@ -396,5 +433,73 @@ double HTMLVideoElement::TotalPlayTime() const {
return total;
}
void HTMLVideoElement::CloneElementVisually(HTMLVideoElement& aTargetVideo,
ErrorResult& rv) {
MOZ_ASSERT(!mUnboundFromTree,
"Can't clone a video that's not bound to a DOM tree.");
MOZ_ASSERT(!aTargetVideo.mUnboundFromTree,
"Can't clone to a video that's not bound to a DOM tree.");
if (mUnboundFromTree || aTargetVideo.mUnboundFromTree) {
rv.Throw(NS_ERROR_UNEXPECTED);
return;
}
if (!SetVisualCloneTarget(&aTargetVideo)) {
rv.Throw(NS_ERROR_FAILURE);
return;
}
if (!aTargetVideo.SetVisualCloneSource(this)) {
mVisualCloneTarget = nullptr;
rv.Throw(NS_ERROR_FAILURE);
return;
}
aTargetVideo.SetMediaInfo(mMediaInfo);
MaybeBeginCloningVisually();
}
void HTMLVideoElement::MaybeBeginCloningVisually() {
if (!mVisualCloneTarget) {
return;
}
if (mDecoder) {
MediaDecoderStateMachine* mdsm = mDecoder->GetStateMachine();
VideoFrameContainer* container =
mVisualCloneTarget->GetVideoFrameContainer();
if (mdsm && container) {
mdsm->SetSecondaryVideoContainer(container);
}
} else if (mSrcStream) {
VideoFrameContainer* container =
mVisualCloneTarget->GetVideoFrameContainer();
if (container && mSelectedVideoStreamTrack) {
mSelectedVideoStreamTrack->AddVideoOutput(container);
}
}
}
void HTMLVideoElement::EndCloningVisually() {
MOZ_ASSERT(mVisualCloneTarget);
if (mDecoder) {
MediaDecoderStateMachine* mdsm = mDecoder->GetStateMachine();
if (mdsm) {
mdsm->SetSecondaryVideoContainer(nullptr);
}
} else if (mSrcStream) {
VideoFrameContainer* container =
mVisualCloneTarget->GetVideoFrameContainer();
if (container && mVisualCloneTarget->mSelectedVideoStreamTrack) {
mVisualCloneTarget->mSelectedVideoStreamTrack->RemoveVideoOutput(
container);
}
}
mVisualCloneTarget = nullptr;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -48,10 +48,15 @@ class HTMLVideoElement final : public HTMLMediaElement {
virtual nsresult Clone(NodeInfo*, nsINode** aResult) const override;
virtual void UnbindFromTree(bool aDeep = true,
bool aNullParent = true) override;
// Set size with the current video frame's height and width.
// If there is no video frame, returns NS_ERROR_FAILURE.
nsresult GetVideoSize(nsIntSize* size);
virtual void UpdateMediaSize(const nsIntSize& aSize) override;
virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) override;
// Element
@ -129,6 +134,8 @@ class HTMLVideoElement final : public HTMLMediaElement {
void SetMozIsOrientationLocked(bool aLock) { mIsOrientationLocked = aLock; }
void CloneElementVisually(HTMLVideoElement& aTarget, ErrorResult& rv);
protected:
virtual ~HTMLVideoElement();
@ -177,6 +184,9 @@ class HTMLVideoElement final : public HTMLMediaElement {
static bool IsVideoStatsEnabled();
double TotalPlayTime() const;
virtual void MaybeBeginCloningVisually() override;
void EndCloningVisually();
};
} // namespace dom

Просмотреть файл

@ -53,6 +53,12 @@ partial interface HTMLVideoElement {
// True if screen orientation is locked by video controls.
[Pref="media.videocontrols.lock-video-orientation", Func="IsChromeOrXBLOrUAWidget"]
attribute boolean mozIsOrientationLocked;
// Clones the frames playing in this <video> to the target. Cloning
// when either node is removed from their DOM trees. Throws if one or
// both <video> elements are not attached to a DOM tree.
[Throws, Func="IsChromeOrXBLOrUAWidget"]
void cloneElementVisually(HTMLVideoElement target);
};
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#idl-def-HTMLVideoElement