/* * Copyright (c) 2020, the SerenityOS developers. * Copyright (c) 2026, Gregory Bertilson * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace Web::HTML { struct VideoFrame { RefPtr frame; double position { 0.0 }; }; class HTMLVideoElement final : public HTMLMediaElement { WEB_PLATFORM_OBJECT(HTMLVideoElement, HTMLMediaElement); GC_DECLARE_ALLOCATOR(HTMLVideoElement); public: static constexpr bool OVERRIDES_FINALIZE = true; virtual ~HTMLVideoElement() override; Layout::VideoBox* layout_node(); Layout::VideoBox const* layout_node() const; void set_video_width(u32 video_width) { m_video_width = video_width; } u32 video_width() const; void set_video_height(u32 video_height) { m_video_height = video_height; } u32 video_height() const; RefPtr const& poster_frame() const { return m_poster_frame; } // https://html.spec.whatwg.org/multipage/media.html#the-video-element:the-video-element-7 // NB: We combine the values of... // - The last frame of the video to have been rendered // - The frame of video corresponding to the current playback position // ...into the value of VideoFrame below, as the playback system itself implements // the details of the selection of a video frame to match the specification in this // respect. enum class Representation : u8 { VideoFrame, FirstVideoFrame, PosterFrame, TransparentBlack, }; Representation current_representation() const; // FIXME: This is a hack for images used as CanvasImageSource. Do something more elegant. RefPtr bitmap() const; private: HTMLVideoElement(DOM::Document&, DOM::QualifiedName); virtual void initialize(JS::Realm&) override; virtual void finalize() override; virtual void visit_edges(Cell::Visitor&) override; virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value, Optional const& namespace_) override; // https://html.spec.whatwg.org/multipage/media.html#the-video-element:dimension-attributes virtual bool supports_dimension_attributes() const override { return true; } virtual GC::Ptr create_layout_node(GC::Ref) override; WebIDL::ExceptionOr determine_element_poster_frame(Optional const& poster); GC::Ptr m_video_track; VideoFrame m_current_frame; RefPtr m_poster_frame; u32 m_video_width { 0 }; u32 m_video_height { 0 }; GC::Ptr m_fetch_controller; Optional m_load_event_delayer; }; }