1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_HTMLVideoElement_h 8 #define mozilla_dom_HTMLVideoElement_h 9 10 #include "mozilla/Attributes.h" 11 #include "mozilla/dom/HTMLMediaElement.h" 12 #include "mozilla/StaticPrefs_media.h" 13 #include "Units.h" 14 15 namespace mozilla { 16 17 class FrameStatistics; 18 19 namespace dom { 20 21 class WakeLock; 22 class VideoPlaybackQuality; 23 24 class HTMLVideoElement final : public HTMLMediaElement { 25 class SecondaryVideoOutput; 26 27 public: 28 NS_DECL_ISUPPORTS_INHERITED 29 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLVideoElement, HTMLMediaElement) 30 31 typedef mozilla::dom::NodeInfo NodeInfo; 32 33 explicit HTMLVideoElement(already_AddRefed<NodeInfo>&& aNodeInfo); 34 35 NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLVideoElement, video) 36 37 using HTMLMediaElement::GetPaused; 38 39 void Invalidate(bool aImageSizeChanged, Maybe<nsIntSize>& aNewIntrinsicSize, 40 bool aForceInvalidate) override; 41 IsVideo()42 virtual bool IsVideo() const override { return true; } 43 44 virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute, 45 const nsAString& aValue, 46 nsIPrincipal* aMaybeScriptedPrincipal, 47 nsAttrValue& aResult) override; 48 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override; 49 50 virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() 51 const override; 52 53 virtual nsresult Clone(NodeInfo*, nsINode** aResult) const override; 54 55 virtual void UnbindFromTree(bool aNullParent = true) override; 56 57 mozilla::Maybe<mozilla::CSSIntSize> GetVideoSize() const; 58 59 virtual void UpdateMediaSize(const nsIntSize& aSize) override; 60 61 virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel) override; 62 63 // Element 64 virtual bool IsInteractiveHTMLContent() const override; 65 66 // WebIDL 67 Width()68 uint32_t Width() const { 69 return GetDimensionAttrAsUnsignedInt(nsGkAtoms::width, 0); 70 } 71 SetWidth(uint32_t aValue,ErrorResult & aRv)72 void SetWidth(uint32_t aValue, ErrorResult& aRv) { 73 SetUnsignedIntAttr(nsGkAtoms::width, aValue, 0, aRv); 74 } 75 Height()76 uint32_t Height() const { 77 return GetDimensionAttrAsUnsignedInt(nsGkAtoms::height, 0); 78 } 79 SetHeight(uint32_t aValue,ErrorResult & aRv)80 void SetHeight(uint32_t aValue, ErrorResult& aRv) { 81 SetUnsignedIntAttr(nsGkAtoms::height, aValue, 0, aRv); 82 } 83 VideoWidth()84 uint32_t VideoWidth() const { 85 if (mMediaInfo.HasVideo()) { 86 if (mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_90 || 87 mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_270) { 88 return mMediaInfo.mVideo.mDisplay.height; 89 } 90 return mMediaInfo.mVideo.mDisplay.width; 91 } 92 return 0; 93 } 94 VideoHeight()95 uint32_t VideoHeight() const { 96 if (mMediaInfo.HasVideo()) { 97 if (mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_90 || 98 mMediaInfo.mVideo.mRotation == VideoInfo::Rotation::kDegree_270) { 99 return mMediaInfo.mVideo.mDisplay.width; 100 } 101 return mMediaInfo.mVideo.mDisplay.height; 102 } 103 return 0; 104 } 105 RotationDegrees()106 VideoInfo::Rotation RotationDegrees() const { 107 return mMediaInfo.mVideo.mRotation; 108 } 109 HasAlpha()110 bool HasAlpha() const { return mMediaInfo.mVideo.HasAlpha(); } 111 GetPoster(nsAString & aValue)112 void GetPoster(nsAString& aValue) { 113 GetURIAttr(nsGkAtoms::poster, nullptr, aValue); 114 } SetPoster(const nsAString & aValue,ErrorResult & aRv)115 void SetPoster(const nsAString& aValue, ErrorResult& aRv) { 116 SetHTMLAttr(nsGkAtoms::poster, aValue, aRv); 117 } 118 119 uint32_t MozParsedFrames() const; 120 121 uint32_t MozDecodedFrames() const; 122 123 uint32_t MozPresentedFrames() const; 124 125 uint32_t MozPaintedFrames(); 126 127 double MozFrameDelay(); 128 129 bool MozHasAudio() const; 130 131 already_AddRefed<VideoPlaybackQuality> GetVideoPlaybackQuality(); 132 MozOrientationLockEnabled()133 bool MozOrientationLockEnabled() const { 134 return StaticPrefs::media_videocontrols_lock_video_orientation(); 135 } 136 MozIsOrientationLocked()137 bool MozIsOrientationLocked() const { return mIsOrientationLocked; } 138 SetMozIsOrientationLocked(bool aLock)139 void SetMozIsOrientationLocked(bool aLock) { mIsOrientationLocked = aLock; } 140 141 already_AddRefed<Promise> CloneElementVisually(HTMLVideoElement& aTarget, 142 ErrorResult& rv); 143 144 void StopCloningElementVisually(); 145 IsCloningElementVisually()146 bool IsCloningElementVisually() const { return !!mVisualCloneTarget; } 147 148 void OnSecondaryVideoContainerInstalled( 149 const RefPtr<VideoFrameContainer>& aSecondaryContainer) override; 150 151 void OnSecondaryVideoOutputFirstFrameRendered(); 152 153 protected: 154 virtual ~HTMLVideoElement(); 155 156 virtual JSObject* WrapNode(JSContext* aCx, 157 JS::Handle<JSObject*> aGivenProto) override; 158 159 /** 160 * We create video wakelock when the video is playing and release it when 161 * video pauses. Note, the actual platform wakelock will automatically be 162 * released when the page is in the background, so we don't need to check the 163 * video's visibility by ourselves. 164 */ 165 void WakeLockRelease() override; 166 void UpdateWakeLock() override; 167 168 bool ShouldCreateVideoWakeLock() const; 169 void CreateVideoWakeLockIfNeeded(); 170 void ReleaseVideoWakeLockIfExists(); 171 172 RefPtr<WakeLock> mScreenWakeLock; 173 174 bool mIsOrientationLocked; 175 176 WatchManager<HTMLVideoElement> mVideoWatchManager; 177 178 private: 179 bool SetVisualCloneTarget( 180 RefPtr<HTMLVideoElement> aVisualCloneTarget, 181 RefPtr<Promise> aVisualCloneTargetPromise = nullptr); 182 bool SetVisualCloneSource(RefPtr<HTMLVideoElement> aVisualCloneSource); 183 184 // For video elements, we can clone the frames being played to 185 // a secondary video element. If we're doing that, we hold a 186 // reference to the video element we're cloning to in 187 // mVisualCloneSource. 188 // 189 // Please don't set this to non-nullptr values directly - use 190 // SetVisualCloneTarget() instead. 191 RefPtr<HTMLVideoElement> mVisualCloneTarget; 192 // Set when mVisualCloneTarget is set, and resolved (and unset) when the 193 // secondary container has been applied to the underlying resource. 194 RefPtr<Promise> mVisualCloneTargetPromise; 195 // Set when beginning to clone visually and we are playing a MediaStream. 196 // This is the output wrapping the VideoFrameContainer of mVisualCloneTarget, 197 // so we can render its first frame, and resolve mVisualCloneTargetPromise as 198 // we do. 199 RefPtr<FirstFrameVideoOutput> mSecondaryVideoOutput; 200 // If this video is the clone target of another video element, 201 // then mVisualCloneSource points to that originating video 202 // element. 203 // 204 // Please don't set this to non-nullptr values directly - use 205 // SetVisualCloneTarget() instead. 206 RefPtr<HTMLVideoElement> mVisualCloneSource; 207 208 static void MapAttributesIntoRule(const nsMappedAttributes* aAttributes, 209 MappedDeclarations&); 210 211 static bool IsVideoStatsEnabled(); 212 double TotalPlayTime() const; 213 214 virtual void MaybeBeginCloningVisually() override; 215 void EndCloningVisually(); 216 }; 217 218 } // namespace dom 219 } // namespace mozilla 220 221 #endif // mozilla_dom_HTMLVideoElement_h 222