diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 16:35:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 15:45:54 +0000 |
commit | 32f5a1c56531e4210bc4cf8d8c7825d66e081888 (patch) | |
tree | eeeec6822f4d738d8454525233fd0e2e3a659e6d /chromium/media/base | |
parent | 99677208ff3b216fdfec551fbe548da5520cd6fb (diff) | |
download | qtwebengine-chromium-32f5a1c56531e4210bc4cf8d8c7825d66e081888.tar.gz |
BASELINE: Update Chromium to 87.0.4280.67
Change-Id: Ib157360be8c2ffb2c73125751a89f60e049c1d54
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/media/base')
53 files changed, 1044 insertions, 401 deletions
diff --git a/chromium/media/base/BUILD.gn b/chromium/media/base/BUILD.gn index 8d281ddff37..676eb651405 100644 --- a/chromium/media/base/BUILD.gn +++ b/chromium/media/base/BUILD.gn @@ -57,6 +57,8 @@ source_set("base") { "audio_decoder_config.h", "audio_discard_helper.cc", "audio_discard_helper.h", + "audio_encoder.cc", + "audio_encoder.h", "audio_fifo.cc", "audio_fifo.h", "audio_hash.cc", @@ -161,8 +163,6 @@ source_set("base") { "format_utils.h", "frame_rate_estimator.cc", "frame_rate_estimator.h", - "hdr_metadata.cc", - "hdr_metadata.h", "key_system_names.cc", "key_system_names.h", "key_system_properties.cc", @@ -299,6 +299,7 @@ source_set("base") { "tuneable.h", "unaligned_shared_memory.cc", "unaligned_shared_memory.h", + "use_after_free_checker.h", "user_input_monitor.cc", "user_input_monitor.h", "video_bitrate_allocation.cc", @@ -315,6 +316,8 @@ source_set("base") { "video_encoder.h", "video_frame.cc", "video_frame.h", + "video_frame_feedback.cc", + "video_frame_feedback.h", "video_frame_layout.cc", "video_frame_layout.h", "video_frame_metadata.cc", @@ -331,6 +334,8 @@ source_set("base") { "video_types.h", "video_util.cc", "video_util.h", + "wait_and_replace_sync_token_client.cc", + "wait_and_replace_sync_token_client.h", "waiting.h", "wall_clock_time_source.cc", "wall_clock_time_source.h", @@ -345,11 +350,13 @@ source_set("base") { "//media:media_buildflags", "//media:shared_memory_support", "//ui/gfx:color_space", + "//ui/gl", ] deps = [ "//base/allocator:buildflags", "//base/util/values:values_util", "//components/system_media_controls/linux/buildflags", + "//gpu/command_buffer/client:interface_base", "//gpu/command_buffer/common", "//gpu/ipc/common:common", "//third_party/libyuv", @@ -394,6 +401,7 @@ source_set("base") { "CoreVideo.framework", "CoreFoundation.framework", "CoreGraphics.framework", + "IOSurface.framework", ] } else if (is_win) { sources += [ "user_input_monitor_win.cc" ] diff --git a/chromium/media/base/android/BUILD.gn b/chromium/media/base/android/BUILD.gn index 16425c1048d..39766b7c387 100644 --- a/chromium/media/base/android/BUILD.gn +++ b/chromium/media/base/android/BUILD.gn @@ -19,13 +19,6 @@ if (is_android) { "//media/filters", ] - if (is_android) { - visibility += [ - "//gpu/command_buffer/service:gles2_sources", - "//gpu/command_buffer/service:android_texture_owner_unittests", - ] - } - sources = [ "android_cdm_factory.cc", "android_cdm_factory.h", @@ -161,7 +154,6 @@ if (is_android) { } android_resources("media_java_resources") { - create_srcjar = false sources = [ "java/res/raw/empty.wav" ] } diff --git a/chromium/media/base/android/jni_hdr_metadata.cc b/chromium/media/base/android/jni_hdr_metadata.cc index 118d7e4a01b..939577a88c8 100644 --- a/chromium/media/base/android/jni_hdr_metadata.cc +++ b/chromium/media/base/android/jni_hdr_metadata.cc @@ -5,13 +5,13 @@ #include "media/base/android/jni_hdr_metadata.h" #include "media/base/android/media_jni_headers/HdrMetadata_jni.h" -#include "media/base/hdr_metadata.h" #include "media/base/video_color_space.h" +#include "ui/gl/hdr_metadata.h" namespace media { JniHdrMetadata::JniHdrMetadata(const VideoColorSpace& color_space, - const HDRMetadata& hdr_metadata) + const gl::HDRMetadata& hdr_metadata) : color_space_(color_space), hdr_metadata_(hdr_metadata) { JNIEnv* env = base::android::AttachCurrentThread(); jobject_ = Java_HdrMetadata_create(env, reinterpret_cast<jlong>(this)); diff --git a/chromium/media/base/android/jni_hdr_metadata.h b/chromium/media/base/android/jni_hdr_metadata.h index 888e920d860..af3510f3bf8 100644 --- a/chromium/media/base/android/jni_hdr_metadata.h +++ b/chromium/media/base/android/jni_hdr_metadata.h @@ -7,16 +7,16 @@ #include "base/android/jni_android.h" #include "base/macros.h" +#include "ui/gl/hdr_metadata.h" namespace media { -struct HDRMetadata; class VideoColorSpace; class JniHdrMetadata { public: JniHdrMetadata(const VideoColorSpace& color_space, - const HDRMetadata& hdr_metadata); + const gl::HDRMetadata& hdr_metadata); ~JniHdrMetadata(); base::android::ScopedJavaLocalRef<jobject> obj() { return jobject_; } @@ -58,7 +58,7 @@ class JniHdrMetadata { private: const VideoColorSpace& color_space_; - const HDRMetadata& hdr_metadata_; + const gl::HDRMetadata& hdr_metadata_; base::android::ScopedJavaLocalRef<jobject> jobject_; DISALLOW_COPY_AND_ASSIGN(JniHdrMetadata); diff --git a/chromium/media/base/android/media_codec_bridge_impl.h b/chromium/media/base/android/media_codec_bridge_impl.h index 35c224c73ed..c21ec38bab6 100644 --- a/chromium/media/base/android/media_codec_bridge_impl.h +++ b/chromium/media/base/android/media_codec_bridge_impl.h @@ -20,11 +20,11 @@ #include "media/base/media_export.h" #include "media/base/video_decoder_config.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/hdr_metadata.h" namespace media { class VideoColorSpace; -struct HDRMetadata; // Configuration info for MediaCodec. class MEDIA_EXPORT VideoCodecConfig { @@ -54,7 +54,7 @@ class MEDIA_EXPORT VideoCodecConfig { // VP9 HDR metadata is only embedded in the container. HDR10 metadata is // embedded in the video stream. - base::Optional<HDRMetadata> hdr_metadata; + base::Optional<gl::HDRMetadata> hdr_metadata; // Enables the async MediaCodec.Callback API. |on_buffers_available_cb| // will be called when input or output buffers are available. This will be diff --git a/chromium/media/base/android/media_codec_util.cc b/chromium/media/base/android/media_codec_util.cc index 45c08d5d30d..ab1975a4f79 100644 --- a/chromium/media/base/android/media_codec_util.cc +++ b/chromium/media/base/android/media_codec_util.cc @@ -416,16 +416,4 @@ bool MediaCodecUtil::CodecNeedsFlushWorkaround(MediaCodecBridge* codec) { "OMX.Exynos.avc.dec.secure" == codec_name); } -// static -bool MediaCodecUtil::LimitAImageReaderMaxSizeToOne() { - // Using MIBOX for both MiBox 4k and MiBox S 4k devices. - std::string disabled_model = "MIBOX"; - const std::string model(base::android::BuildInfo::GetInstance()->model()); - if (base::StartsWith(model, disabled_model, - base::CompareCase::INSENSITIVE_ASCII)) { - return true; - } - return false; -} - } // namespace media diff --git a/chromium/media/base/android/media_codec_util.h b/chromium/media/base/android/media_codec_util.h index b000efb2cd6..5fd273de2ed 100644 --- a/chromium/media/base/android/media_codec_util.h +++ b/chromium/media/base/android/media_codec_util.h @@ -131,11 +131,6 @@ class MEDIA_EXPORT MediaCodecUtil { // WARNING: This can't be used from the renderer process since it attempts to // create a MediaCodec (which requires permissions) to get the codec name. static bool CodecNeedsFlushWorkaround(MediaCodecBridge* codec); - - // Some devices do not support more than 1 image to be acquired from the - // AImageReader.(crbug.com/1051705). This method returns true for those - // devices. - static bool LimitAImageReaderMaxSizeToOne(); }; } // namespace media diff --git a/chromium/media/base/audio_decoder.h b/chromium/media/base/audio_decoder.h index d9a458db4fd..7361e251036 100644 --- a/chromium/media/base/audio_decoder.h +++ b/chromium/media/base/audio_decoder.h @@ -27,16 +27,20 @@ class CdmContext; class MEDIA_EXPORT AudioDecoder : public Decoder { public: - // Callback for AudioDecoder initialization. + // Callback for Decoder initialization. using InitCB = base::OnceCallback<void(Status)>; // Callback for AudioDecoder to return a decoded frame whenever it becomes // available. Only non-EOS frames should be returned via this callback. using OutputCB = base::RepeatingCallback<void(scoped_refptr<AudioBuffer>)>; - // Callback for Decode(). Called after the decoder has accepted corresponding - // DecoderBuffer, indicating that the pipeline can send next buffer to decode. - using DecodeCB = base::OnceCallback<void(DecodeStatus)>; + // Callback type for Decode(). Called after the decoder has completed decoding + // corresponding DecoderBuffer, indicating that it's ready to accept another + // buffer to decode. |kOk| implies success, |kAborted| implies that the + // decode was aborted, which does not necessarily indicate an error. For + // example, a Reset() can trigger this. Any other status code indicates that + // the decoder encountered an error, and must be reset. + using DecodeCB = base::OnceCallback<void(Status)>; AudioDecoder(); diff --git a/chromium/media/base/audio_encoder.cc b/chromium/media/base/audio_encoder.cc new file mode 100644 index 00000000000..0a9ca22e96f --- /dev/null +++ b/chromium/media/base/audio_encoder.cc @@ -0,0 +1,71 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/audio_encoder.h" + +#include "base/logging.h" +#include "base/time/time.h" +#include "media/base/audio_timestamp_helper.h" + +namespace media { + +// ----------------------------------------------------------------------------- +// EncodedAudioBuffer: + +EncodedAudioBuffer::EncodedAudioBuffer(const AudioParameters& params, + std::unique_ptr<uint8_t[]> data, + size_t size, + base::TimeTicks timestamp) + : params(params), + encoded_data(std::move(data)), + encoded_data_size(size), + timestamp(timestamp) {} + +EncodedAudioBuffer::EncodedAudioBuffer(EncodedAudioBuffer&&) = default; + +EncodedAudioBuffer::~EncodedAudioBuffer() = default; + +// ----------------------------------------------------------------------------- +// AudioEncoder: + +AudioEncoder::AudioEncoder(const AudioParameters& input_params, + EncodeCB encode_callback, + StatusCB status_callback) + : audio_input_params_(input_params), + encode_callback_(std::move(encode_callback)), + status_callback_(std::move(status_callback)) { + DCHECK(audio_input_params_.IsValid()); + DCHECK(!encode_callback_.is_null()); + DCHECK(!status_callback_.is_null()); + DETACH_FROM_THREAD(thread_checker_); +} + +AudioEncoder::~AudioEncoder() = default; + +void AudioEncoder::EncodeAudio(const AudioBus& audio_bus, + base::TimeTicks capture_time) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_EQ(audio_bus.channels(), audio_input_params_.channels()); + DCHECK(!capture_time.is_null()); + + DLOG_IF(ERROR, + !last_capture_time_.is_null() && + ((capture_time - last_capture_time_).InSecondsF() > + 1.5f * audio_bus.frames() / audio_input_params().sample_rate())) + << "Possibly frames were skipped, which may result in inaccuarate " + "timestamp calculation."; + + last_capture_time_ = capture_time; + + EncodeAudioImpl(audio_bus, capture_time); +} + +base::TimeTicks AudioEncoder::ComputeTimestamp( + int num_frames, + base::TimeTicks capture_time) const { + return capture_time - AudioTimestampHelper::FramesToTime( + num_frames, audio_input_params_.sample_rate()); +} + +} // namespace media diff --git a/chromium/media/base/audio_encoder.h b/chromium/media/base/audio_encoder.h new file mode 100644 index 00000000000..e7ad866fcb0 --- /dev/null +++ b/chromium/media/base/audio_encoder.h @@ -0,0 +1,112 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_AUDIO_ENCODER_H_ +#define MEDIA_BASE_AUDIO_ENCODER_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "media/base/audio_bus.h" +#include "media/base/audio_parameters.h" +#include "media/base/media_export.h" +#include "media/base/status.h" + +namespace media { + +// Defines a move-only wrapper to hold the encoded audio data. +struct MEDIA_EXPORT EncodedAudioBuffer { + EncodedAudioBuffer(const AudioParameters& params, + std::unique_ptr<uint8_t[]> data, + size_t size, + base::TimeTicks timestamp); + EncodedAudioBuffer(EncodedAudioBuffer&&); + ~EncodedAudioBuffer(); + + // The audio parameters the encoder used to encode the input audio. They may + // differ from the original parameters given to the encoder initially, as the + // encoder may convert the audio to a format more suitable for encoding. + const AudioParameters params; + + // The buffer containing the encoded data. + std::unique_ptr<uint8_t[]> encoded_data; + + // The size of the encoded data in the above buffer. Note that this is not + // necessarily equal to the capacity of the buffer. Some encoders allocate a + // bigger buffer and fill it only with |encoded_data_size| data without + // bothering to allocate another shrunk buffer and copy the data in, since the + // number of encoded bytes may not be known in advance. + const size_t encoded_data_size; + + // The capture time of the first sample of the current AudioBus. + const base::TimeTicks timestamp; +}; + +// Defines an interface for audio encoders. Concrete encoders must implement the +// EncodeAudioImpl() function. +class MEDIA_EXPORT AudioEncoder { + public: + // Signature of the callback invoked to provide the encoded audio data. It is + // invoked on the same thread on which EncodeAudio() is called. The utility + // media::BindToCurrentLoop() can be used to create a callback that will be + // invoked on the same thread it is constructed on. + using EncodeCB = base::RepeatingCallback<void(EncodedAudioBuffer output)>; + + // Signature of the callback to report errors. + using StatusCB = base::RepeatingCallback<void(Status error)>; + + // Constructs the encoder given the audio parameters of the input to this + // encoder, and a callback to trigger to provide the encoded audio data. + // |input_params| must be valid, and |encode_callback| and |status_callback| + // must not be null callbacks. All calls to EncodeAudio() must happen on the + // same thread (usually an encoder thread), but the encoder itself can be + // constructed on any thread. + AudioEncoder(const AudioParameters& input_params, + EncodeCB encode_callback, + StatusCB status_callback); + AudioEncoder(const AudioEncoder&) = delete; + AudioEncoder& operator=(const AudioEncoder&) = delete; + virtual ~AudioEncoder(); + + const AudioParameters& audio_input_params() const { + return audio_input_params_; + } + + // Performs various checks before calling EncodeAudioImpl() which does the + // actual encoding. + void EncodeAudio(const AudioBus& audio_bus, base::TimeTicks capture_time); + + protected: + const EncodeCB& encode_callback() const { return encode_callback_; } + const StatusCB& status_callback() const { return status_callback_; } + base::TimeTicks last_capture_time() const { return last_capture_time_; } + + virtual void EncodeAudioImpl(const AudioBus& audio_bus, + base::TimeTicks capture_time) = 0; + + // Computes the timestamp of an AudioBus which has |num_frames| and was + // captured at |capture_time|. This timestamp is the capture time of the first + // sample in that AudioBus. + base::TimeTicks ComputeTimestamp(int num_frames, + base::TimeTicks capture_time) const; + + private: + const AudioParameters audio_input_params_; + + const EncodeCB encode_callback_; + + const StatusCB status_callback_; + + // The capture time of the most recent |audio_bus| delivered to + // EncodeAudio(). + base::TimeTicks last_capture_time_; + + THREAD_CHECKER(thread_checker_); +}; + +} // namespace media + +#endif // MEDIA_BASE_AUDIO_ENCODER_H_ diff --git a/chromium/media/base/decode_status.cc b/chromium/media/base/decode_status.cc index de30ca7e306..af52c1b8d16 100644 --- a/chromium/media/base/decode_status.cc +++ b/chromium/media/base/decode_status.cc @@ -7,6 +7,7 @@ #include <ostream> #include "base/trace_event/trace_event.h" +#include "media/base/status.h" namespace media { @@ -18,17 +19,16 @@ const char* GetDecodeStatusString(DecodeStatus status) { return "DecodeStatus::ABORTED"; case DecodeStatus::DECODE_ERROR: return "DecodeStatus::DECODE_ERROR"; + default: + // TODO(liberato): Temporary while converting to media::Status. This + // fn should go away. + return "DecodeStatus::UNKNOWN_ERROR"; } NOTREACHED(); return ""; } -std::ostream& operator<<(std::ostream& os, const DecodeStatus& status) { - os << GetDecodeStatusString(status); - return os; -} - // static bool ScopedDecodeTrace::IsEnabled() { bool enable_decode_traces = false; @@ -59,11 +59,11 @@ ScopedDecodeTrace::~ScopedDecodeTrace() { EndTrace(DecodeStatus::ABORTED); } -void ScopedDecodeTrace::EndTrace(DecodeStatus status) { +void ScopedDecodeTrace::EndTrace(const Status& status) { DCHECK(!closed_); closed_ = true; TRACE_EVENT_ASYNC_END1("media", trace_name_, this, "status", - GetDecodeStatusString(status)); + GetDecodeStatusString(status.code())); } } // namespace media diff --git a/chromium/media/base/decode_status.h b/chromium/media/base/decode_status.h index 0271668c92e..d17d8573f71 100644 --- a/chromium/media/base/decode_status.h +++ b/chromium/media/base/decode_status.h @@ -9,22 +9,17 @@ #include "media/base/decoder_buffer.h" #include "media/base/media_export.h" +#include "media/base/status_codes.h" namespace media { -enum class DecodeStatus { - OK = 0, // Everything went as planned. - ABORTED, // Read aborted due to Reset() during pending read. - DECODE_ERROR, // Decoder returned decode error. Note: Prefixed by DECODE_ - // since ERROR is a reserved name (special macro) on Windows. - DECODE_STATUS_MAX = DECODE_ERROR -}; +class Status; -MEDIA_EXPORT const char* GetDecodeStatusString(DecodeStatus status); +// TODO(crbug.com/1129662): This is temporary, to allow DecodeStatus::OK to +// work, while we replace DecodeStatus with actual status codes. +using DecodeStatus = StatusCode; -// Helper function so that DecodeStatus can be printed easily. -MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, - const DecodeStatus& status); +MEDIA_EXPORT const char* GetDecodeStatusString(DecodeStatus status); // Helper class for ensuring that Decode() traces are properly unique and closed // if the Decode is aborted via a WeakPtr invalidation. We use the |this| @@ -45,7 +40,7 @@ class MEDIA_EXPORT ScopedDecodeTrace { ~ScopedDecodeTrace(); // Completes the Decode() trace with the given status. - void EndTrace(DecodeStatus status); + void EndTrace(const Status& status); private: const char* trace_name_; diff --git a/chromium/media/base/decoder.h b/chromium/media/base/decoder.h index 3c0d6c3b87a..8ebec529466 100644 --- a/chromium/media/base/decoder.h +++ b/chromium/media/base/decoder.h @@ -7,8 +7,10 @@ #include <string> +#include "base/callback.h" #include "base/macros.h" #include "media/base/media_export.h" +#include "media/base/status.h" namespace media { diff --git a/chromium/media/base/hdr_metadata.cc b/chromium/media/base/hdr_metadata.cc deleted file mode 100644 index 4bc5400cf08..00000000000 --- a/chromium/media/base/hdr_metadata.cc +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/base/hdr_metadata.h" - -namespace media { - -MasteringMetadata::MasteringMetadata() = default; -MasteringMetadata::MasteringMetadata(const MasteringMetadata& rhs) = default; - -HDRMetadata::HDRMetadata() = default; -HDRMetadata::HDRMetadata(const HDRMetadata& rhs) = default; - -} // namespace media diff --git a/chromium/media/base/hdr_metadata.h b/chromium/media/base/hdr_metadata.h deleted file mode 100644 index 715642d32cd..00000000000 --- a/chromium/media/base/hdr_metadata.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_BASE_HDR_METADATA_H_ -#define MEDIA_BASE_HDR_METADATA_H_ - -#include "media/base/media_export.h" -#include "ui/gfx/geometry/point_f.h" - -namespace media { - -// SMPTE ST 2086 mastering metadata. -struct MEDIA_EXPORT MasteringMetadata { - using Chromaticity = gfx::PointF; - Chromaticity primary_r; - Chromaticity primary_g; - Chromaticity primary_b; - Chromaticity white_point; - float luminance_max = 0; - float luminance_min = 0; - - MasteringMetadata(); - MasteringMetadata(const MasteringMetadata& rhs); - - bool operator==(const MasteringMetadata& rhs) const { - return ((primary_r == rhs.primary_r) && (primary_g == rhs.primary_g) && - (primary_b == rhs.primary_b) && (white_point == rhs.white_point) && - (luminance_max == rhs.luminance_max) && - (luminance_min == rhs.luminance_min)); - } -}; - -// HDR metadata common for HDR10 and WebM/VP9-based HDR formats. -struct MEDIA_EXPORT HDRMetadata { - MasteringMetadata mastering_metadata; - // Max content light level (CLL), i.e. maximum brightness level present in the - // stream), in nits. - unsigned max_content_light_level = 0; - // Max frame-average light level (FALL), i.e. maximum average brightness of - // the brightest frame in the stream), in nits. - unsigned max_frame_average_light_level = 0; - - HDRMetadata(); - HDRMetadata(const HDRMetadata& rhs); - - bool operator==(const HDRMetadata& rhs) const { - return ( - (max_content_light_level == rhs.max_content_light_level) && - (max_frame_average_light_level == rhs.max_frame_average_light_level) && - (mastering_metadata == rhs.mastering_metadata)); - } -}; - -// HDR metadata types as described in -// https://w3c.github.io/media-capabilities/#enumdef-hdrmetadatatype -enum class HdrMetadataType { - kNone, - kSmpteSt2086, - kSmpteSt2094_10, - kSmpteSt2094_40, -}; - -} // namespace media - -#endif // MEDIA_BASE_HDR_METADATA_H_ diff --git a/chromium/media/base/ipc/media_param_traits_macros.h b/chromium/media/base/ipc/media_param_traits_macros.h index 1eca0edb227..9379933883f 100644 --- a/chromium/media/base/ipc/media_param_traits_macros.h +++ b/chromium/media/base/ipc/media_param_traits_macros.h @@ -22,7 +22,6 @@ #include "media/base/demuxer_stream.h" #include "media/base/eme_constants.h" #include "media/base/encryption_scheme.h" -#include "media/base/hdr_metadata.h" #include "media/base/media_log_record.h" #include "media/base/media_status.h" #include "media/base/output_device_info.h" @@ -40,6 +39,7 @@ #include "media/media_buildflags.h" #include "media/video/supported_video_decoder_config.h" #include "ui/gfx/ipc/color/gfx_param_traits_macros.h" +#include "ui/gl/hdr_metadata.h" #if BUILDFLAG(ENABLE_MEDIA_DRM_STORAGE) #include "media/base/media_drm_key_type.h" @@ -75,9 +75,6 @@ IPC_ENUM_TRAITS_MAX_VALUE(media::CdmSessionType, IPC_ENUM_TRAITS_MAX_VALUE(media::ChannelLayout, media::CHANNEL_LAYOUT_MAX) -IPC_ENUM_TRAITS_MAX_VALUE(media::DecodeStatus, - media::DecodeStatus::DECODE_STATUS_MAX) - IPC_ENUM_TRAITS_MAX_VALUE(media::Decryptor::Status, media::Decryptor::Status::kStatusMax) @@ -186,7 +183,7 @@ IPC_STRUCT_TRAITS_BEGIN(media::VideoColorSpace) IPC_STRUCT_TRAITS_MEMBER(range) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(media::MasteringMetadata) +IPC_STRUCT_TRAITS_BEGIN(gl::MasteringMetadata) IPC_STRUCT_TRAITS_MEMBER(primary_r) IPC_STRUCT_TRAITS_MEMBER(primary_g) IPC_STRUCT_TRAITS_MEMBER(primary_b) @@ -195,7 +192,7 @@ IPC_STRUCT_TRAITS_BEGIN(media::MasteringMetadata) IPC_STRUCT_TRAITS_MEMBER(luminance_min) IPC_STRUCT_TRAITS_END() -IPC_STRUCT_TRAITS_BEGIN(media::HDRMetadata) +IPC_STRUCT_TRAITS_BEGIN(gl::HDRMetadata) IPC_STRUCT_TRAITS_MEMBER(mastering_metadata) IPC_STRUCT_TRAITS_MEMBER(max_content_light_level) IPC_STRUCT_TRAITS_MEMBER(max_frame_average_light_level) diff --git a/chromium/media/base/mac/BUILD.gn b/chromium/media/base/mac/BUILD.gn index c4768e137bf..7b16b9833cd 100644 --- a/chromium/media/base/mac/BUILD.gn +++ b/chromium/media/base/mac/BUILD.gn @@ -2,6 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# This file depends on the legacy global sources assignment filter. It should +# be converted to check target platform before assigning source files to the +# sources variable. Remove this import and set_sources_assignment_filter call +# when the file has been converted. See https://crbug.com/1018739 for details. +import("//build/config/deprecated_default_sources_assignment_filter.gni") +set_sources_assignment_filter(deprecated_default_sources_assignment_filter) + assert(is_apple) source_set("mac") { @@ -26,7 +33,7 @@ source_set("mac") { "VideoToolbox.framework", ] } - set_sources_assignment_filter(sources_assignment_filter) + set_sources_assignment_filter(deprecated_default_sources_assignment_filter) configs += [ "//media:subcomponent_config" ] deps = [ diff --git a/chromium/media/base/mac/video_frame_mac.cc b/chromium/media/base/mac/video_frame_mac.cc index 7d3eb1a48ed..458f0274bdb 100644 --- a/chromium/media/base/mac/video_frame_mac.cc +++ b/chromium/media/base/mac/video_frame_mac.cc @@ -11,6 +11,8 @@ #include "base/logging.h" #include "media/base/video_frame.h" +#include "ui/gfx/gpu_memory_buffer.h" +#include "ui/gfx/mac/io_surface.h" namespace media { @@ -41,6 +43,27 @@ WrapVideoFrameInCVPixelBuffer(const VideoFrame& frame) { return pixel_buffer; } + // If the frame has a GMB, yank out its IOSurface if possible. + if (frame.GetGpuMemoryBuffer()) { + gfx::GpuMemoryBufferHandle handle = + frame.GetGpuMemoryBuffer()->CloneHandle(); + if (handle.type == gfx::GpuMemoryBufferType::IO_SURFACE_BUFFER) { + base::ScopedCFTypeRef<IOSurfaceRef> io_surface = + gfx::IOSurfaceMachPortToIOSurface(std::move(handle.mach_port)); + if (io_surface) { + const CVReturn cv_return = CVPixelBufferCreateWithIOSurface( + nullptr, io_surface, nullptr, pixel_buffer.InitializeInto()); + if (cv_return == kCVReturnSuccess) { + VLOG(3) << "Returning IOSurface-based CVPixelBuffer."; + return pixel_buffer; + } + pixel_buffer.reset(); + } + } + } + + VLOG(3) << "Returning RAM based CVPixelBuffer."; + // VideoFrame only supports YUV formats and most of them are 'YVU' ordered, // which CVPixelBuffer does not support. This means we effectively can only // represent I420 and NV12 frames. In addition, VideoFrame does not carry diff --git a/chromium/media/base/media_log_properties.cc b/chromium/media/base/media_log_properties.cc index 36e9943813d..cdfbd8a0f56 100644 --- a/chromium/media/base/media_log_properties.cc +++ b/chromium/media/base/media_log_properties.cc @@ -35,6 +35,7 @@ std::string MediaLogPropertyKeyToString(MediaLogProperty property) { STRINGIFY(kVideoTracks); STRINGIFY(kFramerate); STRINGIFY(kVideoPlaybackRoughness); + STRINGIFY(kVideoPlaybackFreezing); } #undef STRINGIFY } diff --git a/chromium/media/base/media_log_properties.h b/chromium/media/base/media_log_properties.h index 6565ab57c3b..5f6a1084443 100644 --- a/chromium/media/base/media_log_properties.h +++ b/chromium/media/base/media_log_properties.h @@ -84,6 +84,10 @@ enum class MediaLogProperty { // A playback quality metric calculated by VideoPlaybackRoughnessReporter kVideoPlaybackRoughness, + + // A playback quality metric that tries to account for large pauses and/or + // discontinuities during playback. + kVideoPlaybackFreezing, }; MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kResolution, gfx::Size); @@ -109,6 +113,7 @@ MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kTextTracks, std::vector<TextTrackConfig>); MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kVideoTracks, std::vector<VideoDecoderConfig>); MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kFramerate, double); MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kVideoPlaybackRoughness, double); +MEDIA_LOG_PROPERTY_SUPPORTS_TYPE(kVideoPlaybackFreezing, base::TimeDelta); // Convert the enum to a string (used for the front-end enum matching). MEDIA_EXPORT std::string MediaLogPropertyKeyToString(MediaLogProperty property); diff --git a/chromium/media/base/media_permission.cc b/chromium/media/base/media_permission.cc index 307ccb91ec4..56ea2ffc0e8 100644 --- a/chromium/media/base/media_permission.cc +++ b/chromium/media/base/media_permission.cc @@ -10,4 +10,6 @@ MediaPermission::MediaPermission() = default; MediaPermission::~MediaPermission() = default; +void MediaPermission::NotifyUnsupportedPlatform() {} + } // namespace media diff --git a/chromium/media/base/media_permission.h b/chromium/media/base/media_permission.h index 4226086ba47..b71c6ca902b 100644 --- a/chromium/media/base/media_permission.h +++ b/chromium/media/base/media_permission.h @@ -41,6 +41,8 @@ class MEDIA_EXPORT MediaPermission { // the spec. virtual bool IsEncryptedMediaEnabled() = 0; + virtual void NotifyUnsupportedPlatform(); + private: DISALLOW_COPY_AND_ASSIGN(MediaPermission); }; diff --git a/chromium/media/base/media_serializers.h b/chromium/media/base/media_serializers.h index 8e7aae276b4..1a2a6bd5856 100644 --- a/chromium/media/base/media_serializers.h +++ b/chromium/media/base/media_serializers.h @@ -18,6 +18,7 @@ #include "media/base/text_track_config.h" #include "media/base/video_decoder_config.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/hdr_metadata.h" namespace media { @@ -211,8 +212,8 @@ struct MediaSerializer<VideoColorSpace> { // Class (complex) template <> -struct MediaSerializer<HDRMetadata> { - static base::Value Serialize(const HDRMetadata& value) { +struct MediaSerializer<gl::HDRMetadata> { + static base::Value Serialize(const gl::HDRMetadata& value) { // TODO(tmathmeyer) serialize more fields here potentially. base::Value result(base::Value::Type::DICTIONARY); FIELD_SERIALIZE("luminance range", diff --git a/chromium/media/base/media_switches.cc b/chromium/media/base/media_switches.cc index 3a9b0abe7d3..0c20d23e273 100644 --- a/chromium/media/base/media_switches.cc +++ b/chromium/media/base/media_switches.cc @@ -78,6 +78,10 @@ const char kEnableProtectedVideoBuffers[] = "enable-protected-video-buffers"; const char kForceProtectedVideoOutputBuffers[] = "force-protected-video-output-buffers"; +const char kDisableAudioInput[] = "disable-audio-input"; + +// Present video content as overlays. +const char kUseOverlaysForVideo[] = "use-overlays-for-video"; #endif // defined(OS_FUCHSIA) #if defined(USE_CRAS) @@ -183,13 +187,16 @@ const char kOverrideEnabledCdmInterfaceVersion[] = const char kOverrideHardwareSecureCodecsForTesting[] = "override-hardware-secure-codecs-for-testing"; +// Sets the default value for the kLiveCaptionEnabled preference to true. +const char kEnableLiveCaptionPrefForTesting[] = + "enable-live-caption-pref-for-testing"; + #if defined(OS_CHROMEOS) // ChromeOS uses one of two VideoDecoder implementations based on SoC/board // specific configurations that are signalled via this command line flag. // TODO(b/159825227): remove when the "old" video decoder is fully launched. const char kPlatformDisallowsChromeOSDirectVideoDecoder[] = - // TODO(mcasas): Rename the flag string when crrev.com/c/2268600 lands. - "force-disable-new-accelerated-video-decoder"; + "platform-disallows-chromeos-direct-video-decoder"; #endif namespace autoplay { @@ -370,6 +377,10 @@ const base::Feature kGlobalMediaControlsAutoDismiss{ const base::Feature kGlobalMediaControlsForCast{ "GlobalMediaControlsForCast", base::FEATURE_DISABLED_BY_DEFAULT}; +// Allow Global Media Controls in system tray of CrOS. +const base::Feature kGlobalMediaControlsForChromeOS{ + "GlobalMediaControlsForChromeOS", base::FEATURE_DISABLED_BY_DEFAULT}; + // Allow global media controls notifications to be dragged out into overlay // notifications. It is no-op if kGlobalMediaControls is not enabled. const base::Feature kGlobalMediaControlsOverlayControls{ @@ -387,15 +398,12 @@ const base::Feature kGlobalMediaControlsPictureInPicture { }; // Enable selection of audio output device in Global Media Controls. -const base::Feature kGlobalMediaControlsSeamlessTransfer { - "GlobalMediaControlsSeamlessTransfer", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kGlobalMediaControlsSeamlessTransfer{ + "GlobalMediaControlsSeamlessTransfer", base::FEATURE_DISABLED_BY_DEFAULT}; -// Enable new cpu load estimator. Intended for evaluation in local -// testing and origin-trial. -// TODO(nisse): Delete once we have switched over to always using the -// new estimator. -const base::Feature kNewEncodeCpuLoadEstimator{ - "NewEncodeCpuLoadEstimator", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enable an updated version of the Global Media Controls UI. +const base::Feature kGlobalMediaControlsModernUI{ + "GlobalMediaControlsModernUI", base::FEATURE_DISABLED_BY_DEFAULT}; // CanPlayThrough issued according to standard. const base::Feature kSpecCompliantCanPlayThrough{ @@ -406,10 +414,6 @@ const base::Feature kSpecCompliantCanPlayThrough{ const base::Feature kSuspendMutedAudio{"SuspendMutedAudio", base::FEATURE_ENABLED_BY_DEFAULT}; -// Use shared block-based buffering for media. -const base::Feature kUseNewMediaCache{"use-new-media-cache", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables using the media history store to store media engagement metrics. const base::Feature kUseMediaHistoryStore{"UseMediaHistoryStore", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -433,7 +437,7 @@ const base::Feature kVaapiVP8Encoder{"VaapiVP8Encoder", // Enable VA-API hardware encode acceleration for VP9. const base::Feature kVaapiVP9Encoder{"VaapiVP9Encoder", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; #if defined(ARCH_CPU_X86_FAMILY) && defined(OS_CHROMEOS) // Enable VP9 k-SVC decoding with HW decoder for webrtc use case on ChromeOS. @@ -451,10 +455,15 @@ const base::Feature kVideoBlitColorAccuracy{"video-blit-color-accuracy", const base::Feature kExternalClearKeyForTesting{ "ExternalClearKeyForTesting", base::FEATURE_DISABLED_BY_DEFAULT}; -// Enables the LiveCaption feature. +// Enables the Live Caption feature. const base::Feature kLiveCaption{"LiveCaption", base::FEATURE_DISABLED_BY_DEFAULT}; +// Use the Speech On-Device API (SODA) to power the Live Caption feature instead +// of the Cloud-based Open Speech API. +const base::Feature kUseSodaForLiveCaption{"UseSodaForLiveCaption", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Prevents UrlProvisionFetcher from making a provisioning request. If // specified, any provisioning request made will not be sent to the provisioning // server, and the response will indicate a failure to communicate with the @@ -501,6 +510,16 @@ const base::Feature kHardwareMediaKeyHandling { const base::Feature kResolutionBasedDecoderPriority{ "ResolutionBasedDecoderPriority", base::FEATURE_DISABLED_BY_DEFAULT}; +// Forces use of hardware (platform) video decoders in +// `media::DecoderSelector`. +const base::Feature kForceHardwareVideoDecoders{ + "ForceHardwareVideoDecoders", base::FEATURE_DISABLED_BY_DEFAULT}; + +// Forces use of hardware (platform) audio decoders in +// `media::DecoderSelector`. +const base::Feature kForceHardwareAudioDecoders{ + "ForceHardwareAudioDecoders", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables low-delay video rendering in media pipeline on "live" stream. const base::Feature kLowDelayVideoRenderingOnLiveStream{ "low-delay-video-rendering-on-live-stream", @@ -636,9 +655,28 @@ const base::Feature kMediaFoundationVideoCapture{ const base::Feature MEDIA_EXPORT kMediaFoundationVP8Decoding{ "MediaFoundationVP8Decoding", base::FEATURE_DISABLED_BY_DEFAULT}; +// Use the AUDCLNT_STREAMOPTIONS_RAW option on WASAPI input audio streams in +// combination with the IAudioClient2::SetClientProperties() API. +// The audio stream is a 'raw' stream that bypasses all signal processing except +// for endpoint specific, always-on processing in the Audio Processing Object +// (APO), driver, and hardware. +// https://docs.microsoft.com/en-us/windows/win32/api/audioclient/ne-audioclient-audclnt_streamoptions +const base::Feature MEDIA_EXPORT kWasapiRawAudioCapture{ + "WASAPIRawAudioCapture", base::FEATURE_DISABLED_BY_DEFAULT}; + #endif // defined(OS_WIN) #if defined(OS_MAC) +// Controls whether the next version mac capturer, including power improvements, +// zero copy operation, and other improvements, is active. +const base::Feature MEDIA_EXPORT kAVFoundationCaptureV2{ + "AVFoundationCaptureV2", base::FEATURE_ENABLED_BY_DEFAULT}; + +// Controls whether or not the V2 capturer exports IOSurfaces for zero-copy. +// This feature only has any effect if kAVFoundationCaptureV2 is also enabled. +const base::Feature MEDIA_EXPORT kAVFoundationCaptureV2ZeroCopy{ + "AVFoundationCaptureV2ZeroCopy", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature MEDIA_EXPORT kVideoToolboxVp9Decoding{ "VideoToolboxVp9Decoding", base::FEATURE_DISABLED_BY_DEFAULT}; #endif // defined(OS_MAC) @@ -659,11 +697,6 @@ std::string GetEffectiveAutoplayPolicy(const base::CommandLine& command_line) { #endif } -// Adds icons to the overflow menu on the native media controls. -// TODO(steimel): Remove this. -const base::Feature kOverflowIconsForMediaControls{ - "OverflowIconsForMediaControls", base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables Media Engagement Index recording. This data will be used to determine // when to bypass autoplay policies. This is recorded on all platforms. const base::Feature kRecordMediaEngagementScores{ @@ -774,6 +807,9 @@ const base::Feature kKaleidoscopeForceShowFirstRunExperience{ const base::Feature kKaleidoscopeModule{"KaleidoscopeModule", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kKaleidoscopeModuleCacheOnly{ + "KaleidoscopeModuleCacheOnly", base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kUseFakeDeviceForMediaStream{ "use-fake-device-for-media-stream", base::FEATURE_DISABLED_BY_DEFAULT}; diff --git a/chromium/media/base/media_switches.h b/chromium/media/base/media_switches.h index e863d1a93e9..0f47b38a949 100644 --- a/chromium/media/base/media_switches.h +++ b/chromium/media/base/media_switches.h @@ -51,6 +51,8 @@ MEDIA_EXPORT extern const char kWaveOutBuffers[]; #if defined(OS_FUCHSIA) MEDIA_EXPORT extern const char kEnableProtectedVideoBuffers[]; MEDIA_EXPORT extern const char kForceProtectedVideoOutputBuffers[]; +MEDIA_EXPORT extern const char kDisableAudioInput[]; +MEDIA_EXPORT extern const char kUseOverlaysForVideo[]; #endif #if defined(OS_CHROMEOS) @@ -85,6 +87,7 @@ MEDIA_EXPORT extern const char kMSEVideoBufferSizeLimitMb[]; MEDIA_EXPORT extern const char kClearKeyCdmPathForTesting[]; MEDIA_EXPORT extern const char kOverrideEnabledCdmInterfaceVersion[]; MEDIA_EXPORT extern const char kOverrideHardwareSecureCodecsForTesting[]; +MEDIA_EXPORT extern const char kEnableLiveCaptionPrefForTesting[]; namespace autoplay { @@ -126,9 +129,11 @@ MEDIA_EXPORT extern const base::Feature kGav1VideoDecoder; MEDIA_EXPORT extern const base::Feature kGlobalMediaControls; MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsAutoDismiss; MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsForCast; +MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsForChromeOS; MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsOverlayControls; MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsPictureInPicture; MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsSeamlessTransfer; +MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsModernUI; MEDIA_EXPORT extern const base::Feature kH264DecoderBufferIsCompleteFrame; MEDIA_EXPORT extern const base::Feature kHardwareMediaKeyHandling; MEDIA_EXPORT extern const base::Feature kHardwareSecureDecryption; @@ -137,6 +142,7 @@ MEDIA_EXPORT extern const base::Feature kKaleidoscope; MEDIA_EXPORT extern const base::Feature kKaleidoscopeForceShowFirstRunExperience; MEDIA_EXPORT extern const base::Feature kKaleidoscopeModule; +MEDIA_EXPORT extern const base::Feature kKaleidoscopeModuleCacheOnly; MEDIA_EXPORT extern const base::Feature kLiveCaption; MEDIA_EXPORT extern const base::Feature kLowDelayVideoRenderingOnLiveStream; MEDIA_EXPORT extern const base::Feature kMediaCapabilitiesQueryGpuFactories; @@ -154,8 +160,6 @@ MEDIA_EXPORT extern const base::Feature kMediaLearningSmoothnessExperiment; MEDIA_EXPORT extern const base::Feature kMediaOptimizer; MEDIA_EXPORT extern const base::Feature kMediaPowerExperiment; MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC; -MEDIA_EXPORT extern const base::Feature kNewEncodeCpuLoadEstimator; -MEDIA_EXPORT extern const base::Feature kOverflowIconsForMediaControls; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo; MEDIA_EXPORT extern const base::Feature kPictureInPicture; MEDIA_EXPORT extern const base::Feature kPreloadMediaEngagementData; @@ -171,8 +175,8 @@ MEDIA_EXPORT extern const base::Feature kUnifiedAutoplay; MEDIA_EXPORT extern const base::Feature kUseAndroidOverlayAggressively; MEDIA_EXPORT extern const base::Feature kUseFakeDeviceForMediaStream; MEDIA_EXPORT extern const base::Feature kUseMediaHistoryStore; -MEDIA_EXPORT extern const base::Feature kUseNewMediaCache; MEDIA_EXPORT extern const base::Feature kUseR16Texture; +MEDIA_EXPORT extern const base::Feature kUseSodaForLiveCaption; MEDIA_EXPORT extern const base::Feature kVaapiLowPowerEncoderGen9x; MEDIA_EXPORT extern const base::Feature kVaapiVP8Encoder; MEDIA_EXPORT extern const base::Feature kVaapiVP9Encoder; @@ -181,6 +185,8 @@ MEDIA_EXPORT extern const base::Feature kWakeLockOptimisationHiddenMuted; MEDIA_EXPORT extern const base::Feature kWidevineAv1; MEDIA_EXPORT extern const base::Feature kWidevineAv1ForceSupportForTesting; MEDIA_EXPORT extern const base::Feature kResolutionBasedDecoderPriority; +MEDIA_EXPORT extern const base::Feature kForceHardwareVideoDecoders; +MEDIA_EXPORT extern const base::Feature kForceHardwareAudioDecoders; #if defined(ARCH_CPU_X86_FAMILY) && defined(OS_CHROMEOS) MEDIA_EXPORT extern const base::Feature kVp9kSVCHWDecoding; @@ -215,9 +221,12 @@ MEDIA_EXPORT extern const base::Feature kMediaFoundationAsyncH264Encoding; MEDIA_EXPORT extern const base::Feature kMediaFoundationAV1Decoding; MEDIA_EXPORT extern const base::Feature kMediaFoundationVideoCapture; MEDIA_EXPORT extern const base::Feature kMediaFoundationVP8Decoding; +MEDIA_EXPORT extern const base::Feature kWasapiRawAudioCapture; #endif // defined(OS_WIN) #if defined(OS_MAC) +MEDIA_EXPORT extern const base::Feature kAVFoundationCaptureV2; +MEDIA_EXPORT extern const base::Feature kAVFoundationCaptureV2ZeroCopy; MEDIA_EXPORT extern const base::Feature kVideoToolboxVp9Decoding; #endif diff --git a/chromium/media/base/media_types.h b/chromium/media/base/media_types.h index acffbce4486..b96ee7bb4f4 100644 --- a/chromium/media/base/media_types.h +++ b/chromium/media/base/media_types.h @@ -33,7 +33,7 @@ struct MEDIA_EXPORT VideoType { VideoCodecProfile profile; int level; VideoColorSpace color_space; - HdrMetadataType hdr_metadata_type; + gl::HdrMetadataType hdr_metadata_type; }; MEDIA_EXPORT bool operator==(const AudioType& x, const AudioType& y); diff --git a/chromium/media/base/pipeline_impl.cc b/chromium/media/base/pipeline_impl.cc index 9056c8b809d..8104646400b 100644 --- a/chromium/media/base/pipeline_impl.cc +++ b/chromium/media/base/pipeline_impl.cc @@ -470,7 +470,7 @@ void PipelineImpl::RendererWrapper::SetVolume(float volume) { DCHECK(media_task_runner_->BelongsToCurrentThread()); volume_ = volume; - if (state_ == kPlaying) + if (shared_state_.renderer) shared_state_.renderer->SetVolume(volume_); } diff --git a/chromium/media/base/pipeline_impl_unittest.cc b/chromium/media/base/pipeline_impl_unittest.cc index a19dcac8799..cb31db062f6 100644 --- a/chromium/media/base/pipeline_impl_unittest.cc +++ b/chromium/media/base/pipeline_impl_unittest.cc @@ -639,6 +639,30 @@ TEST_F(PipelineImplTest, SetVolume) { base::RunLoop().RunUntilIdle(); } +TEST_F(PipelineImplTest, SetVolumeDuringStartup) { + CreateAudioStream(); + SetDemuxerExpectations(); + + // The audio renderer should receive two calls to SetVolume(). + float expected = 0.5f; + EXPECT_CALL(*renderer_, SetVolume(expected)).Times(2); + EXPECT_CALL(callbacks_, OnStart(PIPELINE_OK)); + EXPECT_CALL(callbacks_, OnMetadata(_)) + .WillOnce(RunOnceClosure(base::BindOnce(&PipelineImpl::SetVolume, + base::Unretained(pipeline_.get()), + expected))); + ExpectRendererInitialization(); + EXPECT_CALL(*renderer_, SetPlaybackRate(0.0)); + EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_)) + .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH, + BUFFERING_CHANGE_REASON_UNKNOWN)); + EXPECT_CALL(callbacks_, + OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, + BUFFERING_CHANGE_REASON_UNKNOWN)); + StartPipeline(); + base::RunLoop().RunUntilIdle(); +} + TEST_F(PipelineImplTest, SetPreservesPitch) { CreateAudioStream(); SetDemuxerExpectations(); diff --git a/chromium/media/base/status_codes.h b/chromium/media/base/status_codes.h index 3aed86d58af..5c2b7feb3f1 100644 --- a/chromium/media/base/status_codes.h +++ b/chromium/media/base/status_codes.h @@ -27,6 +27,9 @@ using StatusCodeType = int32_t; enum class StatusCode : StatusCodeType { kOk = 0, + // General errors: 0x00 + kAborted = 0x00000001, + // Decoder Errors: 0x01 kDecoderInitializeNeverCompleted = 0x00000101, kDecoderFailedDecode = 0x00000102, @@ -44,6 +47,9 @@ enum class StatusCode : StatusCodeType { kInitializationUnspecifiedFailure = 0x0000010C, kDecoderVideoFrameConstructionFailed = 0x0000010D, kMakeContextCurrentFailed = 0x0000010E, + // This is a temporary error for use only by existing code during the + // DecodeStatus => Status conversion. + kDecodeErrorDoNotUse = 0x0000010F, // Windows Errors: 0x02 kWindowsWrappedHresult = 0x00000201, @@ -116,6 +122,23 @@ enum class StatusCode : StatusCodeType { kVaapiBadImageSize = 0x0000070C, kVaapiNoTexture = 0x0000070D, + // Format errors: 0x08 + kH264ParsingError = 0x00000801, + kH264BufferTooSmall = 0x00000802, + + // DecodeStatus temporary codes. These names were chosen to match the + // DecodeStatus enum, so that un-converted code can DecodeStatus::OK/etc. + // Note that OK must result in Status::is_ok(), since converted code will + // check for it. These will be removed when the conversion is complete. + // + // DO NOT ADD NEW USES OF OK/ABORTED/DECODE_ERROR. + OK = kOk, // Everything went as planned. + // Read aborted due to Reset() during pending read. + ABORTED = kAborted, // Read aborted due to Reset() during pending read. + // Decoder returned decode error. Note: Prefixed by DECODE_ + // since ERROR is a reserved name (special macro) on Windows. + DECODE_ERROR = kDecodeErrorDoNotUse, + // Special codes kGenericErrorPleaseRemove = 0x79999999, kCodeOnlyForTesting = std::numeric_limits<StatusCodeType>::max(), diff --git a/chromium/media/base/supported_types.cc b/chromium/media/base/supported_types.cc index f3ccd25f1c4..2047bb52af4 100644 --- a/chromium/media/base/supported_types.cc +++ b/chromium/media/base/supported_types.cc @@ -35,14 +35,14 @@ namespace media { namespace { -bool IsSupportedHdrMetadata(const HdrMetadataType& hdr_metadata_type) { +bool IsSupportedHdrMetadata(const gl::HdrMetadataType& hdr_metadata_type) { switch (hdr_metadata_type) { - case HdrMetadataType::kNone: + case gl::HdrMetadataType::kNone: return true; - case HdrMetadataType::kSmpteSt2086: - case HdrMetadataType::kSmpteSt2094_10: - case HdrMetadataType::kSmpteSt2094_40: + case gl::HdrMetadataType::kSmpteSt2086: + case gl::HdrMetadataType::kSmpteSt2094_10: + case gl::HdrMetadataType::kSmpteSt2094_40: return false; } diff --git a/chromium/media/base/supported_types_unittest.cc b/chromium/media/base/supported_types_unittest.cc index 48013e18e31..15232a77bb2 100644 --- a/chromium/media/base/supported_types_unittest.cc +++ b/chromium/media/base/supported_types_unittest.cc @@ -27,80 +27,71 @@ const bool kMpeg4Supported = false; TEST(SupportedTypesTest, IsSupportedVideoTypeBasics) { // Default to common 709. - const media::VideoColorSpace kColorSpace = media::VideoColorSpace::REC709(); + const VideoColorSpace kColorSpace = VideoColorSpace::REC709(); // Some codecs do not have a notion of level. const int kUnspecifiedLevel = 0; // Expect support for baseline configuration of known codecs. - EXPECT_TRUE(IsSupportedVideoType({media::kCodecVP8, media::VP8PROFILE_ANY, - kUnspecifiedLevel, kColorSpace})); - EXPECT_TRUE( - IsSupportedVideoType({media::kCodecVP9, media::VP9PROFILE_PROFILE0, - kUnspecifiedLevel, kColorSpace})); - EXPECT_TRUE(IsSupportedVideoType({media::kCodecTheora, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP8, VP8PROFILE_ANY, kUnspecifiedLevel, kColorSpace})); + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, kColorSpace})); + EXPECT_TRUE(IsSupportedVideoType({kCodecTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, kColorSpace})); // Expect non-support for the following. - EXPECT_FALSE(IsSupportedVideoType({media::kUnknownVideoCodec, - media::VIDEO_CODEC_PROFILE_UNKNOWN, - kUnspecifiedLevel, kColorSpace})); - EXPECT_FALSE(IsSupportedVideoType({media::kCodecVC1, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + EXPECT_FALSE( + IsSupportedVideoType({kUnknownVideoCodec, VIDEO_CODEC_PROFILE_UNKNOWN, + kUnspecifiedLevel, kColorSpace})); + EXPECT_FALSE(IsSupportedVideoType({kCodecVC1, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, kColorSpace})); - EXPECT_FALSE(IsSupportedVideoType({media::kCodecMPEG2, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + EXPECT_FALSE(IsSupportedVideoType({kCodecMPEG2, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, kColorSpace})); - EXPECT_FALSE(IsSupportedVideoType({media::kCodecHEVC, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + EXPECT_FALSE(IsSupportedVideoType({kCodecHEVC, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, kColorSpace})); // Expect conditional support for the following. EXPECT_EQ( kPropCodecsEnabled, - IsSupportedVideoType( - {media::kCodecH264, media::H264PROFILE_BASELINE, 1, kColorSpace})); + IsSupportedVideoType({kCodecH264, H264PROFILE_BASELINE, 1, kColorSpace})); EXPECT_EQ(kMpeg4Supported, - IsSupportedVideoType({media::kCodecMPEG4, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + IsSupportedVideoType({kCodecMPEG4, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, kColorSpace})); } TEST(SupportedTypesTest, IsSupportedVideoType_VP9TransferFunctions) { size_t num_found = 0; // TODO(hubbe): Verify support for HDR codecs when color management enabled. - const std::set<media::VideoColorSpace::TransferID> kSupportedTransfers = { - media::VideoColorSpace::TransferID::GAMMA22, - media::VideoColorSpace::TransferID::UNSPECIFIED, - media::VideoColorSpace::TransferID::BT709, - media::VideoColorSpace::TransferID::SMPTE170M, - media::VideoColorSpace::TransferID::BT2020_10, - media::VideoColorSpace::TransferID::BT2020_12, - media::VideoColorSpace::TransferID::IEC61966_2_1, - media::VideoColorSpace::TransferID::GAMMA28, - media::VideoColorSpace::TransferID::SMPTE240M, - media::VideoColorSpace::TransferID::LINEAR, - media::VideoColorSpace::TransferID::LOG, - media::VideoColorSpace::TransferID::LOG_SQRT, - media::VideoColorSpace::TransferID::BT1361_ECG, - media::VideoColorSpace::TransferID::SMPTEST2084, - media::VideoColorSpace::TransferID::IEC61966_2_4, - media::VideoColorSpace::TransferID::SMPTEST428_1, - media::VideoColorSpace::TransferID::ARIB_STD_B67, + const std::set<VideoColorSpace::TransferID> kSupportedTransfers = { + VideoColorSpace::TransferID::GAMMA22, + VideoColorSpace::TransferID::UNSPECIFIED, + VideoColorSpace::TransferID::BT709, + VideoColorSpace::TransferID::SMPTE170M, + VideoColorSpace::TransferID::BT2020_10, + VideoColorSpace::TransferID::BT2020_12, + VideoColorSpace::TransferID::IEC61966_2_1, + VideoColorSpace::TransferID::GAMMA28, + VideoColorSpace::TransferID::SMPTE240M, + VideoColorSpace::TransferID::LINEAR, + VideoColorSpace::TransferID::LOG, + VideoColorSpace::TransferID::LOG_SQRT, + VideoColorSpace::TransferID::BT1361_ECG, + VideoColorSpace::TransferID::SMPTEST2084, + VideoColorSpace::TransferID::IEC61966_2_4, + VideoColorSpace::TransferID::SMPTEST428_1, + VideoColorSpace::TransferID::ARIB_STD_B67, }; - for (int i = 0; i <= (1 << (8 * sizeof(media::VideoColorSpace::TransferID))); - i++) { - media::VideoColorSpace color_space = media::VideoColorSpace::REC709(); - color_space.transfer = media::VideoColorSpace::GetTransferID(i); + for (int i = 0; i <= (1 << (8 * sizeof(VideoColorSpace::TransferID))); i++) { + VideoColorSpace color_space = VideoColorSpace::REC709(); + color_space.transfer = VideoColorSpace::GetTransferID(i); bool found = kSupportedTransfers.find(color_space.transfer) != kSupportedTransfers.end(); if (found) num_found++; - EXPECT_EQ(found, IsSupportedVideoType({media::kCodecVP9, - media::VP9PROFILE_PROFILE0, 1, - color_space})); + EXPECT_EQ(found, IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, 1, color_space})); } EXPECT_EQ(kSupportedTransfers.size(), num_found); } @@ -108,31 +99,29 @@ TEST(SupportedTypesTest, IsSupportedVideoType_VP9TransferFunctions) { TEST(SupportedTypesTest, IsSupportedVideoType_VP9Primaries) { size_t num_found = 0; // TODO(hubbe): Verify support for HDR codecs when color management enabled. - const std::set<media::VideoColorSpace::PrimaryID> kSupportedPrimaries = { - media::VideoColorSpace::PrimaryID::BT709, - media::VideoColorSpace::PrimaryID::UNSPECIFIED, - media::VideoColorSpace::PrimaryID::BT470M, - media::VideoColorSpace::PrimaryID::BT470BG, - media::VideoColorSpace::PrimaryID::SMPTE170M, - media::VideoColorSpace::PrimaryID::SMPTE240M, - media::VideoColorSpace::PrimaryID::FILM, - media::VideoColorSpace::PrimaryID::BT2020, - media::VideoColorSpace::PrimaryID::SMPTEST428_1, - media::VideoColorSpace::PrimaryID::SMPTEST431_2, - media::VideoColorSpace::PrimaryID::SMPTEST432_1, + const std::set<VideoColorSpace::PrimaryID> kSupportedPrimaries = { + VideoColorSpace::PrimaryID::BT709, + VideoColorSpace::PrimaryID::UNSPECIFIED, + VideoColorSpace::PrimaryID::BT470M, + VideoColorSpace::PrimaryID::BT470BG, + VideoColorSpace::PrimaryID::SMPTE170M, + VideoColorSpace::PrimaryID::SMPTE240M, + VideoColorSpace::PrimaryID::FILM, + VideoColorSpace::PrimaryID::BT2020, + VideoColorSpace::PrimaryID::SMPTEST428_1, + VideoColorSpace::PrimaryID::SMPTEST431_2, + VideoColorSpace::PrimaryID::SMPTEST432_1, }; - for (int i = 0; i <= (1 << (8 * sizeof(media::VideoColorSpace::PrimaryID))); - i++) { - media::VideoColorSpace color_space = media::VideoColorSpace::REC709(); - color_space.primaries = media::VideoColorSpace::GetPrimaryID(i); + for (int i = 0; i <= (1 << (8 * sizeof(VideoColorSpace::PrimaryID))); i++) { + VideoColorSpace color_space = VideoColorSpace::REC709(); + color_space.primaries = VideoColorSpace::GetPrimaryID(i); bool found = kSupportedPrimaries.find(color_space.primaries) != kSupportedPrimaries.end(); if (found) num_found++; - EXPECT_EQ(found, IsSupportedVideoType({media::kCodecVP9, - media::VP9PROFILE_PROFILE0, 1, - color_space})); + EXPECT_EQ(found, IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, 1, color_space})); } EXPECT_EQ(kSupportedPrimaries.size(), num_found); } @@ -140,87 +129,97 @@ TEST(SupportedTypesTest, IsSupportedVideoType_VP9Primaries) { TEST(SupportedTypesTest, IsSupportedVideoType_VP9Matrix) { size_t num_found = 0; // TODO(hubbe): Verify support for HDR codecs when color management enabled. - const std::set<media::VideoColorSpace::MatrixID> kSupportedMatrix = { - media::VideoColorSpace::MatrixID::BT709, - media::VideoColorSpace::MatrixID::UNSPECIFIED, - media::VideoColorSpace::MatrixID::BT470BG, - media::VideoColorSpace::MatrixID::SMPTE170M, - media::VideoColorSpace::MatrixID::BT2020_NCL, - media::VideoColorSpace::MatrixID::RGB, - media::VideoColorSpace::MatrixID::FCC, - media::VideoColorSpace::MatrixID::SMPTE240M, - media::VideoColorSpace::MatrixID::YCOCG, - media::VideoColorSpace::MatrixID::YDZDX, - media::VideoColorSpace::MatrixID::BT2020_CL, + const std::set<VideoColorSpace::MatrixID> kSupportedMatrix = { + VideoColorSpace::MatrixID::BT709, + VideoColorSpace::MatrixID::UNSPECIFIED, + VideoColorSpace::MatrixID::BT470BG, + VideoColorSpace::MatrixID::SMPTE170M, + VideoColorSpace::MatrixID::BT2020_NCL, + VideoColorSpace::MatrixID::RGB, + VideoColorSpace::MatrixID::FCC, + VideoColorSpace::MatrixID::SMPTE240M, + VideoColorSpace::MatrixID::YCOCG, + VideoColorSpace::MatrixID::YDZDX, + VideoColorSpace::MatrixID::BT2020_CL, }; - for (int i = 0; i <= (1 << (8 * sizeof(media::VideoColorSpace::MatrixID))); - i++) { - media::VideoColorSpace color_space = media::VideoColorSpace::REC709(); - color_space.matrix = media::VideoColorSpace::GetMatrixID(i); + for (int i = 0; i <= (1 << (8 * sizeof(VideoColorSpace::MatrixID))); i++) { + VideoColorSpace color_space = VideoColorSpace::REC709(); + color_space.matrix = VideoColorSpace::GetMatrixID(i); bool found = kSupportedMatrix.find(color_space.matrix) != kSupportedMatrix.end(); if (found) num_found++; - EXPECT_EQ(found, IsSupportedVideoType({media::kCodecVP9, - media::VP9PROFILE_PROFILE0, 1, - color_space})); + EXPECT_EQ(found, IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, 1, color_space})); } EXPECT_EQ(kSupportedMatrix.size(), num_found); } +TEST(SupportedTypesTest, IsSupportedVideoType_VP9Profiles) { + // Default to common 709. + const VideoColorSpace kColorSpace = VideoColorSpace::REC709(); + + // Some codecs do not have a notion of level. + const int kUnspecifiedLevel = 0; + + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, kColorSpace})); + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE1, kUnspecifiedLevel, kColorSpace})); + +// VP9 Profile2 are supported on x86, ChromeOS on ARM and Mac/Win on ARM64. +// See third_party/libvpx/BUILD.gn. +#if defined(ARCH_CPU_X86_FAMILY) || \ + (defined(ARCH_CPU_ARM_FAMILY) && defined(OS_CHROMEOS)) || \ + (defined(ARCH_CPU_ARM64) && (defined(OS_MAC) || defined(OS_WIN))) + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE2, kUnspecifiedLevel, kColorSpace})); +#endif +} + TEST(SupportedTypesTest, IsSupportedAudioTypeWithSpatialRenderingBasics) { const bool is_spatial_rendering = true; // Dolby Atmos = E-AC3 (Dolby Digital Plus) + spatialRendering. Currently not // supported. EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecEAC3, AudioCodecProfile::kUnknown, is_spatial_rendering})); + {kCodecEAC3, AudioCodecProfile::kUnknown, is_spatial_rendering})); // Expect non-support for codecs with which there is no spatial audio format. EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecAAC, AudioCodecProfile::kUnknown, is_spatial_rendering})); + {kCodecAAC, AudioCodecProfile::kUnknown, is_spatial_rendering})); EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecMP3, AudioCodecProfile::kUnknown, is_spatial_rendering})); + {kCodecMP3, AudioCodecProfile::kUnknown, is_spatial_rendering})); EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecPCM, AudioCodecProfile::kUnknown, is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecVorbis, AudioCodecProfile::kUnknown, - is_spatial_rendering})); + {kCodecPCM, AudioCodecProfile::kUnknown, is_spatial_rendering})); EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecFLAC, AudioCodecProfile::kUnknown, is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecAMR_NB, AudioCodecProfile::kUnknown, - is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecAMR_WB, AudioCodecProfile::kUnknown, - is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecPCM_MULAW, AudioCodecProfile::kUnknown, - is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecGSM_MS, AudioCodecProfile::kUnknown, - is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecPCM_S16BE, AudioCodecProfile::kUnknown, - is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecPCM_S24BE, AudioCodecProfile::kUnknown, - is_spatial_rendering})); + {kCodecVorbis, AudioCodecProfile::kUnknown, is_spatial_rendering})); EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecOpus, AudioCodecProfile::kUnknown, is_spatial_rendering})); - EXPECT_FALSE( - IsSupportedAudioType({media::kCodecPCM_ALAW, AudioCodecProfile::kUnknown, - is_spatial_rendering})); + {kCodecFLAC, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecAMR_NB, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecAMR_WB, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecPCM_MULAW, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecGSM_MS, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecPCM_S16BE, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecPCM_S24BE, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecOpus, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecPCM_ALAW, AudioCodecProfile::kUnknown, is_spatial_rendering})); EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecALAC, AudioCodecProfile::kUnknown, is_spatial_rendering})); + {kCodecALAC, AudioCodecProfile::kUnknown, is_spatial_rendering})); EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecAC3, AudioCodecProfile::kUnknown, is_spatial_rendering})); - EXPECT_FALSE(IsSupportedAudioType({media::kCodecMpegHAudio, - AudioCodecProfile::kUnknown, - is_spatial_rendering})); - EXPECT_FALSE(IsSupportedAudioType({media::kUnknownAudioCodec, - AudioCodecProfile::kUnknown, - is_spatial_rendering})); + {kCodecAC3, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kCodecMpegHAudio, AudioCodecProfile::kUnknown, is_spatial_rendering})); + EXPECT_FALSE(IsSupportedAudioType( + {kUnknownAudioCodec, AudioCodecProfile::kUnknown, is_spatial_rendering})); } TEST(SupportedTypesTest, XHE_AACSupportedOnAndroidOnly) { @@ -231,67 +230,60 @@ TEST(SupportedTypesTest, XHE_AACSupportedOnAndroidOnly) { base::android::BuildInfo::GetInstance()->sdk_int() >= base::android::SDK_VERSION_P; - EXPECT_EQ(is_supported, - IsSupportedAudioType( - {media::kCodecAAC, AudioCodecProfile::kXHE_AAC, false})); + EXPECT_EQ(is_supported, IsSupportedAudioType( + {kCodecAAC, AudioCodecProfile::kXHE_AAC, false})); #else - EXPECT_FALSE(IsSupportedAudioType( - {media::kCodecAAC, AudioCodecProfile::kXHE_AAC, false})); + EXPECT_FALSE( + IsSupportedAudioType({kCodecAAC, AudioCodecProfile::kXHE_AAC, false})); #endif } TEST(SupportedTypesTest, IsSupportedVideoTypeWithHdrMetadataBasics) { // Default to common 709. - media::VideoColorSpace color_space = media::VideoColorSpace::REC709(); + VideoColorSpace color_space = VideoColorSpace::REC709(); // Some codecs do not have a notion of level. const int kUnspecifiedLevel = 0; // Expect support for baseline configuration of known codecs. - EXPECT_TRUE(IsSupportedVideoType({media::kCodecVP8, media::VP8PROFILE_ANY, - kUnspecifiedLevel, color_space})); - EXPECT_TRUE( - IsSupportedVideoType({media::kCodecVP9, media::VP9PROFILE_PROFILE0, - kUnspecifiedLevel, color_space})); - EXPECT_TRUE(IsSupportedVideoType({media::kCodecTheora, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space})); + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space})); + EXPECT_TRUE(IsSupportedVideoType({kCodecTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, color_space})); // All combinations of combinations of color gamuts and transfer functions // should be supported. - color_space.primaries = media::VideoColorSpace::PrimaryID::SMPTEST431_2; - color_space.transfer = media::VideoColorSpace::TransferID::SMPTEST2084; - EXPECT_TRUE(IsSupportedVideoType({media::kCodecVP8, media::VP8PROFILE_ANY, - kUnspecifiedLevel, color_space})); - EXPECT_TRUE( - IsSupportedVideoType({media::kCodecVP9, media::VP9PROFILE_PROFILE0, - kUnspecifiedLevel, color_space})); - EXPECT_TRUE(IsSupportedVideoType({media::kCodecTheora, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + color_space.primaries = VideoColorSpace::PrimaryID::SMPTEST431_2; + color_space.transfer = VideoColorSpace::TransferID::SMPTEST2084; + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space})); + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space})); + EXPECT_TRUE(IsSupportedVideoType({kCodecTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, color_space})); - color_space.primaries = media::VideoColorSpace::PrimaryID::BT2020; - color_space.transfer = media::VideoColorSpace::TransferID::ARIB_STD_B67; - EXPECT_TRUE(IsSupportedVideoType({media::kCodecVP8, media::VP8PROFILE_ANY, - kUnspecifiedLevel, color_space})); - EXPECT_TRUE( - IsSupportedVideoType({media::kCodecVP9, media::VP9PROFILE_PROFILE0, - kUnspecifiedLevel, color_space})); - EXPECT_TRUE(IsSupportedVideoType({media::kCodecTheora, - media::VIDEO_CODEC_PROFILE_UNKNOWN, + color_space.primaries = VideoColorSpace::PrimaryID::BT2020; + color_space.transfer = VideoColorSpace::TransferID::ARIB_STD_B67; + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space})); + EXPECT_TRUE(IsSupportedVideoType( + {kCodecVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space})); + EXPECT_TRUE(IsSupportedVideoType({kCodecTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, color_space})); // No HDR metadata types are supported. - EXPECT_FALSE(IsSupportedVideoType({media::kCodecVP8, media::VP8PROFILE_ANY, - kUnspecifiedLevel, color_space, - media::HdrMetadataType::kSmpteSt2086})); + EXPECT_FALSE( + IsSupportedVideoType({kCodecVP8, VP8PROFILE_ANY, kUnspecifiedLevel, + color_space, gl::HdrMetadataType::kSmpteSt2086})); - EXPECT_FALSE(IsSupportedVideoType({media::kCodecVP8, media::VP8PROFILE_ANY, + EXPECT_FALSE(IsSupportedVideoType({kCodecVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space, - media::HdrMetadataType::kSmpteSt2094_10})); + gl::HdrMetadataType::kSmpteSt2094_10})); - EXPECT_FALSE(IsSupportedVideoType({media::kCodecVP8, media::VP8PROFILE_ANY, + EXPECT_FALSE(IsSupportedVideoType({kCodecVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space, - media::HdrMetadataType::kSmpteSt2094_40})); + gl::HdrMetadataType::kSmpteSt2094_40})); } } // namespace media diff --git a/chromium/media/base/test_helpers.cc b/chromium/media/base/test_helpers.cc index ed2b5f6243e..73ac060dc52 100644 --- a/chromium/media/base/test_helpers.cc +++ b/chromium/media/base/test_helpers.cc @@ -244,6 +244,19 @@ VideoDecoderConfig TestVideoConfig::ExtraLargeEncrypted(VideoCodec codec) { } // static +VideoDecoderConfig TestVideoConfig::Custom(gfx::Size size, VideoCodec codec) { + return GetTestConfig(codec, MinProfile(codec), VideoColorSpace::JPEG(), + VIDEO_ROTATION_0, size, false); +} + +// static +VideoDecoderConfig TestVideoConfig::CustomEncrypted(gfx::Size size, + VideoCodec codec) { + return GetTestConfig(codec, MinProfile(codec), VideoColorSpace::JPEG(), + VIDEO_ROTATION_0, size, true); +} + +// static gfx::Size TestVideoConfig::NormalCodedSize() { return kNormalSize; } diff --git a/chromium/media/base/test_helpers.h b/chromium/media/base/test_helpers.h index d2143409117..3a0df8eda59 100644 --- a/chromium/media/base/test_helpers.h +++ b/chromium/media/base/test_helpers.h @@ -110,6 +110,11 @@ class TestVideoConfig { static VideoDecoderConfig ExtraLarge(VideoCodec codec = kCodecVP8); static VideoDecoderConfig ExtraLargeEncrypted(VideoCodec codec = kCodecVP8); + static VideoDecoderConfig Custom(gfx::Size size, + VideoCodec codec = kCodecVP8); + static VideoDecoderConfig CustomEncrypted(gfx::Size size, + VideoCodec codec = kCodecVP8); + // Returns coded size for Normal and Large config. static gfx::Size NormalCodedSize(); static gfx::Size LargeCodedSize(); @@ -219,7 +224,7 @@ MATCHER_P(SameStatusCode, status, "") { return arg.code() == status.code(); } -// Compares two an |arg| Status to a StatusCode provided +// Compares an `arg` Status.code() to a test-supplied StatusCode. MATCHER_P(HasStatusCode, status_code, "") { return arg.code() == status_code; } @@ -228,6 +233,12 @@ MATCHER(IsOkStatus, "") { return arg.is_ok(); } +// True if and only if the Status would be interpreted as an error from a decode +// callback (not okay, not aborted). +MATCHER(IsDecodeErrorStatus, "") { + return !arg.is_ok() && arg.code() != StatusCode::kAborted; +} + // Compares two {Audio|Video}DecoderConfigs MATCHER_P(DecoderConfigEq, config, "") { return arg.Matches(config); diff --git a/chromium/media/base/use_after_free_checker.h b/chromium/media/base/use_after_free_checker.h new file mode 100644 index 00000000000..aefcaae2b59 --- /dev/null +++ b/chromium/media/base/use_after_free_checker.h @@ -0,0 +1,60 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_USE_AFTER_FREE_CHECKER_H_ +#define MEDIA_BASE_USE_AFTER_FREE_CHECKER_H_ + +#include "base/debug/dump_without_crashing.h" +#include "base/location.h" +#include "media/base/media_export.h" + +namespace { + +static base::debug::CrashKeyString* crash_key_string() { + static base::debug::CrashKeyString* string = nullptr; + if (!string) { + string = base::debug::AllocateCrashKeyString( + "use_after_free_checker", base::debug::CrashKeySize::Size32); + } + + return string; +} + +} // namespace + +namespace media { + +// Maintains a guard value from ctor => dtor, and causes a crash if it's ever +// found to be in an incorrect state. Includes a crash key that identifies +// whether itse use-after-free or corruption. +class MEDIA_EXPORT UseAfterFreeChecker { + public: + inline ~UseAfterFreeChecker() { + check(); + state_ = State::kDestructed; + } + + void check() { + if (state_ != State::kConstructed) { + base::debug::ScopedCrashKeyString scoped( + crash_key_string(), + state_ == State::kDestructed ? "destructed" : "corrupt"); + CHECK(false); + } + } + + private: + enum State : uint64_t { + kConstructed = 0x80C0FFEE, + kDestructed = 0xDEADC0DE, + }; + + // Declare this as an int rather than State, to avoid undefinedness if it gets + // overwritten with an arbitrary value. + uint64_t state_ = State::kConstructed; +}; + +} // namespace media + +#endif // MEDIA_BASE_USE_AFTER_FREE_CHECKER_H_ diff --git a/chromium/media/base/user_input_monitor_linux.cc b/chromium/media/base/user_input_monitor_linux.cc index 397bae21a7b..13c373fadfd 100644 --- a/chromium/media/base/user_input_monitor_linux.cc +++ b/chromium/media/base/user_input_monitor_linux.cc @@ -115,9 +115,10 @@ void UserInputMonitorLinuxCore::DispatchXEvent(x11::Event* event) { DCHECK(io_task_runner_->BelongsToCurrentThread()); auto* raw = event->As<x11::Input::RawDeviceEvent>(); - DCHECK(raw); - DCHECK(raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress || - raw->opcode == x11::Input::RawDeviceEvent::RawKeyRelease); + if (!raw || (raw->opcode != x11::Input::RawDeviceEvent::RawKeyPress && + raw->opcode != x11::Input::RawDeviceEvent::RawKeyRelease)) { + return; + } ui::EventType type = raw->opcode == x11::Input::RawDeviceEvent::RawKeyPress ? ui::ET_KEY_PRESSED @@ -179,7 +180,7 @@ void UserInputMonitorLinuxCore::StartMonitor() { // Register OnConnectionData() to be called every time there is something to // read from |connection_|. watch_controller_ = base::FileDescriptorWatcher::WatchReadable( - ConnectionNumber(connection_->display()), + connection_->GetFd(), base::BindRepeating(&UserInputMonitorLinuxCore::OnConnectionData, base::Unretained(this))); diff --git a/chromium/media/base/video_decoder.h b/chromium/media/base/video_decoder.h index 145ee96dacf..b66186c625e 100644 --- a/chromium/media/base/video_decoder.h +++ b/chromium/media/base/video_decoder.h @@ -7,14 +7,12 @@ #include <string> -#include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "media/base/decode_status.h" #include "media/base/decoder.h" #include "media/base/media_export.h" #include "media/base/pipeline_status.h" -#include "media/base/status.h" #include "media/base/waiting.h" #include "ui/gfx/geometry/size.h" @@ -27,8 +25,8 @@ class VideoFrame; class MEDIA_EXPORT VideoDecoder : public Decoder { public: - // Callback for VideoDecoder initialization. - using InitCB = base::OnceCallback<void(Status status)>; + // Callback for Decoder initialization. + using InitCB = base::OnceCallback<void(Status)>; // Callback for VideoDecoder to return a decoded frame whenever it becomes // available. Only non-EOS frames should be returned via this callback. @@ -36,8 +34,11 @@ class MEDIA_EXPORT VideoDecoder : public Decoder { // Callback type for Decode(). Called after the decoder has completed decoding // corresponding DecoderBuffer, indicating that it's ready to accept another - // buffer to decode. - using DecodeCB = base::OnceCallback<void(DecodeStatus)>; + // buffer to decode. |kOk| implies success, |kAborted| implies that the + // decode was aborted, which does not necessarily indicate an error. For + // example, a Reset() can trigger this. Any other status code indicates that + // the decoder encountered an error, and must be reset. + using DecodeCB = base::OnceCallback<void(Status)>; VideoDecoder(); ~VideoDecoder() override; diff --git a/chromium/media/base/video_decoder_config.h b/chromium/media/base/video_decoder_config.h index 052adc4f6d6..01ad01d48ca 100644 --- a/chromium/media/base/video_decoder_config.h +++ b/chromium/media/base/video_decoder_config.h @@ -13,7 +13,6 @@ #include "base/macros.h" #include "base/optional.h" #include "media/base/encryption_scheme.h" -#include "media/base/hdr_metadata.h" #include "media/base/media_export.h" #include "media/base/video_codecs.h" #include "media/base/video_color_space.h" @@ -21,6 +20,7 @@ #include "media/base/video_types.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/hdr_metadata.h" namespace media { @@ -154,10 +154,10 @@ class MEDIA_EXPORT VideoDecoderConfig { const VideoColorSpace& color_space_info() const { return color_space_info_; } // Dynamic range of the image data. - void set_hdr_metadata(const HDRMetadata& hdr_metadata) { + void set_hdr_metadata(const gl::HDRMetadata& hdr_metadata) { hdr_metadata_ = hdr_metadata; } - const base::Optional<HDRMetadata>& hdr_metadata() const { + const base::Optional<gl::HDRMetadata>& hdr_metadata() const { return hdr_metadata_; } @@ -192,7 +192,7 @@ class MEDIA_EXPORT VideoDecoderConfig { EncryptionScheme encryption_scheme_ = EncryptionScheme::kUnencrypted; VideoColorSpace color_space_info_; - base::Optional<HDRMetadata> hdr_metadata_; + base::Optional<gl::HDRMetadata> hdr_metadata_; // Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler // generated copy constructor and assignment operator. Since the extra data is diff --git a/chromium/media/base/video_encoder.h b/chromium/media/base/video_encoder.h index 51b5247ae5b..9b1badf5835 100644 --- a/chromium/media/base/video_encoder.h +++ b/chromium/media/base/video_encoder.h @@ -26,10 +26,10 @@ struct MEDIA_EXPORT VideoEncoderOutput { // Feel free take this buffer out and use underlying memory as is without // copying. std::unique_ptr<uint8_t[]> data; - size_t size; + size_t size = 0; base::TimeDelta timestamp; - bool key_frame; + bool key_frame = false; }; class MEDIA_EXPORT VideoEncoder { @@ -47,9 +47,16 @@ class MEDIA_EXPORT VideoEncoder { base::Optional<int> keyframe_interval = 10000; }; + // A sequence of codec specific bytes, commonly known as extradata. + // If available, it should be given to the decoder as part of the + // decoder config. + using CodecDescription = std::vector<uint8_t>; + // Callback for VideoEncoder to report an encoded video frame whenever it // becomes available. - using OutputCB = base::RepeatingCallback<void(VideoEncoderOutput output)>; + using OutputCB = + base::RepeatingCallback<void(VideoEncoderOutput output, + base::Optional<CodecDescription>)>; // Callback to report success and errors in encoder calls. using StatusCB = base::OnceCallback<void(Status error)>; diff --git a/chromium/media/base/video_frame.cc b/chromium/media/base/video_frame.cc index 35490eb429a..e889678706f 100644 --- a/chromium/media/base/video_frame.cc +++ b/chromium/media/base/video_frame.cc @@ -27,6 +27,9 @@ #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/gpu_memory_buffer.h" +#if defined(OS_MAC) +#include "ui/gfx/mac/io_surface.h" +#endif namespace media { @@ -543,6 +546,45 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvaData( } // static +scoped_refptr<VideoFrame> VideoFrame::WrapExternalYuvData( + VideoPixelFormat format, + const gfx::Size& coded_size, + const gfx::Rect& visible_rect, + const gfx::Size& natural_size, + int32_t y_stride, + int32_t uv_stride, + uint8_t* y_data, + uint8_t* uv_data, + base::TimeDelta timestamp) { + const StorageType storage = STORAGE_UNOWNED_MEMORY; + if (!IsValidConfig(format, storage, coded_size, visible_rect, natural_size)) { + DLOG(ERROR) << __func__ << " Invalid config." + << ConfigToString(format, storage, coded_size, visible_rect, + natural_size); + return nullptr; + } + + if (NumPlanes(format) != 2) { + DLOG(ERROR) << "Expecting Y, UV planes to be present for the video format."; + return nullptr; + } + + auto layout = VideoFrameLayout::CreateWithStrides(format, coded_size, + {y_stride, uv_stride}); + if (!layout) { + DLOG(ERROR) << "Invalid layout"; + return nullptr; + } + + scoped_refptr<VideoFrame> frame( + new VideoFrame(*layout, storage, visible_rect, natural_size, timestamp)); + frame->data_[kYPlane] = y_data; + frame->data_[kUVPlane] = uv_data; + + return frame; +} + +// static scoped_refptr<VideoFrame> VideoFrame::WrapExternalGpuMemoryBuffer( const gfx::Rect& visible_rect, const gfx::Size& natural_size, @@ -564,13 +606,27 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalGpuMemoryBuffer( return nullptr; } + uint64_t modifier = gfx::NativePixmapHandle::kNoModifier; +#if defined(OS_LINUX) || defined(OS_CHROMEOS) + if (gpu_memory_buffer->GetType() == gfx::NATIVE_PIXMAP) { + const auto gmb_handle = gpu_memory_buffer->CloneHandle(); + if (gmb_handle.is_null() || + gmb_handle.native_pixmap_handle.planes.empty()) { + DLOG(ERROR) << "Failed to clone the GpuMemoryBufferHandle"; + return nullptr; + } + modifier = gmb_handle.native_pixmap_handle.modifier; + } +#endif + const size_t num_planes = NumberOfPlanesForLinearBufferFormat(gpu_memory_buffer->GetFormat()); std::vector<int32_t> strides; for (size_t i = 0; i < num_planes; ++i) strides.push_back(gpu_memory_buffer->stride(i)); - const auto layout = VideoFrameLayout::CreateWithStrides(*format, coded_size, - std::move(strides)); + const auto layout = VideoFrameLayout::CreateWithStrides( + *format, coded_size, std::move(strides), + VideoFrameLayout::kBufferAddressAlignment, modifier); if (!layout) { DLOG(ERROR) << __func__ << " Invalid layout"; return nullptr; @@ -633,6 +689,72 @@ scoped_refptr<VideoFrame> VideoFrame::WrapExternalDmabufs( #if defined(OS_MAC) // static +scoped_refptr<VideoFrame> VideoFrame::WrapIOSurface( + gfx::GpuMemoryBufferHandle handle, + const gfx::Rect& visible_rect, + base::TimeDelta timestamp) { + if (handle.type != gfx::GpuMemoryBufferType::IO_SURFACE_BUFFER) { + DLOG(ERROR) << "Non-IOSurface handle."; + return nullptr; + } + base::ScopedCFTypeRef<IOSurfaceRef> io_surface = + gfx::IOSurfaceMachPortToIOSurface(std::move(handle.mach_port)); + if (!io_surface) { + return nullptr; + } + + // Only support NV12 IOSurfaces. + const OSType cv_pixel_format = IOSurfaceGetPixelFormat(io_surface); + if (cv_pixel_format != kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) { + DLOG(ERROR) << "Invalid (non-NV12) pixel format."; + return nullptr; + } + const VideoPixelFormat pixel_format = PIXEL_FORMAT_NV12; + + // Retrieve the layout parameters for |io_surface_|. + const size_t num_planes = IOSurfaceGetPlaneCount(io_surface); + const gfx::Size size(IOSurfaceGetWidth(io_surface), + IOSurfaceGetHeight(io_surface)); + std::vector<int32_t> strides; + for (size_t i = 0; i < num_planes; ++i) + strides.push_back(IOSurfaceGetBytesPerRowOfPlane(io_surface, i)); + base::Optional<VideoFrameLayout> layout = + media::VideoFrameLayout::CreateWithStrides(pixel_format, size, strides); + if (!layout) { + DLOG(ERROR) << "Invalid layout."; + return nullptr; + } + + const StorageType storage_type = STORAGE_UNOWNED_MEMORY; + if (!IsValidConfig(pixel_format, storage_type, size, visible_rect, size)) { + DLOG(ERROR) << "Invalid config."; + return nullptr; + } + + // Lock the IOSurface for CPU read access. After the VideoFrame is created, + // add a destruction callback to unlock the IOSurface. + kern_return_t lock_result = + IOSurfaceLock(io_surface, kIOSurfaceLockReadOnly, nullptr); + if (lock_result != kIOReturnSuccess) { + DLOG(ERROR) << "Failed to lock IOSurface."; + return nullptr; + } + auto unlock_lambda = [](base::ScopedCFTypeRef<IOSurfaceRef> io_surface) { + IOSurfaceUnlock(io_surface, kIOSurfaceLockReadOnly, nullptr); + }; + + scoped_refptr<VideoFrame> frame = + new VideoFrame(*layout, storage_type, visible_rect, size, timestamp); + for (size_t i = 0; i < num_planes; ++i) { + frame->data_[i] = reinterpret_cast<uint8_t*>( + IOSurfaceGetBaseAddressOfPlane(io_surface, i)); + } + frame->AddDestructionObserver( + base::BindOnce(unlock_lambda, std::move(io_surface))); + return frame; +} + +// static scoped_refptr<VideoFrame> VideoFrame::WrapCVPixelBuffer( CVPixelBufferRef cv_pixel_buffer, base::TimeDelta timestamp) { @@ -978,6 +1100,12 @@ bool VideoFrame::IsMappable() const { } bool VideoFrame::HasTextures() const { + // A SharedImage can be turned into a texture, and so it counts as a texture + // in the context of this call. + if (mailbox_holders_[0].mailbox.IsSharedImage()) + return true; + + DCHECK(!wrapped_frame_ || !wrapped_frame_->HasTextures()); return wrapped_frame_ ? wrapped_frame_->HasTextures() : !mailbox_holders_[0].mailbox.IsZero(); } @@ -1171,6 +1299,12 @@ VideoFrame::~VideoFrame() { std::move(mailbox_holders_release_cb_).Run(release_sync_token); } + // Someone might be monitoring original wrapped frame for feedback. + // Ensure all accumulated feedback is propagated to the original frame. + if (wrapped_frame_) { + wrapped_frame_->feedback()->Combine(feedback_); + } + for (auto& callback : done_callbacks_) std::move(callback).Run(); } diff --git a/chromium/media/base/video_frame.h b/chromium/media/base/video_frame.h index 0cb07b47317..e31d70dfe0f 100644 --- a/chromium/media/base/video_frame.h +++ b/chromium/media/base/video_frame.h @@ -27,13 +27,14 @@ #include "build/build_config.h" #include "gpu/command_buffer/common/mailbox_holder.h" #include "gpu/ipc/common/vulkan_ycbcr_info.h" -#include "media/base/hdr_metadata.h" +#include "media/base/video_frame_feedback.h" #include "media/base/video_frame_layout.h" #include "media/base/video_frame_metadata.h" #include "media/base/video_types.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +#include "ui/gl/hdr_metadata.h" #if defined(OS_MAC) #include <CoreVideo/CVPixelBuffer.h> @@ -46,6 +47,7 @@ namespace gfx { class GpuMemoryBuffer; +struct GpuMemoryBufferHandle; } namespace media { @@ -234,6 +236,19 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { uint8_t* a_data, base::TimeDelta timestamp); + // Wraps external NV12 data of the given parameters with a VideoFrame. + // The returned VideoFrame does not own the data passed in. + static scoped_refptr<VideoFrame> WrapExternalYuvData( + VideoPixelFormat format, + const gfx::Size& coded_size, + const gfx::Rect& visible_rect, + const gfx::Size& natural_size, + int32_t y_stride, + int32_t uv_stride, + uint8_t* y_data, + uint8_t* uv_data, + base::TimeDelta timestamp); + // Wraps |gpu_memory_buffer| along with the mailboxes created from // |gpu_memory_buffer|. |mailbox_holders_release_cb| will be called with a // sync token as the argument when the VideoFrame is to be destroyed. @@ -276,6 +291,13 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { static scoped_refptr<VideoFrame> WrapCVPixelBuffer( CVPixelBufferRef cv_pixel_buffer, base::TimeDelta timestamp); + + // Wraps a provided IOSurface with a VideoFrame. The IOSurface is retained + // and locked for the lifetime of the VideoFrame. + static scoped_refptr<VideoFrame> WrapIOSurface( + gfx::GpuMemoryBufferHandle handle, + const gfx::Rect& visible_rect, + base::TimeDelta timestamp); #endif // Wraps |frame|. |visible_rect| must be a sub rect within @@ -418,11 +440,11 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { color_space_ = color_space; } - const base::Optional<HDRMetadata>& hdr_metadata() const { + const base::Optional<gl::HDRMetadata>& hdr_metadata() const { return hdr_metadata_; } - void set_hdr_metadata(const base::Optional<HDRMetadata>& hdr_metadata) { + void set_hdr_metadata(const base::Optional<gl::HDRMetadata>& hdr_metadata) { hdr_metadata_ = hdr_metadata; } @@ -546,6 +568,9 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { // Resets |metadata_|. void clear_metadata() { set_metadata(VideoFrameMetadata()); } + const VideoFrameFeedback* feedback() const { return &feedback_; } + VideoFrameFeedback* feedback() { return &feedback_; } + // The time span between the current frame and the first frame of the stream. // This is the media timestamp, and not the reference time. // See VideoFrameMetadata::REFERENCE_TIME for details. @@ -699,11 +724,13 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { VideoFrameMetadata metadata_; + VideoFrameFeedback feedback_; + // Generated at construction time. const int unique_id_; gfx::ColorSpace color_space_; - base::Optional<HDRMetadata> hdr_metadata_; + base::Optional<gl::HDRMetadata> hdr_metadata_; // Sampler conversion information which is used in vulkan context for android. base::Optional<gpu::VulkanYCbCrInfo> ycbcr_info_; diff --git a/chromium/media/base/video_frame_feedback.cc b/chromium/media/base/video_frame_feedback.cc new file mode 100644 index 00000000000..9dcfae837e1 --- /dev/null +++ b/chromium/media/base/video_frame_feedback.cc @@ -0,0 +1,50 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/video_frame_feedback.h" + +#include <cmath> + +namespace media { + +VideoFrameFeedback::VideoFrameFeedback() = default; +VideoFrameFeedback::VideoFrameFeedback(const VideoFrameFeedback& other) = + default; + +VideoFrameFeedback::VideoFrameFeedback(double resource_utilization, + float max_framerate_fps, + int max_pixels) + : resource_utilization(resource_utilization), + max_framerate_fps(max_framerate_fps), + max_pixels(max_pixels) {} + +void VideoFrameFeedback::Combine(const VideoFrameFeedback& other) { + // Take maximum of non-negative and finite |resource_utilization| values. + if (other.resource_utilization >= 0 && + std::isfinite(other.resource_utilization)) { + if (!std::isfinite(resource_utilization) || + resource_utilization < other.resource_utilization) { + resource_utilization = other.resource_utilization; + } + } + + // Take minimum non-negative max_pixels value to satisfy both constraints. + if (other.max_pixels > 0 && + (max_pixels <= 0 || max_pixels > other.max_pixels)) { + max_pixels = other.max_pixels; + } + + // Take minimum of non-negative max_framerate_fps. + if (other.max_framerate_fps >= 0.0 && + (max_framerate_fps < 0.0 || max_framerate_fps > other.max_framerate_fps)) + max_framerate_fps = other.max_framerate_fps; +} + +bool VideoFrameFeedback::Empty() const { + return !std::isfinite(max_framerate_fps) && + max_pixels == std::numeric_limits<int>::max() && + (resource_utilization < 0.0); +} + +} // namespace media diff --git a/chromium/media/base/video_frame_feedback.h b/chromium/media/base/video_frame_feedback.h new file mode 100644 index 00000000000..efb89f5034a --- /dev/null +++ b/chromium/media/base/video_frame_feedback.h @@ -0,0 +1,73 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_VIDEO_FRAME_FEEDBACK_H_ +#define MEDIA_BASE_VIDEO_FRAME_FEEDBACK_H_ + +#include <limits> + +#include "media/base/media_export.h" + +namespace media { + +// Feedback from the frames consumer. +// This class is passed from the frames sink to the capturer to limit +// incoming video feed frame-rate and/or resolution. +struct MEDIA_EXPORT VideoFrameFeedback { + VideoFrameFeedback(); + VideoFrameFeedback(const VideoFrameFeedback& other); + + explicit VideoFrameFeedback( + double resource_utilization, + float max_framerate_fps = std::numeric_limits<float>::infinity(), + int max_pixels = std::numeric_limits<int>::max()); + + bool operator==(const VideoFrameFeedback& other) const { + return resource_utilization == other.resource_utilization && + max_pixels == other.max_pixels && + max_framerate_fps == other.max_framerate_fps; + } + + // Combine constraints of two different sinks resulting in constraints fitting + // both of them. + void Combine(const VideoFrameFeedback& other); + + // True if no actionable feedback is present (no resource utilization recorded + // and all constraints are infinite or absent). + bool Empty() const; + + // A feedback signal that indicates the fraction of the tolerable maximum + // amount of resources that were utilized to process this frame. A producer + // can check this value after-the-fact, usually via a VideoFrame destruction + // observer, to determine whether the consumer can handle more or less data + // volume, and achieve the right quality versus performance trade-off. + // + // Values are interpreted as follows: + // Less than 0.0 is meaningless and should be ignored. 1.0 indicates a + // maximum sustainable utilization. Greater than 1.0 indicates the consumer + // is likely to stall or drop frames if the data volume is not reduced. + // -1.0 and any other negative values should be ignored and mean that no + // resource utilization is measured. + // + // Example: In a system that encodes and transmits video frames over the + // network, this value can be used to indicate whether sufficient CPU + // is available for encoding and/or sufficient bandwidth is available for + // transmission over the network. The maximum of the two utilization + // measurements would be used as feedback. + double resource_utilization = -1.0; + + // A feedback signal that indicates how big of a frame-rate and image size the + // consumer can consume without overloading. A producer can check this value + // after-the-fact, usually via a VideoFrame destruction observer, to + // limit produced frame size and frame-rate accordingly. + // Negative values should be ignored. + float max_framerate_fps = std::numeric_limits<float>::infinity(); + + // Maximum requested resolution by a sink (given as a number of pixels). + // Negative values should be ignored. + int max_pixels = std::numeric_limits<int>::max(); +}; + +} // namespace media +#endif // MEDIA_BASE_VIDEO_FRAME_FEEDBACK_H_ diff --git a/chromium/media/base/video_frame_layout.cc b/chromium/media/base/video_frame_layout.cc index 9ded967aecc..ac6b633e240 100644 --- a/chromium/media/base/video_frame_layout.cc +++ b/chromium/media/base/video_frame_layout.cc @@ -97,8 +97,11 @@ base::Optional<VideoFrameLayout> VideoFrameLayout::Create( base::Optional<VideoFrameLayout> VideoFrameLayout::CreateWithStrides( VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<int32_t> strides) { - return CreateWithPlanes(format, coded_size, PlanesFromStrides(strides)); + std::vector<int32_t> strides, + size_t buffer_addr_align, + uint64_t modifier) { + return CreateWithPlanes(format, coded_size, PlanesFromStrides(strides), + buffer_addr_align, modifier); } // static @@ -172,7 +175,7 @@ std::ostream& operator<<(std::ostream& ostream, << VectorToString(layout.planes()) << ", is_multi_planar: " << layout.is_multi_planar() << ", buffer_addr_align: " << layout.buffer_addr_align() - << ", modifier: " << layout.modifier() << ")"; + << ", modifier: 0x" << std::hex << layout.modifier() << ")"; return ostream; } diff --git a/chromium/media/base/video_frame_layout.h b/chromium/media/base/video_frame_layout.h index aeb0ceaeef5..9d1f7c17437 100644 --- a/chromium/media/base/video_frame_layout.h +++ b/chromium/media/base/video_frame_layout.h @@ -62,7 +62,9 @@ class MEDIA_EXPORT VideoFrameLayout { static base::Optional<VideoFrameLayout> CreateWithStrides( VideoPixelFormat format, const gfx::Size& coded_size, - std::vector<int32_t> strides); + std::vector<int32_t> strides, + size_t buffer_addr_align = kBufferAddressAlignment, + uint64_t modifier = gfx::NativePixmapHandle::kNoModifier); // Create a layout suitable for |format| at |coded_size|, with the |planes| // fully provided. diff --git a/chromium/media/base/video_frame_layout_unittest.cc b/chromium/media/base/video_frame_layout_unittest.cc index 17ad2a9c039..4ac87af1ffa 100644 --- a/chromium/media/base/video_frame_layout_unittest.cc +++ b/chromium/media/base/video_frame_layout_unittest.cc @@ -35,6 +35,12 @@ std::vector<ColorPlaneLayout> CreatePlanes(const std::vector<int32_t>& strides, return planes; } +static std::string ModifierToHexString(uint64_t modifier) { + std::stringstream stream; + stream << "0x" << std::hex << modifier; + return stream.str(); +} + } // namespace TEST(VideoFrameLayout, CreateI420) { @@ -208,7 +214,7 @@ TEST(VideoFrameLayout, ToStringWithPlanes) { std::ostringstream ostream; ostream << *layout; const std::string kNoModifier = - std::to_string(gfx::NativePixmapHandle::kNoModifier); + ModifierToHexString(gfx::NativePixmapHandle::kNoModifier); EXPECT_EQ(ostream.str(), "VideoFrameLayout(format: PIXEL_FORMAT_I420, coded_size: 320x180, " "planes (stride, offset, size): [(384, 0, 0), (192, 0, 0), " @@ -229,7 +235,7 @@ TEST(VideoFrameLayout, ToStringMultiPlanar) { std::ostringstream ostream; ostream << *layout; const std::string kNoModifier = - std::to_string(gfx::NativePixmapHandle::kNoModifier); + ModifierToHexString(gfx::NativePixmapHandle::kNoModifier); EXPECT_EQ(ostream.str(), "VideoFrameLayout(format: PIXEL_FORMAT_NV12, coded_size: 320x180, " "planes (stride, offset, size): [(384, 0, 100), (192, 100, 100)], " @@ -246,7 +252,7 @@ TEST(VideoFrameLayout, ToString) { std::ostringstream ostream; ostream << *layout; const std::string kNoModifier = - std::to_string(gfx::NativePixmapHandle::kNoModifier); + ModifierToHexString(gfx::NativePixmapHandle::kNoModifier); EXPECT_EQ(ostream.str(), "VideoFrameLayout(format: PIXEL_FORMAT_NV12, coded_size: 320x180, " "planes (stride, offset, size): [(0, 0, 0), (0, 0, 0)], " diff --git a/chromium/media/base/video_frame_metadata.cc b/chromium/media/base/video_frame_metadata.cc index cb1784e34ee..584bdf6bc43 100644 --- a/chromium/media/base/video_frame_metadata.cc +++ b/chromium/media/base/video_frame_metadata.cc @@ -37,7 +37,6 @@ void VideoFrameMetadata::MergeMetadataFrom( MERGE_FIELD(frame_rate, metadata_source); MERGE_FIELD(interactive_content, metadata_source); MERGE_FIELD(reference_time, metadata_source); - MERGE_FIELD(resource_utilization, metadata_source); MERGE_FIELD(read_lock_fences_enabled, metadata_source); MERGE_FIELD(rotation, metadata_source); MERGE_FIELD(texture_owner, metadata_source); diff --git a/chromium/media/base/video_frame_metadata.h b/chromium/media/base/video_frame_metadata.h index 9b845259592..eed8b133a9b 100644 --- a/chromium/media/base/video_frame_metadata.h +++ b/chromium/media/base/video_frame_metadata.h @@ -109,24 +109,6 @@ struct MEDIA_EXPORT VideoFrameMetadata { // and for A/V synchronization purposes. base::Optional<base::TimeTicks> reference_time; - // A feedback signal that indicates the fraction of the tolerable maximum - // amount of resources that were utilized to process this frame. A producer - // can check this value after-the-fact, usually via a VideoFrame destruction - // observer, to determine whether the consumer can handle more or less data - // volume, and achieve the right quality versus performance trade-off. - // - // Values are interpreted as follows: - // Less than 0.0 is meaningless and should be ignored. 1.0 indicates a - // maximum sustainable utilization. Greater than 1.0 indicates the consumer - // is likely to stall or drop frames if the data volume is not reduced. - // - // Example: In a system that encodes and transmits video frames over the - // network, this value can be used to indicate whether sufficient CPU - // is available for encoding and/or sufficient bandwidth is available for - // transmission over the network. The maximum of the two utilization - // measurements would be used as feedback. - base::Optional<double> resource_utilization; - // Sources of VideoFrames use this marker to indicate that an instance of // VideoFrameExternalResources produced from the associated video frame // should use read lock fences. diff --git a/chromium/media/base/video_frame_unittest.cc b/chromium/media/base/video_frame_unittest.cc index 5e3ec211afc..da2f4a9120f 100644 --- a/chromium/media/base/video_frame_unittest.cc +++ b/chromium/media/base/video_frame_unittest.cc @@ -86,7 +86,6 @@ media::VideoFrameMetadata GetFullVideoFrameMetadata() { metadata.root_scroll_offset_x = 100.2; metadata.root_scroll_offset_y = 200.1; metadata.top_controls_visible_height = 25.5; - metadata.resource_utilization = 95.8; metadata.frame_rate = 29.94; metadata.rtp_timestamp = 1.0; @@ -120,7 +119,6 @@ void VerifyVideoFrameMetadataEquality(const media::VideoFrameMetadata& a, EXPECT_EQ(a.frame_rate, b.frame_rate); EXPECT_EQ(a.interactive_content, b.interactive_content); EXPECT_EQ(a.reference_time, b.reference_time); - EXPECT_EQ(a.resource_utilization, b.resource_utilization); EXPECT_EQ(a.read_lock_fences_enabled, b.read_lock_fences_enabled); EXPECT_EQ(a.rotation, b.rotation); EXPECT_EQ(a.texture_owner, b.texture_owner); @@ -443,9 +441,14 @@ TEST(VideoFrame, WrapExternalGpuMemoryBuffer) { gfx::Size coded_size = gfx::Size(256, 256); gfx::Rect visible_rect(coded_size); auto timestamp = base::TimeDelta::FromMilliseconds(1); +#if defined(OS_LINUX) || defined(OS_CHROMEOS) + const uint64_t modifier = 0x001234567890abcdULL; +#else + const uint64_t modifier = gfx::NativePixmapHandle::kNoModifier; +#endif std::unique_ptr<gfx::GpuMemoryBuffer> gmb = std::make_unique<FakeGpuMemoryBuffer>( - coded_size, gfx::BufferFormat::YUV_420_BIPLANAR); + coded_size, gfx::BufferFormat::YUV_420_BIPLANAR, modifier); gfx::GpuMemoryBuffer* gmb_raw_ptr = gmb.get(); gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes] = { gpu::MailboxHolder(gpu::Mailbox::Generate(), gpu::SyncToken(), 5), @@ -461,6 +464,7 @@ TEST(VideoFrame, WrapExternalGpuMemoryBuffer) { for (size_t i = 0; i < 2; ++i) { EXPECT_EQ(frame->layout().planes()[i].stride, coded_size.width()); } + EXPECT_EQ(frame->layout().modifier(), modifier); EXPECT_EQ(frame->storage_type(), VideoFrame::STORAGE_GPU_MEMORY_BUFFER); EXPECT_TRUE(frame->HasGpuMemoryBuffer()); EXPECT_EQ(frame->GetGpuMemoryBuffer(), gmb_raw_ptr); @@ -750,13 +754,11 @@ TEST(VideoFrameMetadata, PartialMergeMetadata) { const base::TimeTicks kTempTicks = base::TimeTicks::Now() + base::TimeDelta::FromSeconds(2); const base::TimeDelta kTempDelta = base::TimeDelta::FromMilliseconds(31415); - const double kTempDouble = 123.45; VideoFrameMetadata partial_metadata; partial_metadata.capture_update_rect = kTempRect; partial_metadata.reference_time = kTempTicks; partial_metadata.processing_time = kTempDelta; - partial_metadata.resource_utilization = kTempDouble; partial_metadata.allow_overlay = false; // Merging partial metadata into full metadata partially override it. @@ -765,7 +767,6 @@ TEST(VideoFrameMetadata, PartialMergeMetadata) { EXPECT_EQ(partial_metadata.capture_update_rect, kTempRect); EXPECT_EQ(partial_metadata.reference_time, kTempTicks); EXPECT_EQ(partial_metadata.processing_time, kTempDelta); - EXPECT_EQ(partial_metadata.resource_utilization, kTempDouble); EXPECT_EQ(partial_metadata.allow_overlay, false); } diff --git a/chromium/media/base/video_thumbnail_decoder.cc b/chromium/media/base/video_thumbnail_decoder.cc index 130813a00fb..e1ba856efe0 100644 --- a/chromium/media/base/video_thumbnail_decoder.cc +++ b/chromium/media/base/video_thumbnail_decoder.cc @@ -50,8 +50,8 @@ void VideoThumbnailDecoder::OnVideoDecoderInitialized(Status status) { weak_factory_.GetWeakPtr())); } -void VideoThumbnailDecoder::OnVideoBufferDecoded(DecodeStatus status) { - if (status != DecodeStatus::OK) { +void VideoThumbnailDecoder::OnVideoBufferDecoded(Status status) { + if (!status.is_ok()) { NotifyComplete(nullptr); return; } @@ -62,8 +62,8 @@ void VideoThumbnailDecoder::OnVideoBufferDecoded(DecodeStatus status) { weak_factory_.GetWeakPtr())); } -void VideoThumbnailDecoder::OnEosBufferDecoded(DecodeStatus status) { - if (status != DecodeStatus::OK) +void VideoThumbnailDecoder::OnEosBufferDecoded(Status status) { + if (!status.is_ok()) NotifyComplete(nullptr); } diff --git a/chromium/media/base/video_thumbnail_decoder.h b/chromium/media/base/video_thumbnail_decoder.h index 69f0c4faf76..409ec23ab6a 100644 --- a/chromium/media/base/video_thumbnail_decoder.h +++ b/chromium/media/base/video_thumbnail_decoder.h @@ -39,8 +39,8 @@ class MEDIA_EXPORT VideoThumbnailDecoder { private: void OnVideoDecoderInitialized(Status status); - void OnVideoBufferDecoded(DecodeStatus status); - void OnEosBufferDecoded(DecodeStatus status); + void OnVideoBufferDecoded(Status status); + void OnEosBufferDecoded(Status status); // Called when the output frame is generated. void OnVideoFrameDecoded(scoped_refptr<VideoFrame> frame); diff --git a/chromium/media/base/wait_and_replace_sync_token_client.cc b/chromium/media/base/wait_and_replace_sync_token_client.cc new file mode 100644 index 00000000000..b78a6b0eb02 --- /dev/null +++ b/chromium/media/base/wait_and_replace_sync_token_client.cc @@ -0,0 +1,24 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "media/base/wait_and_replace_sync_token_client.h" +#include "gpu/command_buffer/client/interface_base.h" + +namespace media { + +WaitAndReplaceSyncTokenClient::WaitAndReplaceSyncTokenClient( + gpu::InterfaceBase* ib) + : ib_(ib) {} + +void WaitAndReplaceSyncTokenClient::GenerateSyncToken( + gpu::SyncToken* sync_token) { + ib_->GenSyncTokenCHROMIUM(sync_token->GetData()); +} + +void WaitAndReplaceSyncTokenClient::WaitSyncToken( + const gpu::SyncToken& sync_token) { + ib_->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); +} + +} // namespace media diff --git a/chromium/media/base/wait_and_replace_sync_token_client.h b/chromium/media/base/wait_and_replace_sync_token_client.h new file mode 100644 index 00000000000..6aa1e1f07b9 --- /dev/null +++ b/chromium/media/base/wait_and_replace_sync_token_client.h @@ -0,0 +1,34 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_WAIT_AND_REPLACE_SYNC_TOKEN_CLIENT_H_ +#define MEDIA_BASE_WAIT_AND_REPLACE_SYNC_TOKEN_CLIENT_H_ + +#include "base/macros.h" +#include "gpu/command_buffer/common/sync_token.h" +#include "media/base/media_export.h" +#include "media/base/video_frame.h" + +namespace gpu { +class InterfaceBase; +} + +namespace media { + +class MEDIA_EXPORT WaitAndReplaceSyncTokenClient + : public VideoFrame::SyncTokenClient { + public: + explicit WaitAndReplaceSyncTokenClient(gpu::InterfaceBase* ib); + void GenerateSyncToken(gpu::SyncToken* sync_token) final; + void WaitSyncToken(const gpu::SyncToken& sync_token) final; + + private: + gpu::InterfaceBase* ib_; + + DISALLOW_COPY_AND_ASSIGN(WaitAndReplaceSyncTokenClient); +}; + +} // namespace media + +#endif // MEDIA_BASE_WAIT_AND_REPLACE_SYNC_TOKEN_CLIENT_H_ diff --git a/chromium/media/base/win/BUILD.gn b/chromium/media/base/win/BUILD.gn index 2b1d25cf518..b3b33bd42d2 100644 --- a/chromium/media/base/win/BUILD.gn +++ b/chromium/media/base/win/BUILD.gn @@ -2,6 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# This file depends on the legacy global sources assignment filter. It should +# be converted to check target platform before assigning source files to the +# sources variable. Remove this import and set_sources_assignment_filter call +# when the file has been converted. See https://crbug.com/1018739 for details. +import("//build/config/deprecated_default_sources_assignment_filter.gni") +set_sources_assignment_filter(deprecated_default_sources_assignment_filter) + assert(is_win) config("delay_load_mf") { @@ -22,7 +29,7 @@ component("media_foundation_util") { "mf_initializer.h", "mf_initializer_export.h", ] - set_sources_assignment_filter(sources_assignment_filter) + set_sources_assignment_filter(deprecated_default_sources_assignment_filter) configs += [ # TODO(crbug.com/167187): Fix size_t to int truncations. "//build/config/compiler:no_size_t_to_int_warning", |