зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
38db7d8e61
Коммит
59c1141de6
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче