#pragma once #include #include #include #include #include #include #include #include namespace aethera::web { enum struct Video_Pixel_Layout : std::uint8_t { bgra, rgba }; enum struct Video_Encoder_Backend : std::uint8_t { libx264 }; [[nodiscard]] std::string_view video_encoder_backend_name( Video_Encoder_Backend backend) noexcept; [[nodiscard]] std::string_view h264_profile_level_id() noexcept; struct Encoded_Video_Frame { std::vector annex_b{}; /* 带起始码的完整 H.264 access unit,可直接交给 RTP packetizer。 */ std::chrono::microseconds presentation_time{}; /* 从 Plot 帧时钟起点累计的媒体时间戳。 */ std::uint64_t sequence{}; /* 对应 Render_Frame 的单调序号。 */ Video_Encoder_Backend backend{Video_Encoder_Backend::libx264}; /* 实际产生本 access unit 的 FFmpeg 后端。 */ bool key_frame{}; /* 本 access unit 是否可独立解码。 */ }; struct H264_Encoder final { public: explicit H264_Encoder(double frame_rate); ~H264_Encoder(); H264_Encoder(const H264_Encoder&) = delete; H264_Encoder& operator=(const H264_Encoder&) = delete; void request_key_frame(); [[nodiscard]] std::optional encode( std::span pixels, std::uint32_t width, std::uint32_t height, Video_Pixel_Layout layout, std::uint64_t sequence, std::chrono::microseconds presentation_time); private: struct Private; std::unique_ptr d; }; }