#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/modules/webcodecs/video_decoder.h"
#include <utility>
#include <vector>
#include "base/containers/span.h"
#include "base/metrics/histogram_functions.h"
#include "base/time/time.h"
#include "media/base/decoder_buffer.h"
#include "media/base/limits.h"
#include "media/base/media_util.h"
#include "media/base/mime_util.h"
#include "media/base/supported_types.h"
#include "media/base/timestamp_constants.h"
#include "media/base/video_aspect_ratio.h"
#include "media/base/video_decoder.h"
#include "media/base/video_frame.h"
#include "media/media_buildflags.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/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/modules/v8/v8_encoded_video_chunk.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_decoder_support.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/modules/webcodecs/array_buffer_util.h"
#include "third_party/blink/renderer/modules/webcodecs/decrypt_config_util.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_decoder_broker.h"
#include "third_party/blink/renderer/modules/webcodecs/video_frame.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.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/heap/cross_thread_handle.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier_std.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/libgav1/src/src/buffer_pool.h"
#include "third_party/libgav1/src/src/decoder_state.h"
#include "third_party/libgav1/src/src/gav1/status_code.h"
#include "third_party/libgav1/src/src/obu_parser.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#if BUILDFLAG(ENABLE_LIBVPX)
#include "third_party/libvpx/source/libvpx/vpx/vp8dx.h"
#include "third_party/libvpx/source/libvpx/vpx/vpx_decoder.h"
#endif
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
#include "media/filters/h264_to_annex_b_bitstream_converter.h"
#include "media/formats/mp4/box_definitions.h"
#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
#include "media/filters/h265_to_annex_b_bitstream_converter.h"
#include "media/formats/mp4/hevc.h"
#endif
#endif
namespace blink {
namespace {
void DecoderSupport_OnKnown(
VideoDecoderSupport* support,
std::unique_ptr<VideoDecoder::MediaConfigType> media_config,
ScriptPromiseResolver<VideoDecoderSupport>* resolver,
media::GpuVideoAcceleratorFactories* gpu_factories) { … }
bool ParseCodecString(const String& codec_string,
media::VideoType& out_video_type,
String& js_error_message) { … }
VideoDecoderConfig* CopyConfig(const VideoDecoderConfig& config) { … }
void ParseAv1KeyFrame(const media::DecoderBuffer& buffer,
libgav1::BufferPool* buffer_pool,
bool* is_key_frame) { … }
void ParseVpxKeyFrame(const media::DecoderBuffer& buffer,
media::VideoCodec codec,
bool* is_key_frame) { … }
void ParseH264KeyFrame(const media::DecoderBuffer& buffer, bool* is_key_frame) { … }
void ParseH265KeyFrame(const media::DecoderBuffer& buffer, bool* is_key_frame) { … }
}
struct VideoDecoder::DecoderSpecificData { … };
std::unique_ptr<VideoDecoderTraits::MediaDecoderType>
VideoDecoderTraits::CreateDecoder(
ExecutionContext& execution_context,
media::GpuVideoAcceleratorFactories* gpu_factories,
media::MediaLog* media_log) { … }
HardwarePreference VideoDecoder::GetHardwareAccelerationPreference(
const ConfigType& config) { … }
void VideoDecoderTraits::InitializeDecoder(
MediaDecoderType& decoder,
bool low_delay,
const MediaConfigType& media_config,
MediaDecoderType::InitCB init_cb,
MediaDecoderType::OutputCB output_cb) { … }
void VideoDecoderTraits::UpdateDecoderLog(const MediaDecoderType& decoder,
const MediaConfigType& media_config,
media::MediaLog* media_log) { … }
int VideoDecoderTraits::GetMaxDecodeRequests(const MediaDecoderType& decoder) { … }
const char* VideoDecoderTraits::GetName() { … }
VideoDecoder* VideoDecoder::Create(ScriptState* script_state,
const VideoDecoderInit* init,
ExceptionState& exception_state) { … }
ScriptPromise<VideoDecoderSupport> VideoDecoder::isConfigSupported(
ScriptState* script_state,
const VideoDecoderConfig* config,
ExceptionState& exception_state) { … }
HardwarePreference VideoDecoder::GetHardwarePreference(
const ConfigType& config) { … }
bool VideoDecoder::GetLowDelayPreference(const ConfigType& config) { … }
void VideoDecoder::SetHardwarePreference(HardwarePreference preference) { … }
std::optional<media::VideoType> VideoDecoder::IsValidVideoDecoderConfig(
const VideoDecoderConfig& config,
String* js_error_message) { … }
std::optional<media::VideoDecoderConfig>
VideoDecoder::MakeMediaVideoDecoderConfig(const ConfigType& config,
String* js_error_message,
bool* needs_converter_out) { … }
std::optional<media::VideoDecoderConfig>
VideoDecoder::MakeMediaVideoDecoderConfigInternal(
const ConfigType& config,
DecoderSpecificData& decoder_specific_data,
String* js_error_message,
bool* needs_converter_out) { … }
VideoDecoder::VideoDecoder(ScriptState* script_state,
const VideoDecoderInit* init,
ExceptionState& exception_state)
: … { … }
VideoDecoder::~VideoDecoder() = default;
bool VideoDecoder::IsValidConfig(const ConfigType& config,
String* js_error_message) { … }
std::optional<media::VideoDecoderConfig> VideoDecoder::MakeMediaConfig(
const ConfigType& config,
String* js_error_message) { … }
media::DecoderStatus::Or<scoped_refptr<media::DecoderBuffer>>
VideoDecoder::MakeInput(const InputType& chunk, bool verify_key_frame) { … }
media::DecoderStatus::Or<VideoDecoder::OutputType*> VideoDecoder::MakeOutput(
scoped_refptr<MediaOutputType> output,
ExecutionContext* context) { … }
const AtomicString& VideoDecoder::InterfaceName() const { … }
}