#include "third_party/blink/renderer/modules/webcodecs/video_encoder.h"
#include <algorithm>
#include <string>
#include "base/containers/contains.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/clamped_math.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/trace_event/common/trace_event_common.h"
#include "base/trace_event/trace_event.h"
#include "components/viz/common/gpu/raster_context_provider.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/raster_interface.h"
#include "media/base/async_destroy_video_encoder.h"
#include "media/base/limits.h"
#include "media/base/media_log.h"
#include "media/base/mime_util.h"
#include "media/base/svc_scalability_mode.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
#include "media/base/video_encoder.h"
#include "media/base/video_util.h"
#include "media/media_buildflags.h"
#include "media/mojo/clients/mojo_video_encoder_metrics_provider.h"
#include "media/parsers/h264_level_limits.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "media/video/offloading_video_encoder.h"
#include "media/video/video_encode_accelerator_adapter.h"
#include "media/video/video_encoder_fallback.h"
#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h"
#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_traits.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_avc_encoder_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_metadata.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_hevc_encoder_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options_for_av_1.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options_for_avc.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_encode_options_for_vp_9.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_support.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_video_pixel_format.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/streams/readable_stream.h"
#include "third_party/blink/renderer/core/streams/writable_stream.h"
#include "third_party/blink/renderer/modules/event_modules.h"
#include "third_party/blink/renderer/modules/webcodecs/array_buffer_util.h"
#include "third_party/blink/renderer/modules/webcodecs/background_readback.h"
#include "third_party/blink/renderer/modules/webcodecs/codec_state_helper.h"
#include "third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.h"
#include "third_party/blink/renderer/modules/webcodecs/gpu_factories_retriever.h"
#include "third_party/blink/renderer/modules/webcodecs/video_color_space.h"
#include "third_party/blink/renderer/modules/webcodecs/video_encoder_buffer.h"
#include "third_party/blink/renderer/platform/bindings/enumeration_base.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_video_frame_pool.h"
#include "third_party/blink/renderer/platform/heap/cross_thread_handle.h"
#include "third_party/blink/renderer/platform/heap/heap_barrier_callback.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_base.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#if BUILDFLAG(ENABLE_LIBAOM)
#include "media/video/av1_video_encoder.h"
#endif
#if BUILDFLAG(ENABLE_OPENH264)
#include "media/video/openh264_video_encoder.h"
#endif
#if BUILDFLAG(ENABLE_LIBVPX)
#include "media/video/vpx_video_encoder.h"
#endif
namespace WTF {
template <>
struct CrossThreadCopier<media::EncoderStatus>
: public CrossThreadCopierPassThrough<media::EncoderStatus> { … };
}
namespace blink {
EncoderType;
namespace {
constexpr const char kCategory[] = …;
BASE_FEATURE(…);
media::VideoPixelFormat ToOpaqueMediaPixelFormat(media::VideoPixelFormat fmt) { … }
int ComputeMaxActiveEncodes(std::optional<int> frame_delay = std::nullopt,
std::optional<int> input_capacity = std::nullopt) { … }
media::VideoEncodeAccelerator::SupportedRateControlMode BitrateToSupportedMode(
const media::Bitrate& bitrate) { … }
media::EncoderStatus IsAcceleratedConfigurationSupported(
media::VideoCodecProfile profile,
const media::VideoEncoder::Options& options,
media::GpuVideoAcceleratorFactories* gpu_factories,
EncoderType required_encoder_type) { … }
VideoEncoderTraits::ParsedConfig* ParseConfigStatic(
const VideoEncoderConfig* config,
ExceptionState& exception_state) { … }
bool VerifyCodecSupportStatic(VideoEncoderTraits::ParsedConfig* config,
String* js_error_message) { … }
VideoEncoderConfig* CopyConfig(
const VideoEncoderConfig& config,
const VideoEncoderTraits::ParsedConfig& parsed_config) { … }
bool CanUseGpuMemoryBufferReadback(media::VideoPixelFormat format,
bool force_opaque) { … }
bool MayHaveOSSoftwareEncoder(media::VideoCodecProfile profile) { … }
EncoderType GetRequiredEncoderType(media::VideoCodecProfile profile,
HardwarePreference hw_pref) { … }
}
const char* VideoEncoderTraits::GetName() { … }
String VideoEncoderTraits::ParsedConfig::ToString() { … }
VideoEncoder* VideoEncoder::Create(ScriptState* script_state,
const VideoEncoderInit* init,
ExceptionState& exception_state) { … }
VideoEncoder::VideoEncoder(ScriptState* script_state,
const VideoEncoderInit* init,
ExceptionState& exception_state)
: … { … }
VideoEncoder::~VideoEncoder() = default;
VideoEncoder::ParsedConfig* VideoEncoder::ParseConfig(
const VideoEncoderConfig* config,
ExceptionState& exception_state) { … }
bool VideoEncoder::VerifyCodecSupport(ParsedConfig* config,
String* js_error_message) { … }
media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>>
VideoEncoder::CreateAcceleratedVideoEncoder(
media::VideoCodecProfile profile,
const media::VideoEncoder::Options& options,
media::GpuVideoAcceleratorFactories* gpu_factories,
HardwarePreference hw_pref) { … }
std::unique_ptr<media::VideoEncoder> CreateAv1VideoEncoder() { … }
std::unique_ptr<media::VideoEncoder> CreateVpxVideoEncoder() { … }
std::unique_ptr<media::VideoEncoder> CreateOpenH264VideoEncoder() { … }
media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>>
VideoEncoder::CreateSoftwareVideoEncoder(VideoEncoder* self,
bool fallback,
media::VideoCodec codec) { … }
media::EncoderStatus::Or<std::unique_ptr<media::VideoEncoder>>
VideoEncoder::CreateMediaVideoEncoder(
const ParsedConfig& config,
media::GpuVideoAcceleratorFactories* gpu_factories,
bool& is_platform_encoder) { … }
void VideoEncoder::ContinueConfigureWithGpuFactories(
Request* request,
media::GpuVideoAcceleratorFactories* gpu_factories) { … }
std::unique_ptr<media::VideoEncoderMetricsProvider>
VideoEncoder::CreateVideoEncoderMetricsProvider() const { … }
bool VideoEncoder::CanReconfigure(ParsedConfig& original_config,
ParsedConfig& new_config) { … }
const AtomicString& VideoEncoder::InterfaceName() const { … }
bool VideoEncoder::HasPendingActivity() const { … }
void VideoEncoder::Trace(Visitor* visitor) const { … }
void VideoEncoder::ReportError(const char* error_message,
const media::EncoderStatus& status,
bool is_error_message_from_software_codec) { … }
bool VideoEncoder::ReadyToProcessNextRequest() { … }
bool VideoEncoder::StartReadback(scoped_refptr<media::VideoFrame> frame,
ReadbackDoneCallback result_cb) { … }
void VideoEncoder::ProcessEncode(Request* request) { … }
media::VideoEncoder::EncodeOptions VideoEncoder::CreateEncodeOptions(
Request* request) { … }
void VideoEncoder::OnReadbackDone(
Request* request,
scoped_refptr<media::VideoFrame> txt_frame,
media::VideoEncoder::EncoderStatusCB done_callback,
scoped_refptr<media::VideoFrame> result_frame) { … }
void VideoEncoder::OnEncodeDone(Request* request, media::EncoderStatus status) { … }
void VideoEncoder::ProcessConfigure(Request* request) { … }
void VideoEncoder::ProcessReconfigure(Request* request) { … }
void VideoEncoder::OnMediaEncoderInfoChanged(
const media::VideoEncoderInfo& encoder_info) { … }
void VideoEncoder::CallOutputCallback(
ParsedConfig* active_config,
uint32_t reset_count,
media::VideoEncoderOutput output,
std::optional<media::VideoEncoder::CodecDescription> codec_desc) { … }
void VideoEncoder::ResetInternal(DOMException* ex) { … }
void FindAnySupported(ScriptPromiseResolver<VideoEncoderSupport>* resolver,
const HeapVector<Member<VideoEncoderSupport>>& supports) { … }
static void isConfigSupportedWithSoftwareOnly(
ScriptState* script_state,
base::OnceCallback<void(VideoEncoderSupport*)> callback,
VideoEncoderSupport* support,
VideoEncoderTraits::ParsedConfig* config) { … }
static void isConfigSupportedWithHardwareOnly(
WTF::CrossThreadOnceFunction<void(blink::VideoEncoderSupport*)> callback,
VideoEncoderSupport* support,
VideoEncoderTraits::ParsedConfig* config,
media::GpuVideoAcceleratorFactories* gpu_factories) { … }
ScriptPromise<VideoEncoderSupport> VideoEncoder::isConfigSupported(
ScriptState* script_state,
const VideoEncoderConfig* config,
ExceptionState& exception_state) { … }
HeapVector<Member<VideoEncoderBuffer>> VideoEncoder::getAllFrameBuffers(
ScriptState*,
ExceptionState& exception_state) { … }
}