nsVideoFrame.h (5465B)
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 /* rendering object for the HTML <video> element */ 8 9 #ifndef nsVideoFrame_h___ 10 #define nsVideoFrame_h___ 11 12 #include "nsContainerFrame.h" 13 #include "nsIAnonymousContentCreator.h" 14 #include "nsIReflowCallback.h" 15 #include "nsStringFwd.h" 16 #include "nsTArrayForwardDeclare.h" 17 18 class nsPresContext; 19 class nsDisplayItem; 20 21 class nsVideoFrame : public nsContainerFrame, 22 public nsIReflowCallback, 23 public nsIAnonymousContentCreator { 24 public: 25 template <typename T> 26 using Maybe = mozilla::Maybe<T>; 27 using Nothing = mozilla::Nothing; 28 using Visibility = mozilla::Visibility; 29 30 nsVideoFrame(ComputedStyle* aStyle, nsPresContext* aPc) 31 : nsVideoFrame(aStyle, aPc, kClassID) {} 32 nsVideoFrame(ComputedStyle*, nsPresContext*, ClassID); 33 34 NS_DECL_QUERYFRAME 35 NS_DECL_FRAMEARENA_HELPERS(nsVideoFrame) 36 37 void ReflowCallbackCanceled() final { mReflowCallbackPosted = false; } 38 bool ReflowFinished() final; 39 40 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 41 const nsDisplayListSet& aLists) final; 42 43 nsresult AttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, 44 AttrModType aModType) final; 45 46 void OnVisibilityChange( 47 Visibility aNewVisibility, 48 const Maybe<OnNonvisible>& aNonvisibleAction = Nothing()) final; 49 50 /* get the size of the video's display */ 51 mozilla::IntrinsicSize GetIntrinsicSize() final; 52 mozilla::IntrinsicSize GetIntrinsicSize(bool aIgnoreContainment) const; 53 mozilla::AspectRatio GetIntrinsicRatio() const final; 54 mozilla::AspectRatio GetIntrinsicRatio(bool aIgnoreContainment) const; 55 SizeComputationResult ComputeSize( 56 const SizeComputationInput& aSizingInput, mozilla::WritingMode aWM, 57 const mozilla::LogicalSize& aCBSize, nscoord aAvailableISize, 58 const mozilla::LogicalSize& aMargin, 59 const mozilla::LogicalSize& aBorderPadding, 60 const mozilla::StyleSizeOverrides& aSizeOverrides, 61 mozilla::ComputeSizeFlags aFlags) final; 62 63 nscoord IntrinsicISize(const mozilla::IntrinsicSizeInput& aInput, 64 mozilla::IntrinsicISizeType aType) final; 65 66 nsRect GetDestRect(const nsRect& aContentBox) const; 67 68 void Destroy(DestroyContext&) final; 69 70 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 71 const ReflowInput& aReflowInput, nsReflowStatus& aStatus) final; 72 73 #ifdef ACCESSIBILITY 74 mozilla::a11y::AccType AccessibleType() final; 75 #endif 76 77 nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) final; 78 void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, 79 uint32_t aFilters) final; 80 81 mozilla::dom::Element* GetPosterImage() const { return mPosterImage; } 82 83 // Returns true if we should display the poster. Note that once we show 84 // a video frame, the poster will never be displayed again. 85 bool ShouldDisplayPoster() const; 86 87 nsIContent* GetCaptionOverlay() const { return mCaptionDiv; } 88 nsIContent* GetVideoControls() const; 89 90 #ifdef DEBUG_FRAME_DUMP 91 nsresult GetFrameName(nsAString& aResult) const override; 92 #endif 93 94 protected: 95 // Returns true if we're rendering for a video element. We create an 96 // nsAudioFrame (which is still an nsVideoFrame) to render controls for an 97 // audio element. 98 bool HasVideoElement() const { return !mIsAudio; } 99 100 // Returns true if there is video data to render. Can return false 101 // when we're the frame for an audio element, or we've created a video 102 // element for a media which is audio-only. 103 bool HasVideoData() const; 104 105 // Get the poster image's size if there is any. 106 mozilla::Maybe<nsSize> PosterImageSize() const; 107 108 // Sets the mPosterImage's src attribute to be the video's poster attribute, 109 // if we're the frame for a video element. Only call on frames for video 110 // elements, not for frames for audio elements. 111 void UpdatePosterSource(bool aNotify); 112 113 // Notify the mediaElement that the mCaptionDiv was created. 114 void UpdateTextTrack(); 115 116 virtual ~nsVideoFrame(); 117 118 // Anonymous child which is the image element of the poster frame. 119 RefPtr<mozilla::dom::Element> mPosterImage; 120 121 // Anonymous child which is the text track caption display div. 122 nsCOMPtr<nsIContent> mCaptionDiv; 123 124 // Some sizes tracked for notification purposes. 125 // TODO: Maybe the calling code could be rewritten to use ResizeObserver for 126 // this nowadays. 127 nsSize mControlsTrackedSize{-1, -1}; 128 nsSize mCaptionTrackedSize{-1, -1}; 129 bool mReflowCallbackPosted = false; 130 const bool mIsAudio; 131 }; 132 133 // NOTE(emilio): This class here only for the purpose of having different 134 // ClassFlags for <audio> elements. This frame shouldn't contain extra logic, as 135 // things are set up now, because <audio> can also use video controls etc. 136 // In the future we might want to rejigger this to be less weird (e.g, an audio 137 // frame might not need a caption, or text tracks, or what not). 138 class nsAudioFrame final : public nsVideoFrame { 139 public: 140 NS_DECL_QUERYFRAME 141 NS_DECL_FRAMEARENA_HELPERS(nsAudioFrame) 142 143 nsAudioFrame(ComputedStyle*, nsPresContext*); 144 virtual ~nsAudioFrame(); 145 }; 146 147 #endif /* nsVideoFrame_h___ */