|  | // Copyright 2020 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_ENCODER_H_ | 
|  | #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_ENCODER_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <optional> | 
|  |  | 
|  | #include "base/containers/flat_map.h" | 
|  | #include "base/time/time.h" | 
|  | #include "media/base/video_codecs.h" | 
|  | #include "media/base/video_color_space.h" | 
|  | #include "media/base/video_encoder.h" | 
|  | #include "media/base/video_frame_pool.h" | 
|  | #include "media/video/video_encoder_info.h" | 
|  | #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" | 
|  | #include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_output_callback.h" | 
|  | #include "third_party/blink/renderer/modules/webcodecs/encoder_base.h" | 
|  | #include "third_party/blink/renderer/modules/webcodecs/hardware_preference.h" | 
|  | #include "third_party/blink/renderer/modules/webcodecs/video_frame.h" | 
|  | #include "ui/gfx/color_space.h" | 
|  |  | 
|  | namespace media { | 
|  | class GpuVideoAcceleratorFactories; | 
|  | class VideoEncoderMetricsProvider; | 
|  | class VideoEncoder; | 
|  | struct VideoEncoderOutput; | 
|  | }  // namespace media | 
|  |  | 
|  | namespace blink { | 
|  |  | 
|  | class VideoEncoderBuffer; | 
|  | class VideoEncoderConfig; | 
|  | class VideoEncoderInit; | 
|  | class VideoEncoderEncodeOptions; | 
|  | class VideoEncoderSupport; | 
|  | class WebGraphicsContext3DVideoFramePool; | 
|  | class BackgroundReadback; | 
|  |  | 
|  | class MODULES_EXPORT VideoEncoderTraits { | 
|  | public: | 
|  | struct ParsedConfig final : public GarbageCollected<ParsedConfig> { | 
|  | media::VideoCodec codec; | 
|  | media::VideoCodecProfile profile; | 
|  | uint8_t level; | 
|  |  | 
|  | HardwarePreference hw_pref; | 
|  |  | 
|  | media::VideoEncoder::Options options; | 
|  | String codec_string; | 
|  | std::optional<gfx::Size> display_size; | 
|  |  | 
|  | std::optional<String> not_supported_error_message; | 
|  |  | 
|  | String ToString(); | 
|  | void Trace(Visitor*) const {} | 
|  | }; | 
|  |  | 
|  | using Init = VideoEncoderInit; | 
|  | using Config = VideoEncoderConfig; | 
|  | using InternalConfig = ParsedConfig; | 
|  | using Input = VideoFrame; | 
|  | using EncodeOptions = VideoEncoderEncodeOptions; | 
|  | using OutputChunk = EncodedVideoChunk; | 
|  | using OutputCallback = V8EncodedVideoChunkOutputCallback; | 
|  | using MediaEncoder = media::VideoEncoder; | 
|  |  | 
|  | // Can't be a virtual method, because it's used from base ctor. | 
|  | static const char* GetName(); | 
|  | }; | 
|  |  | 
|  | class MODULES_EXPORT VideoEncoder : public EncoderBase<VideoEncoderTraits> { | 
|  | DEFINE_WRAPPERTYPEINFO(); | 
|  |  | 
|  | public: | 
|  | static VideoEncoder* Create(ScriptState*, | 
|  | const VideoEncoderInit*, | 
|  | ExceptionState&); | 
|  | VideoEncoder(ScriptState*, const VideoEncoderInit*, ExceptionState&); | 
|  | ~VideoEncoder() override; | 
|  |  | 
|  | static ScriptPromise<VideoEncoderSupport> | 
|  | isConfigSupported(ScriptState*, const VideoEncoderConfig*, ExceptionState&); | 
|  |  | 
|  | HeapVector<Member<VideoEncoderBuffer>> getAllFrameBuffers(ScriptState*, | 
|  | ExceptionState&); | 
|  |  | 
|  | // EventTarget interface | 
|  | const AtomicString& InterfaceName() const override; | 
|  |  | 
|  | // ScriptWrappable override. | 
|  | bool HasPendingActivity() const override; | 
|  |  | 
|  | // GarbageCollected override. | 
|  | void Trace(Visitor*) const override; | 
|  |  | 
|  | // If `is_error_message_from_software_codec` is true, `error_message` will be | 
|  | // updated to include `status.message()` if non-empty. | 
|  | void ReportError(const char* error_message, | 
|  | const media::EncoderStatus& status, | 
|  | bool is_error_message_from_software_codec); | 
|  |  | 
|  | std::unique_ptr<media::VideoEncoderMetricsProvider> encoder_metrics_provider_ | 
|  | GUARDED_BY_CONTEXT(sequence_checker_); | 
|  |  | 
|  | protected: | 
|  | using Base = EncoderBase<VideoEncoderTraits>; | 
|  | using ParsedConfig = VideoEncoderTraits::ParsedConfig; | 
|  |  | 
|  | void OnMediaEncoderInfoChanged(const media::VideoEncoderInfo& encoder_info); | 
|  | void CallOutputCallback( | 
|  | ParsedConfig* active_config, | 
|  | uint32_t reset_count, | 
|  | media::VideoEncoderOutput output, | 
|  | std::optional<media::VideoEncoder::CodecDescription> codec_desc); | 
|  | bool ReadyToProcessNextRequest() override; | 
|  | void ProcessEncode(Request* request) override; | 
|  | void ProcessConfigure(Request* request) override; | 
|  | void ProcessReconfigure(Request* request) override; | 
|  | void ResetInternal(DOMException* ex) override; | 
|  | void OnNewEncode(VideoFrame* input, ExceptionState& exception_state) override; | 
|  |  | 
|  | void OnEncodeDone(Request* request, media::EncoderStatus status); | 
|  | media::VideoEncoder::EncodeOptions CreateEncodeOptions(Request* request); | 
|  | // This will execute shortly after the async readback completes. | 
|  | void OnReadbackDone(Request* request, | 
|  | scoped_refptr<media::VideoFrame> txt_frame, | 
|  | media::VideoEncoder::EncoderStatusCB done_callback, | 
|  | scoped_refptr<media::VideoFrame> result_frame); | 
|  | static media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>> | 
|  | CreateSoftwareVideoEncoder(VideoEncoder* self, | 
|  | bool fallback, | 
|  | media::VideoCodec codec); | 
|  |  | 
|  | ParsedConfig* OnNewConfigure(const VideoEncoderConfig*, | 
|  | ExceptionState&) override; | 
|  | bool VerifyCodecSupport(ParsedConfig*, String* js_error_message) override; | 
|  |  | 
|  | // Virtual for UTs. | 
|  | // Returns the VideoEncoder. | 
|  | virtual media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>> | 
|  | CreateMediaVideoEncoder(const ParsedConfig& config, | 
|  | media::GpuVideoAcceleratorFactories* gpu_factories, | 
|  | bool& is_platform_encoder); | 
|  | virtual std::unique_ptr<media::VideoEncoderMetricsProvider> | 
|  | CreateVideoEncoderMetricsProvider() const; | 
|  |  | 
|  | void ContinueConfigureWithGpuFactories( | 
|  | Request* request, | 
|  | media::GpuVideoAcceleratorFactories* gpu_factories); | 
|  | void ContinueConfigureAfterFlush(Request* request); | 
|  | media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>> | 
|  | CreateAcceleratedVideoEncoder( | 
|  | media::VideoCodecProfile profile, | 
|  | const media::VideoEncoder::Options& options, | 
|  | media::GpuVideoAcceleratorFactories* gpu_factories, | 
|  | HardwarePreference hw_pref); | 
|  | bool CanReconfigure(ParsedConfig& original_config, | 
|  | ParsedConfig& new_config) override; | 
|  |  | 
|  | using ReadbackDoneCallback = | 
|  | base::OnceCallback<void(scoped_refptr<media::VideoFrame>)>; | 
|  | bool StartReadback(scoped_refptr<media::VideoFrame> frame, | 
|  | ReadbackDoneCallback result_cb); | 
|  |  | 
|  | std::unique_ptr<WebGraphicsContext3DVideoFramePool> accelerated_frame_pool_; | 
|  | Member<BackgroundReadback> background_readback_; | 
|  |  | 
|  | // True if an error occurs during frame pool usage. | 
|  | bool disable_accelerated_frame_pool_ = false; | 
|  |  | 
|  | // The number of encoding requests currently handled by |media_encoder_| | 
|  | // Should not exceed |max_active_encodes_|. | 
|  | int active_encodes_ = 0; | 
|  |  | 
|  | // The current upper limit on |active_encodes_|. | 
|  | int max_active_encodes_; | 
|  |  | 
|  | // True if a running video encoder is hardware accelerated. | 
|  | bool is_platform_encoder_ = false; | 
|  |  | 
|  | // Per-frame metadata to be applied to outputs, linked by timestamp. | 
|  | struct FrameMetadata { | 
|  | base::TimeDelta duration; | 
|  | media::VideoTransformation transformation; | 
|  | }; | 
|  | base::flat_map<base::TimeDelta, FrameMetadata> frame_metadata_; | 
|  |  | 
|  | // Buffers returned by getAllFrameBuffers() | 
|  | HeapVector<Member<VideoEncoderBuffer>> frame_reference_buffers_; | 
|  |  | 
|  | // The color space corresponding to the last emitted output. Used to update | 
|  | // emitted VideoDecoderConfig when necessary. | 
|  | gfx::ColorSpace last_output_color_space_; | 
|  |  | 
|  | // The transformation corresponding to the last input received by | 
|  | // ProcessEncode(). Used to request a key frame. | 
|  | std::optional<media::VideoTransformation> first_input_transformation_; | 
|  |  | 
|  | // Latest VideoEncoderInfo reported by encoder | 
|  | media::VideoEncoderInfo encoder_info_; | 
|  | }; | 
|  |  | 
|  | }  // namespace blink | 
|  |  | 
|  | #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_VIDEO_ENCODER_H_ |