chromium/third_party/blink/renderer/modules/webcodecs/video_encoder.cc

// 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.

#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 WTF

namespace blink {

EncoderType;

namespace {

constexpr const char kCategory[] =;
// Controls if VideoEncoder will use timestamp from blink::VideoFrame
// instead of media::VideoFrame.
BASE_FEATURE();

// TODO(crbug.com/40215121): This is very similar to the method in
// video_frame.cc. It should probably be a function in video_types.cc.
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) {}

}  // namespace

// static
const char* VideoEncoderTraits::GetName() {}

String VideoEncoderTraits::ParsedConfig::ToString() {}

// static
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() {}

// This method is static and takes |self| in order to make it possible to use it
// with a weak |this|. It's needed in to avoid a persistent reference cycle.
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) {}

// static
ScriptPromise<VideoEncoderSupport> VideoEncoder::isConfigSupported(
    ScriptState* script_state,
    const VideoEncoderConfig* config,
    ExceptionState& exception_state) {}

HeapVector<Member<VideoEncoderBuffer>> VideoEncoder::getAllFrameBuffers(
    ScriptState*,
    ExceptionState& exception_state) {}

}  // namespace blink