diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-09-01 11:08:40 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-10-01 12:16:21 +0000 |
commit | 03c549e0392f92c02536d3f86d5e1d8dfa3435ac (patch) | |
tree | fe49d170a929b34ba82cd10db1a0bd8e3760fa4b /chromium/media/base | |
parent | 5d013f5804a0d91fcf6c626b2d6fb6eca5c845b0 (diff) | |
download | qtwebengine-chromium-03c549e0392f92c02536d3f86d5e1d8dfa3435ac.tar.gz |
BASELINE: Update Chromium to 91.0.4472.160
Change-Id: I0def1f08a2412aeed79a9ab95dd50eb5c3f65f31
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/media/base')
68 files changed, 538 insertions, 853 deletions
diff --git a/chromium/media/base/BUILD.gn b/chromium/media/base/BUILD.gn index bcdea7612cb..54e6842abd4 100644 --- a/chromium/media/base/BUILD.gn +++ b/chromium/media/base/BUILD.gn @@ -22,6 +22,11 @@ source_set("base") { visibility = media_subcomponent_deps visibility += [ "//media" ] + if (!enable_library_cdms) { + # cdm_type_conversion is not part of media_subcomponent_deps. + visibility += [ "//media/cdm:cdm_type_conversion" ] + } + # TODO(dalecurtis): Replace this with empty targets on non-mac so # we can just include //media/base/mac in media_subcomponent_deps. if (is_apple) { @@ -265,8 +270,6 @@ source_set("base") { "seekable_buffer.h", "serial_runner.cc", "serial_runner.h", - "shared_memory_pool.cc", - "shared_memory_pool.h", "silent_sink_suspender.cc", "silent_sink_suspender.h", "simple_sync_token_client.cc", @@ -324,8 +327,6 @@ 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", @@ -338,8 +339,6 @@ source_set("base") { "video_thumbnail_decoder.h", "video_transformation.cc", "video_transformation.h", - "video_types.cc", - "video_types.h", "video_util.cc", "video_util.h", "wait_and_replace_sync_token_client.cc", @@ -592,7 +591,6 @@ source_set("unit_tests") { "renderer_factory_selector_unittest.cc", "seekable_buffer_unittest.cc", "serial_runner_unittest.cc", - "shared_memory_pool_unittest.cc", "silent_sink_suspender_unittest.cc", "sinc_resampler_unittest.cc", "status_unittest.cc", diff --git a/chromium/media/base/OWNERS b/chromium/media/base/OWNERS index 7f62fe2fb3e..c83a845a813 100644 --- a/chromium/media/base/OWNERS +++ b/chromium/media/base/OWNERS @@ -1,3 +1 @@ per-file *audio*=file://media/audio/OWNERS - -per-file media_switches.*=mlamouri@chromium.org diff --git a/chromium/media/base/android/BUILD.gn b/chromium/media/base/android/BUILD.gn index 886dbbf132e..b98b73ad331 100644 --- a/chromium/media/base/android/BUILD.gn +++ b/chromium/media/base/android/BUILD.gn @@ -162,7 +162,6 @@ if (is_android) { ":display_java", ":media_java_resources", "//base:base_java", - "//base:jni_java", "//third_party/androidx:androidx_annotation_annotation_java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] diff --git a/chromium/media/base/android/media_codec_loop_unittest.cc b/chromium/media/base/android/media_codec_loop_unittest.cc index 6784015c7c9..b52a888f33e 100644 --- a/chromium/media/base/android/media_codec_loop_unittest.cc +++ b/chromium/media/base/android/media_codec_loop_unittest.cc @@ -4,6 +4,8 @@ #include "media/base/android/media_codec_loop.h" +#include <memory> + #include "base/android/build_info.h" #include "base/macros.h" #include "base/single_thread_task_runner.h" @@ -46,7 +48,7 @@ class MediaCodecLoopTest : public testing::Test { public: MediaCodecLoopTest() : task_runner_handle_(mock_task_runner_), - client_(new StrictMock<MockMediaCodecLoopClient>()) {} + client_(std::make_unique<MockMediaCodecLoopClient>()) {} ~MediaCodecLoopTest() override {} diff --git a/chromium/media/base/android/media_codec_util.cc b/chromium/media/base/android/media_codec_util.cc index ab1975a4f79..bef79b00fe5 100644 --- a/chromium/media/base/android/media_codec_util.cc +++ b/chromium/media/base/android/media_codec_util.cc @@ -28,9 +28,9 @@ using base::android::ConvertUTF8ToJavaString; using base::android::JavaIntArrayToIntVector; using base::android::JavaRef; using base::android::ScopedJavaLocalRef; -using base::android::SDK_VERSION_KITKAT; using base::android::SDK_VERSION_LOLLIPOP; using base::android::SDK_VERSION_LOLLIPOP_MR1; +using base::android::SDK_VERSION_P; namespace media { @@ -43,6 +43,7 @@ const char kAc3MimeType[] = "audio/ac3"; const char kEac3MimeType[] = "audio/eac3"; const char kBitstreamAudioMimeType[] = "audio/raw"; const char kAvcMimeType[] = "video/avc"; +const char kDolbyVisionMimeType[] = "video/dolby-vision"; const char kHevcMimeType[] = "video/hevc"; const char kVp8MimeType[] = "video/x-vnd.on2.vp8"; const char kVp9MimeType[] = "video/x-vnd.on2.vp9"; @@ -63,8 +64,9 @@ static CodecProfileLevel MediaCodecProfileLevelToChromiumProfileLevel( static bool IsSupportedAndroidMimeType(const std::string& mime_type) { std::vector<std::string> supported{ - kMp3MimeType, kAacMimeType, kOpusMimeType, kVorbisMimeType, kAvcMimeType, - kHevcMimeType, kVp8MimeType, kVp9MimeType, kAv1MimeType}; + kMp3MimeType, kAacMimeType, kOpusMimeType, kVorbisMimeType, + kAvcMimeType, kDolbyVisionMimeType, kHevcMimeType, kVp8MimeType, + kVp9MimeType, kAv1MimeType}; return std::find(supported.begin(), supported.end(), mime_type) != supported.end(); } @@ -152,6 +154,8 @@ std::string MediaCodecUtil::CodecToAndroidMimeType(VideoCodec codec) { return kVp8MimeType; case kCodecVP9: return kVp9MimeType; + case kCodecDolbyVision: + return kDolbyVisionMimeType; case kCodecAV1: return kAv1MimeType; default: @@ -182,21 +186,6 @@ bool MediaCodecUtil::IsMediaCodecAvailableFor(int sdk, const char* model) { static const BlocklistEntry blocklist[] = { // crbug.com/653905 {"LGMS330", SDK_VERSION_LOLLIPOP_MR1}, - - // crbug.com/615872 - {"GT-I9100", SDK_VERSION_KITKAT}, - {"GT-I9300", SDK_VERSION_KITKAT}, - {"GT-N7000", SDK_VERSION_KITKAT}, - {"GT-N7100", SDK_VERSION_KITKAT}, - - // crbug.com/628509 - {"A6600", SDK_VERSION_KITKAT}, - {"A6800", SDK_VERSION_KITKAT}, - - // crbug.com/634920 - {"GT-S7262", SDK_VERSION_KITKAT}, - {"GT-S5282", SDK_VERSION_KITKAT}, - {"GT-I8552", SDK_VERSION_KITKAT}, }; const BlocklistEntry* iter = std::find( @@ -205,13 +194,6 @@ bool MediaCodecUtil::IsMediaCodecAvailableFor(int sdk, const char* model) { } // static -bool MediaCodecUtil::SupportsSetParameters() { - // MediaCodec.setParameters() is only available starting with KitKat. - return base::android::BuildInfo::GetInstance()->sdk_int() >= - SDK_VERSION_KITKAT; -} - -// static bool MediaCodecUtil::PlatformSupportsCbcsEncryption(int sdk) { JNIEnv* env = AttachCurrentThread(); return Java_MediaCodecUtil_platformSupportsCbcsEncryption(env, sdk); @@ -238,6 +220,14 @@ std::set<int> MediaCodecUtil::GetEncoderColorFormats( return color_formats; } +#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) +// static +bool MediaCodecUtil::IsDolbyVisionDecoderAvailable() { + return IsMediaCodecAvailable() && + IsDecoderSupportedByDevice(kDolbyVisionMimeType); +} +#endif + // static bool MediaCodecUtil::IsVp8DecoderAvailable() { return IsMediaCodecAvailable() && IsDecoderSupportedByDevice(kVp8MimeType); @@ -382,15 +372,13 @@ bool MediaCodecUtil::IsKnownUnaccelerated(VideoCodec codec, return true; // MediaTek hardware vp8 is known slower than the software implementation. - // MediaTek hardware vp9 is known crashy, see http://crbug.com/446974 and - // http://crbug.com/597836. if (base::StartsWith(codec_name, "OMX.MTK.", base::CompareCase::SENSITIVE)) { - if (codec == kCodecVP8) - return true; - - if (codec == kCodecVP9) - return base::android::BuildInfo::GetInstance()->sdk_int() < - SDK_VERSION_LOLLIPOP; + if (codec == kCodecVP8) { + // We may still reject VP8 hardware decoding later on certain chipsets, + // see isDecoderSupportedForDevice(). We don't have the the chipset ID + // here to check now though. + return base::android::BuildInfo::GetInstance()->sdk_int() < SDK_VERSION_P; + } return false; } @@ -405,15 +393,4 @@ bool MediaCodecUtil::IsKnownUnaccelerated(VideoCodec codec, base::StartsWith(codec_name, "OMX.SEC.", base::CompareCase::SENSITIVE); } -// static -bool MediaCodecUtil::CodecNeedsFlushWorkaround(MediaCodecBridge* codec) { - const auto& codec_name = codec->GetName(); - return base::android::BuildInfo::GetInstance()->sdk_int() == - SDK_VERSION_KITKAT && - base::StartsWith(base::android::BuildInfo::GetInstance()->model(), - "SM-G800", base::CompareCase::INSENSITIVE_ASCII) && - ("OMX.Exynos.avc.dec" == codec_name || - "OMX.Exynos.avc.dec.secure" == codec_name); -} - } // namespace media diff --git a/chromium/media/base/android/media_codec_util.h b/chromium/media/base/android/media_codec_util.h index 5fd273de2ed..4eeb6682948 100644 --- a/chromium/media/base/android/media_codec_util.h +++ b/chromium/media/base/android/media_codec_util.h @@ -19,8 +19,6 @@ namespace media { -class MediaCodecBridge; - // WARNING: Not all methods on this class can be used in the renderer process, // only those which do not attempt to use MediaCodec or MediaCodecList. // @@ -43,12 +41,14 @@ class MEDIA_EXPORT MediaCodecUtil { // to mock BuildInfo instead. static bool IsMediaCodecAvailableFor(int sdk, const char* model); - // Returns true if MediaCodec.setParameters() is available on the device. - static bool SupportsSetParameters(); - // Returns true if MediaCodec supports CBCS Encryption. static bool PlatformSupportsCbcsEncryption(int sdk); +#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) + // Indicates if Dolby Vision decoder is available on this device. + static bool IsDolbyVisionDecoderAvailable(); +#endif + // Indicates if the vp8 decoder or encoder is available on this device. static bool IsVp8DecoderAvailable(); static bool IsVp8EncoderAvailable(); @@ -122,15 +122,6 @@ class MEDIA_EXPORT MediaCodecUtil { // create a MediaCodec (which requires permissions) to get the codec name. static bool IsKnownUnaccelerated(VideoCodec codec, MediaCodecDirection direction); - - // Indicates if the decoder is known to fail when flushed. (b/8125974, - // b/8347958) - // When true, the client should work around the issue by releasing the - // decoder and instantiating a new one rather than flushing the current one. - // - // 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); }; } // namespace media diff --git a/chromium/media/base/android/media_codec_util_unittest.cc b/chromium/media/base/android/media_codec_util_unittest.cc index 6ffda9a5adc..d496e884f39 100644 --- a/chromium/media/base/android/media_codec_util_unittest.cc +++ b/chromium/media/base/android/media_codec_util_unittest.cc @@ -35,17 +35,6 @@ TEST_F(MediaCodecUtilTest, TestCodecAvailableIfNewerVersion) { const char* model; int last_bad_sdk; } devices[] = {{"LGMS330", SDK_VERSION_LOLLIPOP_MR1}, - - {"GT-I9100", SDK_VERSION_KITKAT}, - {"GT-I9300", SDK_VERSION_KITKAT}, - {"GT-N7000", SDK_VERSION_KITKAT}, - {"GT-N7100", SDK_VERSION_KITKAT}, - {"A6600", SDK_VERSION_KITKAT}, - {"A6800", SDK_VERSION_KITKAT}, - {"GT-S7262", SDK_VERSION_KITKAT}, - {"GT-S5282", SDK_VERSION_KITKAT}, - {"GT-I8552", SDK_VERSION_KITKAT}, - {"always_works", 0}, // Some codec that works everywhere. {nullptr, 0}}; diff --git a/chromium/media/base/android/media_player_bridge.cc b/chromium/media/base/android/media_player_bridge.cc index 41d0ab6356d..e034fdd8f5a 100644 --- a/chromium/media/base/android/media_player_bridge.cc +++ b/chromium/media/base/android/media_player_bridge.cc @@ -314,8 +314,8 @@ void MediaPlayerBridge::OnCookiesRetrieved(const std::string& cookies) { } void MediaPlayerBridge::OnAuthCredentialsRetrieved( - const base::string16& username, - const base::string16& password) { + const std::u16string& username, + const std::u16string& password) { GURL::ReplacementsW replacements; if (!username.empty()) { replacements.SetUsernameStr(username); diff --git a/chromium/media/base/android/media_player_bridge.h b/chromium/media/base/android/media_player_bridge.h index 52648721aa1..46f129ae7f4 100644 --- a/chromium/media/base/android/media_player_bridge.h +++ b/chromium/media/base/android/media_player_bridge.h @@ -16,7 +16,6 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/strings/string16.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "media/base/android/media_player_listener.h" @@ -173,8 +172,8 @@ class MEDIA_EXPORT MediaPlayerBridge { // Callback function passed to |resource_getter_|. Called when the auth // credentials are retrieved. - void OnAuthCredentialsRetrieved(const base::string16& username, - const base::string16& password); + void OnAuthCredentialsRetrieved(const std::u16string& username, + const std::u16string& password); // Extract the media metadata from a url, asynchronously. // OnMediaMetadataExtracted() will be called when this call finishes. diff --git a/chromium/media/base/android/media_resource_getter.h b/chromium/media/base/android/media_resource_getter.h index 62b9b782bf8..21d9bb0c676 100644 --- a/chromium/media/base/android/media_resource_getter.h +++ b/chromium/media/base/android/media_resource_getter.h @@ -10,7 +10,6 @@ #include <string> #include "base/callback.h" -#include "base/strings/string16.h" #include "base/time/time.h" #include "media/base/media_export.h" #include "url/gurl.h" @@ -32,7 +31,7 @@ class MEDIA_EXPORT MediaResourceGetter { typedef base::OnceCallback<void(const std::string&)> GetPlatformPathCB; // Callback to get the auth credentials. Args: username and password. - typedef base::OnceCallback<void(const base::string16&, const base::string16&)> + typedef base::OnceCallback<void(const std::u16string&, const std::u16string&)> GetAuthCredentialsCB; // Callback to get the media metadata. Args: duration, width, height, and diff --git a/chromium/media/base/async_destroy_video_decoder.h b/chromium/media/base/async_destroy_video_decoder.h index 948fa8c5a7c..c28cf566b18 100644 --- a/chromium/media/base/async_destroy_video_decoder.h +++ b/chromium/media/base/async_destroy_video_decoder.h @@ -40,11 +40,6 @@ class AsyncDestroyVideoDecoder final : public VideoDecoder { return wrapped_decoder_->GetDecoderType(); } - std::string GetDisplayName() const override { - DCHECK(wrapped_decoder_); - return wrapped_decoder_->GetDisplayName(); - } - bool IsPlatformDecoder() const override { DCHECK(wrapped_decoder_); return wrapped_decoder_->IsPlatformDecoder(); diff --git a/chromium/media/base/audio_buffer_converter.cc b/chromium/media/base/audio_buffer_converter.cc index 3e5c0fa114f..a62b6113bdb 100644 --- a/chromium/media/base/audio_buffer_converter.cc +++ b/chromium/media/base/audio_buffer_converter.cc @@ -6,6 +6,7 @@ #include <algorithm> #include <cmath> +#include <memory> #include "base/check_op.h" #include "media/base/audio_bus.h" @@ -157,8 +158,8 @@ void AudioBufferConverter::ResetConverter(const AudioBuffer& buffer) { return; // Note: The FIFO is disabled to avoid extraneous memcpy(). - audio_converter_.reset( - new AudioConverter(input_params_, output_params_, true)); + audio_converter_ = + std::make_unique<AudioConverter>(input_params_, output_params_, true); audio_converter_->AddInput(this); } diff --git a/chromium/media/base/audio_buffer_converter_unittest.cc b/chromium/media/base/audio_buffer_converter_unittest.cc index b57d8b456df..64d8e450f79 100644 --- a/chromium/media/base/audio_buffer_converter_unittest.cc +++ b/chromium/media/base/audio_buffer_converter_unittest.cc @@ -41,7 +41,8 @@ class AudioBufferConverterTest : public ::testing::Test { kOutChannelLayout, kOutSampleRate, kOutFrameSize) { - audio_buffer_converter_.reset(new AudioBufferConverter(output_params_)); + audio_buffer_converter_ = + std::make_unique<AudioBufferConverter>(output_params_); } void Reset() { @@ -209,7 +210,8 @@ TEST_F(AudioBufferConverterTest, DiscreteChannelLayout) { AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, CHANNEL_LAYOUT_DISCRETE, kOutSampleRate, 512); output_params_.set_channels_for_discrete(2); - audio_buffer_converter_.reset(new AudioBufferConverter(output_params_)); + audio_buffer_converter_ = + std::make_unique<AudioBufferConverter>(output_params_); AddInput(MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_STEREO, 2, 512)); ConsumeAllOutput(); } @@ -220,7 +222,8 @@ TEST_F(AudioBufferConverterTest, LargeBuffersResampling) { kOutSampleRate, 2048); - audio_buffer_converter_.reset(new AudioBufferConverter(output_params_)); + audio_buffer_converter_ = + std::make_unique<AudioBufferConverter>(output_params_); const int kInputSampleRate = 48000; const int kInputFrameSize = 8192; ASSERT_NE(kInputSampleRate, kOutSampleRate); diff --git a/chromium/media/base/audio_converter.cc b/chromium/media/base/audio_converter.cc index 5b000656c3d..ac54e86ed35 100644 --- a/chromium/media/base/audio_converter.cc +++ b/chromium/media/base/audio_converter.cc @@ -11,6 +11,7 @@ #include "media/base/audio_converter.h" #include <algorithm> +#include <memory> #include "base/bind.h" #include "base/callback_helpers.h" @@ -44,7 +45,8 @@ AudioConverter::AudioConverter(const AudioParameters& input_params, << " to " << output_params.channel_layout() << "; from " << input_params.channels() << " channels to " << output_params.channels() << " channels."; - channel_mixer_.reset(new ChannelMixer(input_params, output_params)); + channel_mixer_ = + std::make_unique<ChannelMixer>(input_params, output_params); // Pare off data as early as we can for efficiency. downmix_early_ = input_params.channels() > output_params.channels(); @@ -56,11 +58,11 @@ AudioConverter::AudioConverter(const AudioParameters& input_params, << output_params.sample_rate(); const int request_size = disable_fifo ? SincResampler::kDefaultRequestSize : input_params.frames_per_buffer(); - resampler_.reset(new MultiChannelResampler( + resampler_ = std::make_unique<MultiChannelResampler>( downmix_early_ ? output_params.channels() : input_params.channels(), io_sample_rate_ratio_, request_size, base::BindRepeating(&AudioConverter::ProvideInput, - base::Unretained(this)))); + base::Unretained(this))); } // The resampler can be configured to work with a specific request size, so a @@ -75,11 +77,11 @@ AudioConverter::AudioConverter(const AudioParameters& input_params, DVLOG(1) << "Rebuffering from " << input_params.frames_per_buffer() << " to " << output_params.frames_per_buffer(); chunk_size_ = input_params.frames_per_buffer(); - audio_fifo_.reset(new AudioPullFifo( + audio_fifo_ = std::make_unique<AudioPullFifo>( downmix_early_ ? output_params.channels() : input_params.channels(), chunk_size_, base::BindRepeating(&AudioConverter::SourceCallback, - base::Unretained(this)))); + base::Unretained(this))); } } diff --git a/chromium/media/base/audio_converter_unittest.cc b/chromium/media/base/audio_converter_unittest.cc index c27a7b338fc..86d6ddd2023 100644 --- a/chromium/media/base/audio_converter_unittest.cc +++ b/chromium/media/base/audio_converter_unittest.cc @@ -45,8 +45,8 @@ class AudioConverterTest AudioParameters::AUDIO_PCM_LOW_LATENCY, std::get<2>(GetParam()), std::get<1>(GetParam()), kLowLatencyBufferSize); - converter_.reset(new AudioConverter( - input_parameters_, output_parameters_, false)); + converter_ = std::make_unique<AudioConverter>(input_parameters_, + output_parameters_, false); audio_bus_ = AudioBus::Create(output_parameters_); expected_audio_bus_ = AudioBus::Create(output_parameters_); @@ -54,7 +54,8 @@ class AudioConverterTest // Allocate one callback for generating expected results. double step = kSineCycles / static_cast<double>( output_parameters_.frames_per_buffer()); - expected_callback_.reset(new FakeAudioRenderCallback(step, kSampleRate)); + expected_callback_ = + std::make_unique<FakeAudioRenderCallback>(step, kSampleRate); } // Creates |count| input callbacks to be used for conversion testing. diff --git a/chromium/media/base/audio_push_fifo_unittest.cc b/chromium/media/base/audio_push_fifo_unittest.cc index 2adf285f37e..a5fc8a37885 100644 --- a/chromium/media/base/audio_push_fifo_unittest.cc +++ b/chromium/media/base/audio_push_fifo_unittest.cc @@ -25,8 +25,8 @@ class AudioPushFifoTest : public testing::TestWithParam<int> { int output_chunk_size() const { return GetParam(); } void SetUp() final { - fifo_.reset(new AudioPushFifo(base::BindRepeating( - &AudioPushFifoTest::ReceiveAndCheckNextChunk, base::Unretained(this)))); + fifo_ = std::make_unique<AudioPushFifo>(base::BindRepeating( + &AudioPushFifoTest::ReceiveAndCheckNextChunk, base::Unretained(this))); fifo_->Reset(output_chunk_size()); ASSERT_EQ(output_chunk_size(), fifo_->frames_per_buffer()); } diff --git a/chromium/media/base/audio_renderer_mixer_input_unittest.cc b/chromium/media/base/audio_renderer_mixer_input_unittest.cc index 01f4491e66b..f843c8d2f2a 100644 --- a/chromium/media/base/audio_renderer_mixer_input_unittest.cc +++ b/chromium/media/base/audio_renderer_mixer_input_unittest.cc @@ -42,7 +42,7 @@ class AudioRendererMixerInputTest : public testing::Test, kSampleRate, kBufferSize); CreateMixerInput(kDefaultDeviceId); - fake_callback_.reset(new FakeAudioRenderCallback(0, kSampleRate)); + fake_callback_ = std::make_unique<FakeAudioRenderCallback>(0, kSampleRate); audio_bus_ = AudioBus::Create(audio_parameters_); } diff --git a/chromium/media/base/audio_renderer_mixer_unittest.cc b/chromium/media/base/audio_renderer_mixer_unittest.cc index 60ddd9df47a..d5aab5d4516 100644 --- a/chromium/media/base/audio_renderer_mixer_unittest.cc +++ b/chromium/media/base/audio_renderer_mixer_unittest.cc @@ -82,8 +82,8 @@ class AudioRendererMixerTest // Allocate one callback for generating expected results. double step = kSineCycles / static_cast<double>( output_parameters_.frames_per_buffer()); - expected_callback_.reset( - new FakeAudioRenderCallback(step, output_parameters_.sample_rate())); + expected_callback_ = std::make_unique<FakeAudioRenderCallback>( + step, output_parameters_.sample_rate()); } AudioRendererMixer* GetMixer(const base::UnguessableToken& owner_token, diff --git a/chromium/media/base/callback_registry.h b/chromium/media/base/callback_registry.h index fe519cb840b..737eed8dc13 100644 --- a/chromium/media/base/callback_registry.h +++ b/chromium/media/base/callback_registry.h @@ -37,8 +37,8 @@ class CallbackRegistry; // callbacks. This class is thread safe: all methods can be called on any // thread. The CallbackRegistry must outlive all CallbackRegistrations returned // by Register(). -// TODO(xhwang): This class is similar to base::CallbackList, but is simpler, -// and provides thread safety. Consider merging these two. +// TODO(xhwang): This class is similar to base::RepeatingCallbackList, but is +// simpler, and provides thread safety. Consider merging these two. template <typename... Args> class CallbackRegistry<void(Args...)> { public: diff --git a/chromium/media/base/cdm_context.h b/chromium/media/base/cdm_context.h index aacea9ec764..9bb677217cc 100644 --- a/chromium/media/base/cdm_context.h +++ b/chromium/media/base/cdm_context.h @@ -76,8 +76,9 @@ class MEDIA_EXPORT CdmContext { // CallbackRegistration object can be destructed on any thread. // - Thread Model: Can be called on any thread. The registered callback will // always be called on the thread where RegisterEventCB() is called. - // - TODO(xhwang): Not using base::CallbackList because it is not thread- - // safe. Consider refactoring base::CallbackList to avoid code duplication. + // - TODO(xhwang): Not using base::RepeatingCallbackList because it is not + // thread- safe. Consider refactoring base::RepeatingCallbackList to avoid + // code duplication. virtual std::unique_ptr<CallbackRegistration> RegisterEventCB( EventCB event_cb); diff --git a/chromium/media/base/content_decryption_module.h b/chromium/media/base/content_decryption_module.h index b6185c8b7c0..45bd5d1e5bb 100644 --- a/chromium/media/base/content_decryption_module.h +++ b/chromium/media/base/content_decryption_module.h @@ -43,8 +43,7 @@ typedef std::vector<std::unique_ptr<CdmKeyInformation>> CdmKeysInfo; enum class CdmSessionType { kTemporary, kPersistentLicense, - kPersistentUsageRecord, - kMaxValue = kPersistentUsageRecord + kMaxValue = kPersistentLicense }; // Type of message being sent to the application. diff --git a/chromium/media/base/decoder.cc b/chromium/media/base/decoder.cc index 8e06f1e2514..f14ec631d2e 100644 --- a/chromium/media/base/decoder.cc +++ b/chromium/media/base/decoder.cc @@ -43,13 +43,18 @@ std::string GetDecoderName(VideoDecoderType type) { case VideoDecoderType::kD3D11: return "D3D11VideoDecoder"; case VideoDecoderType::kVaapi: - return "VaapiVideoDecodeAccelerator"; + return "VaapiVideoDecoder"; case VideoDecoderType::kBroker: return "VideoDecoderBroker"; - case VideoDecoderType::kChromeOs: - return "VideoDecoderPipeline (ChromeOs)"; case VideoDecoderType::kVda: - return "VideoDecodeAccelerator"; + return "VDAVideoDecoder"; + case VideoDecoderType::kV4L2: + return "V4L2VideoDecoder"; + case VideoDecoderType::kTesting: + return "Testing or Mock Video decoder"; + default: + NOTREACHED(); + return "VideoDecoderType created through invalid static_cast"; } } @@ -67,7 +72,20 @@ std::string GetDecoderName(AudioDecoderType type) { return "MediaCodecAudioDecoder"; case AudioDecoderType::kBroker: return "AudioDecoderBroker"; + case AudioDecoderType::kTesting: + return "Testing or Mock Audio decoder"; + default: + NOTREACHED(); + return "VideoDecoderType created through invalid static_cast"; } } +std::ostream& operator<<(std::ostream& out, AudioDecoderType type) { + return out << GetDecoderName(type); +} + +std::ostream& operator<<(std::ostream& out, VideoDecoderType type) { + return out << GetDecoderName(type); +} + } // namespace media diff --git a/chromium/media/base/decoder.h b/chromium/media/base/decoder.h index fb43f9ca369..d724edb4970 100644 --- a/chromium/media/base/decoder.h +++ b/chromium/media/base/decoder.h @@ -23,8 +23,10 @@ enum class AudioDecoderType : int { kDecrypting = 3, // DecryptingAudioDecoder kMediaCodec = 4, // MediaCodecAudioDecoder (Android) kBroker = 5, // AudioDecoderBroker + kTesting = 6, // Never send this to UKM, for tests only. - kMaxValue = kBroker // Keep this at the end and equal to the last entry. + // Keep this at the end and equal to the last entry. + kMaxValue = kTesting, }; // List of known VideoDecoder implementations; recorded to UKM, always add new @@ -42,18 +44,22 @@ enum class VideoDecoderType : int { kMediaCodec = 9, // MediaCodecVideoDecoder (Android) kGav1 = 10, // Gav1VideoDecoder kD3D11 = 11, // D3D11VideoDecoder - kVaapi = 12, // VaapiVideoDecodeAccelerator + kVaapi = 12, // VaapiVideoDecoder kBroker = 13, // VideoDecoderBroker (Webcodecs) kVda = 14, // VDAVideoDecoder + // kChromeOs = 15, // DEPRECATED, should be kVaapi or kV4L2 instead. + kV4L2 = 16, // V4L2VideoDecoder - // Chromeos uses VideoDecoderPipeline. This could potentially become more - // granulated in the future. - kChromeOs = 15, - kMaxValue = kChromeOs // Keep this at the end and equal to the last entry. + kTesting = 17, // Never send this to UKM, for tests only. + + // Keep this at the end and equal to the last entry. + kMaxValue = kTesting }; MEDIA_EXPORT std::string GetDecoderName(AudioDecoderType type); MEDIA_EXPORT std::string GetDecoderName(VideoDecoderType type); +MEDIA_EXPORT std::ostream& operator<<(std::ostream& out, AudioDecoderType type); +MEDIA_EXPORT std::ostream& operator<<(std::ostream& out, VideoDecoderType type); class MEDIA_EXPORT Decoder { public: @@ -72,12 +78,6 @@ class MEDIA_EXPORT Decoder { // |DecoderSelector| potentially slowing down the selection process. virtual bool SupportsDecryption() const; - // Returns the name of the decoder for logging and decoder selection purposes. - // This name should be available immediately after construction, and should - // also be stable in the sense that the name does not change across multiple - // constructions. - virtual std::string GetDisplayName() const = 0; - protected: Decoder(); }; diff --git a/chromium/media/base/fake_demuxer_stream_unittest.cc b/chromium/media/base/fake_demuxer_stream_unittest.cc index 085b37a5f60..5108d788f30 100644 --- a/chromium/media/base/fake_demuxer_stream_unittest.cc +++ b/chromium/media/base/fake_demuxer_stream_unittest.cc @@ -45,15 +45,16 @@ class FakeDemuxerStreamTest : public testing::Test { enum ReadResult { OK, ABORTED, CONFIG_CHANGED, READ_ERROR, EOS, PENDING }; void EnterNormalReadState() { - stream_.reset( - new FakeDemuxerStream(kNumConfigs, kNumBuffersInOneConfig, false)); + stream_ = std::make_unique<FakeDemuxerStream>( + kNumConfigs, kNumBuffersInOneConfig, false); for (int i = 0; i < kNumBuffersToReadFirst; ++i) ReadAndExpect(OK); DCHECK_EQ(kNumBuffersToReadFirst, num_buffers_received_); } void EnterBeforeEOSState() { - stream_.reset(new FakeDemuxerStream(1, kNumBuffersInOneConfig, false)); + stream_ = + std::make_unique<FakeDemuxerStream>(1, kNumBuffersInOneConfig, false); for (int i = 0; i < kNumBuffersInOneConfig; ++i) ReadAndExpect(OK); DCHECK_EQ(kNumBuffersInOneConfig, num_buffers_received_); @@ -170,8 +171,8 @@ class FakeDemuxerStreamTest : public testing::Test { void TestRead(int num_configs, int num_buffers_in_one_config, bool is_encrypted) { - stream_.reset(new FakeDemuxerStream( - num_configs, num_buffers_in_one_config, is_encrypted)); + stream_ = std::make_unique<FakeDemuxerStream>( + num_configs, num_buffers_in_one_config, is_encrypted); const VideoDecoderConfig& config = stream_->video_decoder_config(); EXPECT_TRUE(config.IsValidConfig()); @@ -296,8 +297,8 @@ TEST_F(FakeDemuxerStreamTest, Error_BeforeEOS) { } TEST_F(FakeDemuxerStreamTest, NoConfigChanges) { - stream_.reset( - new FakeDemuxerStream(1, kNumBuffersInOneConfig, false)); + stream_ = + std::make_unique<FakeDemuxerStream>(1, kNumBuffersInOneConfig, false); EXPECT_FALSE(stream_->SupportsConfigChanges()); for (int i = 0; i < kNumBuffersInOneConfig; ++i) ReadAndExpect(OK); diff --git a/chromium/media/base/fake_localized_strings.cc b/chromium/media/base/fake_localized_strings.cc index a497483dc4b..888821fa361 100644 --- a/chromium/media/base/fake_localized_strings.cc +++ b/chromium/media/base/fake_localized_strings.cc @@ -7,11 +7,11 @@ namespace media { -base::string16 FakeLocalizedStringProvider(MessageId message_id) { +std::u16string FakeLocalizedStringProvider(MessageId message_id) { if (message_id == DEFAULT_AUDIO_DEVICE_NAME) - return base::ASCIIToUTF16("Default"); + return u"Default"; - return base::ASCIIToUTF16("FakeString"); + return u"FakeString"; } void SetUpFakeLocalizedStrings() { diff --git a/chromium/media/base/key_system_properties.h b/chromium/media/base/key_system_properties.h index b8f169598f2..032f745fd42 100644 --- a/chromium/media/base/key_system_properties.h +++ b/chromium/media/base/key_system_properties.h @@ -48,11 +48,6 @@ class MEDIA_EXPORT KeySystemProperties { // sessions. virtual EmeSessionTypeSupport GetPersistentLicenseSessionSupport() const = 0; - // Returns the support this key system provides for persistent-usage-record - // sessions. - virtual EmeSessionTypeSupport GetPersistentUsageRecordSessionSupport() - const = 0; - // Returns the support this key system provides for persistent state. virtual EmeFeatureSupport GetPersistentStateSupport() const = 0; diff --git a/chromium/media/base/key_systems.cc b/chromium/media/base/key_systems.cc index d81b872ff33..c05c68495e6 100644 --- a/chromium/media/base/key_systems.cc +++ b/chromium/media/base/key_systems.cc @@ -171,11 +171,6 @@ class ClearKeyProperties : public KeySystemProperties { return EmeSessionTypeSupport::NOT_SUPPORTED; } - EmeSessionTypeSupport GetPersistentUsageRecordSessionSupport() - const override { - return EmeSessionTypeSupport::NOT_SUPPORTED; - } - EmeFeatureSupport GetPersistentStateSupport() const override { return EmeFeatureSupport::NOT_SUPPORTED; } @@ -274,9 +269,6 @@ class KeySystemsImpl : public KeySystems { EmeSessionTypeSupport GetPersistentLicenseSessionSupport( const std::string& key_system) const override; - EmeSessionTypeSupport GetPersistentUsageRecordSessionSupport( - const std::string& key_system) const override; - EmeFeatureSupport GetPersistentStateSupport( const std::string& key_system) const override; @@ -471,8 +463,6 @@ void KeySystemsImpl::AddSupportedKeySystems( DCHECK(!properties->GetKeySystemName().empty()); DCHECK(properties->GetPersistentLicenseSessionSupport() != EmeSessionTypeSupport::INVALID); - DCHECK(properties->GetPersistentUsageRecordSessionSupport() != - EmeSessionTypeSupport::INVALID); DCHECK(properties->GetPersistentStateSupport() != EmeFeatureSupport::INVALID); DCHECK(properties->GetDistinctiveIdentifierSupport() != @@ -491,8 +481,6 @@ void KeySystemsImpl::AddSupportedKeySystems( EmeFeatureSupport::NOT_SUPPORTED) { DCHECK(properties->GetPersistentLicenseSessionSupport() == EmeSessionTypeSupport::NOT_SUPPORTED); - DCHECK(properties->GetPersistentUsageRecordSessionSupport() == - EmeSessionTypeSupport::NOT_SUPPORTED); } // If distinctive identifiers are not supported, then no other features can @@ -501,8 +489,6 @@ void KeySystemsImpl::AddSupportedKeySystems( EmeFeatureSupport::NOT_SUPPORTED) { DCHECK(properties->GetPersistentLicenseSessionSupport() != EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER); - DCHECK(properties->GetPersistentUsageRecordSessionSupport() != - EmeSessionTypeSupport::SUPPORTED_WITH_IDENTIFIER); } if (!CanBlock(*properties)) { @@ -749,18 +735,6 @@ EmeSessionTypeSupport KeySystemsImpl::GetPersistentLicenseSessionSupport( return key_system_iter->second->GetPersistentLicenseSessionSupport(); } -EmeSessionTypeSupport KeySystemsImpl::GetPersistentUsageRecordSessionSupport( - const std::string& key_system) const { - DCHECK(thread_checker_.CalledOnValidThread()); - - auto key_system_iter = key_system_properties_map_.find(key_system); - if (key_system_iter == key_system_properties_map_.end()) { - NOTREACHED(); - return EmeSessionTypeSupport::INVALID; - } - return key_system_iter->second->GetPersistentUsageRecordSessionSupport(); -} - EmeFeatureSupport KeySystemsImpl::GetPersistentStateSupport( const std::string& key_system) const { DCHECK(thread_checker_.CalledOnValidThread()); diff --git a/chromium/media/base/key_systems.h b/chromium/media/base/key_systems.h index d57aa8e6c96..34fd6a46602 100644 --- a/chromium/media/base/key_systems.h +++ b/chromium/media/base/key_systems.h @@ -65,11 +65,6 @@ class MEDIA_EXPORT KeySystems { virtual EmeSessionTypeSupport GetPersistentLicenseSessionSupport( const std::string& key_system) const = 0; - // Returns the support |key_system| provides for persistent-usage-record - // sessions. - virtual EmeSessionTypeSupport GetPersistentUsageRecordSessionSupport( - const std::string& key_system) const = 0; - // Returns the support |key_system| provides for persistent state. virtual EmeFeatureSupport GetPersistentStateSupport( const std::string& key_system) const = 0; diff --git a/chromium/media/base/key_systems_unittest.cc b/chromium/media/base/key_systems_unittest.cc index 78685a7b8a2..e38e2b33c2b 100644 --- a/chromium/media/base/key_systems_unittest.cc +++ b/chromium/media/base/key_systems_unittest.cc @@ -80,11 +80,6 @@ class TestKeySystemPropertiesBase : public KeySystemProperties { return requested_robustness.empty() ? EmeConfigRule::SUPPORTED : EmeConfigRule::NOT_SUPPORTED; } - - EmeSessionTypeSupport GetPersistentUsageRecordSessionSupport() - const override { - return EmeSessionTypeSupport::NOT_SUPPORTED; - } }; class AesKeySystemProperties : public TestKeySystemPropertiesBase { diff --git a/chromium/media/base/localized_strings.cc b/chromium/media/base/localized_strings.cc index 613accca08a..86422124389 100644 --- a/chromium/media/base/localized_strings.cc +++ b/chromium/media/base/localized_strings.cc @@ -20,9 +20,9 @@ std::string GetLocalizedStringUTF8(MessageId message_id) { return base::UTF16ToUTF8(GetLocalizedStringUTF16(message_id)); } -base::string16 GetLocalizedStringUTF16(MessageId message_id) { +std::u16string GetLocalizedStringUTF16(MessageId message_id) { return g_localized_string_provider ? g_localized_string_provider(message_id) - : base::string16(); + : std::u16string(); } #endif diff --git a/chromium/media/base/localized_strings.h b/chromium/media/base/localized_strings.h index 4a0d36ce837..9ee50b18bb7 100644 --- a/chromium/media/base/localized_strings.h +++ b/chromium/media/base/localized_strings.h @@ -7,7 +7,6 @@ #include <string> -#include "base/strings/string16.h" #include "build/build_config.h" #include "media/base/media_export.h" #include "media/media_buildflags.h" @@ -29,7 +28,7 @@ enum MessageId { // Implementations are expected to convert MessageIds to generated_resources.grd // IDs and extract the matching string from Chrome's resource bundle (e.g. // through l10n_util::GetStringUTF16). -using LocalizedStringProvider = base::string16 (*)(MessageId message_id); +using LocalizedStringProvider = std::u16string (*)(MessageId message_id); // Initializes the global LocalizedStringProvider function. MEDIA_EXPORT void SetLocalizedStringProvider(LocalizedStringProvider func); @@ -42,7 +41,7 @@ MEDIA_EXPORT void SetLocalizedStringProvider(LocalizedStringProvider func); // Returns an empty string if the LocalizedStringProvider has not been // initialized or if the ID is unrecognized. MEDIA_EXPORT std::string GetLocalizedStringUTF8(MessageId message_id); -base::string16 GetLocalizedStringUTF16(MessageId message_id); +std::u16string GetLocalizedStringUTF16(MessageId message_id); #endif } // namespace media diff --git a/chromium/media/base/media_permission.cc b/chromium/media/base/media_permission.cc index 56ea2ffc0e8..307ccb91ec4 100644 --- a/chromium/media/base/media_permission.cc +++ b/chromium/media/base/media_permission.cc @@ -10,6 +10,4 @@ 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 b71c6ca902b..4226086ba47 100644 --- a/chromium/media/base/media_permission.h +++ b/chromium/media/base/media_permission.h @@ -41,8 +41,6 @@ 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_switches.cc b/chromium/media/base/media_switches.cc index 7215555d66c..065ff8a0bd6 100644 --- a/chromium/media/base/media_switches.cc +++ b/chromium/media/base/media_switches.cc @@ -360,6 +360,10 @@ const base::Feature kD3D11VideoDecoderAlwaysCopy{ const base::Feature kD3D11VideoDecoderAllowOverlay{ "D3D11VideoDecoderAllowOverlay", base::FEATURE_ENABLED_BY_DEFAULT}; +// If enabled, D3D11VideoDecoder will enable HDR support even if the OS doesn't. +const base::Feature kD3D11VideoDecoderForceEnableHDR{ + "D3D11VideoDecoderForceEnableHDR", base::FEATURE_DISABLED_BY_DEFAULT}; + // Falls back to other decoders after audio/video decode error happens. The // implementation may choose different strategies on when to fallback. See // DecoderStream for details. When disabled, playback will fail immediately @@ -459,9 +463,7 @@ const base::Feature kUseR16Texture{"use-r16-texture", const base::Feature kUnifiedAutoplay{"UnifiedAutoplay", base::FEATURE_ENABLED_BY_DEFAULT}; -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#if defined(OS_LINUX) // Enable vaapi video decoding on linux. This is already enabled by default on // chromeos, but needs an experiment on linux. const base::Feature kVaapiVideoDecodeLinux{"VaapiVideoDecoder", @@ -469,22 +471,28 @@ const base::Feature kVaapiVideoDecodeLinux{"VaapiVideoDecoder", const base::Feature kVaapiVideoEncodeLinux{"VaapiVideoEncoder", base::FEATURE_DISABLED_BY_DEFAULT}; -#endif // defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#endif // defined(OS_LINUX) // Enable VA-API hardware decode acceleration for AV1. const base::Feature kVaapiAV1Decoder{"VaapiAV1Decoder", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enable VA-API hardware low power encoder for all codecs on intel Gen9x gpu. const base::Feature kVaapiLowPowerEncoderGen9x{ "VaapiLowPowerEncoderGen9x", base::FEATURE_DISABLED_BY_DEFAULT}; -// Deny specific (likely small) resolutions for VA-API hardware decode and -// encode acceleration. -// TOOD(b/171041334): Enable by default once the ARC++ hw codecs issue is fixed. +// Reject creation of encode/decode VAContexts when the requested resolution is +// outside the enumerated minimum and maximum. TODO(b/171041334): Remove and +// enable by default once the ARC++ hw codecs issue is fixed. const base::Feature kVaapiEnforceVideoMinMaxResolution{ "VaapiEnforceVideoMinMaxResolution", base::FEATURE_DISABLED_BY_DEFAULT}; +// Ensure the advertised minimum supported resolution is larger than or equal to +// a given one (likely QVGA + 1) for certain codecs/modes and platforms, for +// performance reasons. This does not affect JPEG decoding. +const base::Feature kVaapiVideoMinResolutionForPerformance{ + "VaapiVideoMinResolutionForPerformance", base::FEATURE_ENABLED_BY_DEFAULT}; + // Enable VA-API hardware encode acceleration for VP8. const base::Feature kVaapiVP8Encoder{"VaapiVP8Encoder", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -510,13 +518,25 @@ const base::Feature kExternalClearKeyForTesting{ "ExternalClearKeyForTesting", base::FEATURE_DISABLED_BY_DEFAULT}; // Enables the Live Caption feature. -const base::Feature kLiveCaption{"LiveCaption", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kLiveCaption { + "LiveCaption", +#if defined(OS_CHROMEOS) + // TODO(crbug.com/1209058): Remove this special case after it's merged + // into M91. + base::FEATURE_DISABLED_BY_DEFAULT +#else + base::FEATURE_ENABLED_BY_DEFAULT +#endif +}; // 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}; + base::FEATURE_ENABLED_BY_DEFAULT}; + +// Live Caption can be used in multiple languages, as opposed to just English. +const base::Feature kLiveCaptionMultiLanguage{ + "LiveCaptionMultiLanguage", base::FEATURE_DISABLED_BY_DEFAULT}; // Live Caption runs system-wide on ChromeOS, as opposed to just in the browser. const base::Feature kLiveCaptionSystemWideOnChromeOS{ @@ -539,19 +559,6 @@ const base::Feature kHardwareSecureDecryption{ const base::Feature kWakeLockOptimisationHiddenMuted{ "kWakeLockOptimisationHiddenMuted", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enables encrypted AV1 support in EME requestMediaKeySystemAccess() query by -// Widevine key system if it is also supported by the underlying Widevine CDM. -// This feature does not affect the actual playback of encrypted AV1 if it's -// served by the player regardless of the query result. -const base::Feature kWidevineAv1{"WidevineAv1", - base::FEATURE_ENABLED_BY_DEFAULT}; - -// Forces to support encrypted AV1 in EME requestMediaKeySystemAccess() query by -// Widevine key system even if the underlying Widevine CDM doesn't support it. -// No effect if "WidevineAv1" feature is disabled. -const base::Feature kWidevineAv1ForceSupportForTesting{ - "WidevineAv1ForceSupportForTesting", base::FEATURE_DISABLED_BY_DEFAULT}; - // Enables handling of hardware media keys for controlling media. const base::Feature kHardwareMediaKeyHandling { "HardwareMediaKeyHandling", @@ -659,7 +666,7 @@ const base::Feature kUsePooledSharedImageVideoProvider{ "UsePooledSharedImageVideoProvider", base::FEATURE_ENABLED_BY_DEFAULT}; #endif // defined(OS_ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) +#if defined(OS_CHROMEOS) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) // Enable the hardware-accelerated direct video decoder instead of the one // needing the VdaVideoDecoder adapter. This flag is used mainly as a // chrome:flag for developers debugging issues. TODO(b/159825227): remove when @@ -674,8 +681,7 @@ const base::Feature kUseChromeOSDirectVideoDecoder{ const base::Feature kUseAlternateVideoDecoderImplementation{ "UseAlternateVideoDecoderImplementation", base::FEATURE_DISABLED_BY_DEFAULT}; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) && - // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) +#endif // defined(OS_CHROMEOS) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) #if defined(OS_WIN) // Does NV12->NV12 video copy on the main thread right before the texture's @@ -726,22 +732,10 @@ const base::Feature MEDIA_EXPORT kWasapiRawAudioCapture{ #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_DISABLED_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_ENABLED_BY_DEFAULT}; -#endif // defined(OS_MAC) - -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) const base::Feature MEDIA_EXPORT kDeprecateLowUsageCodecs{ "DeprecateLowUsageCodecs", base::FEATURE_ENABLED_BY_DEFAULT}; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // defined(OS_CHROMEOS) std::string GetEffectiveAutoplayPolicy(const base::CommandLine& command_line) { // Return the autoplay policy set in the command line, if any. @@ -790,19 +784,6 @@ const base::Feature kPreloadMediaEngagementData{ const base::Feature kMediaEngagementHTTPSOnly{ "MediaEngagementHTTPSOnly", base::FEATURE_DISABLED_BY_DEFAULT}; -// Enables Media Feeds to allow sites to provide specific recommendations for -// users. -const base::Feature kMediaFeeds{"MediaFeeds", - base::FEATURE_DISABLED_BY_DEFAULT}; - -// Enables fetching Media Feeds periodically in the background. -const base::Feature kMediaFeedsBackgroundFetching{ - "MediaFeedsBackgroundFetching", base::FEATURE_DISABLED_BY_DEFAULT}; - -// Enables checking Media Feeds against safe search to prevent adult content. -const base::Feature kMediaFeedsSafeSearch{"MediaFeedsSafeSearch", - base::FEATURE_DISABLED_BY_DEFAULT}; - // Enables experimental local learning for media. Used in the context of media // capabilities only. Adds reporting only; does not change media behavior. const base::Feature kMediaLearningExperiment{"MediaLearningExperiment", @@ -827,6 +808,10 @@ const base::Feature kMediaOptimizer{"JointMediaOptimizer", const base::Feature kMediaPowerExperiment{"MediaPowerExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; +// Enable WebRTC actions for the Media Session API. +const base::Feature kMediaSessionWebRTC{"MediaSessionWebRTC", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables flash to be ducked by audio focus. This is enabled on Chrome OS which // has audio focus enabled. const base::Feature kAudioFocusDuckFlash { @@ -866,12 +851,6 @@ const base::Feature kKaleidoscopeForceShowFirstRunExperience{ "KaleidoscopeForceShowFirstRunExperience", base::FEATURE_DISABLED_BY_DEFAULT}; -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 62396246cf6..57ae439f02b 100644 --- a/chromium/media/base/media_switches.h +++ b/chromium/media/base/media_switches.h @@ -121,6 +121,7 @@ MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoderAV1; MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoderSkipMultithreaded; MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoderAlwaysCopy; MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoderAllowOverlay; +MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoderForceEnableHDR; MEDIA_EXPORT extern const base::Feature kEnableMediaInternals; MEDIA_EXPORT extern const base::Feature kExposeSwDecodersToWebRTC; MEDIA_EXPORT extern const base::Feature kExternalClearKeyForTesting; @@ -143,9 +144,8 @@ MEDIA_EXPORT extern const base::Feature kKaleidoscope; MEDIA_EXPORT extern const base::Feature kKaleidoscopeInMenu; 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 kLiveCaptionMultiLanguage; MEDIA_EXPORT extern const base::Feature kLiveCaptionSystemWideOnChromeOS; MEDIA_EXPORT extern const base::Feature kLowDelayVideoRenderingOnLiveStream; MEDIA_EXPORT extern const base::Feature kMediaCapabilitiesQueryGpuFactories; @@ -153,14 +153,12 @@ MEDIA_EXPORT extern const base::Feature kMediaCapabilitiesWithParameters; MEDIA_EXPORT extern const base::Feature kMediaCastOverlayButton; MEDIA_EXPORT extern const base::Feature kMediaEngagementBypassAutoplayPolicies; MEDIA_EXPORT extern const base::Feature kMediaEngagementHTTPSOnly; -MEDIA_EXPORT extern const base::Feature kMediaFeeds; -MEDIA_EXPORT extern const base::Feature kMediaFeedsBackgroundFetching; -MEDIA_EXPORT extern const base::Feature kMediaFeedsSafeSearch; MEDIA_EXPORT extern const base::Feature kMediaLearningExperiment; MEDIA_EXPORT extern const base::Feature kMediaLearningFramework; 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 kMediaSessionWebRTC; MEDIA_EXPORT extern const base::Feature kMemoryPressureBasedSourceBufferGC; MEDIA_EXPORT extern const base::Feature kOverlayFullscreenVideo; MEDIA_EXPORT extern const base::Feature kPictureInPicture; @@ -181,21 +179,18 @@ MEDIA_EXPORT extern const base::Feature kUseFakeDeviceForMediaStream; MEDIA_EXPORT extern const base::Feature kUseMediaHistoryStore; MEDIA_EXPORT extern const base::Feature kUseR16Texture; MEDIA_EXPORT extern const base::Feature kUseSodaForLiveCaption; -// TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is -// complete. -#if (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) +#if defined(OS_LINUX) MEDIA_EXPORT extern const base::Feature kVaapiVideoDecodeLinux; MEDIA_EXPORT extern const base::Feature kVaapiVideoEncodeLinux; -#endif // defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) +#endif // defined(OS_LINUX) MEDIA_EXPORT extern const base::Feature kVaapiAV1Decoder; MEDIA_EXPORT extern const base::Feature kVaapiLowPowerEncoderGen9x; MEDIA_EXPORT extern const base::Feature kVaapiEnforceVideoMinMaxResolution; +MEDIA_EXPORT extern const base::Feature kVaapiVideoMinResolutionForPerformance; MEDIA_EXPORT extern const base::Feature kVaapiVP8Encoder; MEDIA_EXPORT extern const base::Feature kVaapiVP9Encoder; MEDIA_EXPORT extern const base::Feature kVideoBlitColorAccuracy; 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; @@ -219,12 +214,11 @@ MEDIA_EXPORT extern const base::Feature kUseAudioLatencyFromHAL; MEDIA_EXPORT extern const base::Feature kUsePooledSharedImageVideoProvider; #endif // defined(OS_ANDROID) -#if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) +#if defined(OS_CHROMEOS) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) MEDIA_EXPORT extern const base::Feature kUseChromeOSDirectVideoDecoder; MEDIA_EXPORT extern const base::Feature kUseAlternateVideoDecoderImplementation; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) && - // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) +#endif // defined(OS_CHROMEOS) && BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION) #if defined(OS_WIN) MEDIA_EXPORT extern const base::Feature kDelayCopyNV12Textures; @@ -238,12 +232,7 @@ MEDIA_EXPORT extern const base::Feature kMediaFoundationD3D11VideoCapture; 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; -#endif - -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) MEDIA_EXPORT extern const base::Feature kDeprecateLowUsageCodecs; #endif diff --git a/chromium/media/base/media_url_demuxer_unittest.cc b/chromium/media/base/media_url_demuxer_unittest.cc index 136f0ac4794..644bbc4ed49 100644 --- a/chromium/media/base/media_url_demuxer_unittest.cc +++ b/chromium/media/base/media_url_demuxer_unittest.cc @@ -4,6 +4,8 @@ #include "media/base/media_url_demuxer.h" +#include <memory> + #include "base/bind.h" #include "base/callback_helpers.h" #include "base/macros.h" @@ -24,9 +26,9 @@ class MediaUrlDemuxerTest : public testing::Test { void InitializeTest(const GURL& media_url, const GURL& first_party, bool allow_credentials) { - demuxer_.reset(new MediaUrlDemuxer( + demuxer_ = std::make_unique<MediaUrlDemuxer>( base::ThreadTaskRunnerHandle::Get(), media_url, first_party, - url::Origin::Create(first_party), allow_credentials, false)); + url::Origin::Create(first_party), allow_credentials, false); } void InitializeTest() { diff --git a/chromium/media/base/mime_util_internal.cc b/chromium/media/base/mime_util_internal.cc index 6c554eb112e..ccfe8e9a653 100644 --- a/chromium/media/base/mime_util_internal.cc +++ b/chromium/media/base/mime_util_internal.cc @@ -144,6 +144,10 @@ MimeUtil::MimeUtil() { // video decoders and MediaCodec; indicated by HasPlatformDecoderSupport(). // When the Android pipeline is used, we only need access to MediaCodec. platform_info_.has_platform_decoders = HasPlatformDecoderSupport(); +#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) + platform_info_.has_platform_dv_decoder = + MediaCodecUtil::IsDolbyVisionDecoderAvailable(); +#endif platform_info_.has_platform_vp8_decoder = MediaCodecUtil::IsVp8DecoderAvailable(); platform_info_.has_platform_vp9_decoder = @@ -649,9 +653,11 @@ bool MimeUtil::IsCodecSupportedOnAndroid( } case DOLBY_VISION: - // This function is only called on Android which doesn't support Dolby - // Vision. +#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) + return platform_info.has_platform_dv_decoder; +#else return false; +#endif case AC3: case EAC3: diff --git a/chromium/media/base/mime_util_internal.h b/chromium/media/base/mime_util_internal.h index 9ddec636d95..614d357c5b0 100644 --- a/chromium/media/base/mime_util_internal.h +++ b/chromium/media/base/mime_util_internal.h @@ -54,6 +54,9 @@ class MEDIA_EXPORT MimeUtil { // runtime. Also used by tests to simulate platform differences. struct PlatformInfo { bool has_platform_decoders = false; +#if BUILDFLAG(ENABLE_PLATFORM_DOLBY_VISION) + bool has_platform_dv_decoder = false; +#endif bool has_platform_vp8_decoder = false; bool has_platform_vp9_decoder = false; #if BUILDFLAG(ENABLE_PLATFORM_HEVC) diff --git a/chromium/media/base/mock_filters.cc b/chromium/media/base/mock_filters.cc index 4e8d7c481aa..4bf36edf546 100644 --- a/chromium/media/base/mock_filters.cc +++ b/chromium/media/base/mock_filters.cc @@ -72,17 +72,17 @@ void MockDemuxerStream::set_liveness(DemuxerStream::Liveness liveness) { liveness_ = liveness; } -MockVideoDecoder::MockVideoDecoder() : MockVideoDecoder("MockVideoDecoder") {} +MockVideoDecoder::MockVideoDecoder() : MockVideoDecoder(0) {} -MockVideoDecoder::MockVideoDecoder(std::string decoder_name) - : MockVideoDecoder(false, false, std::move(decoder_name)) {} +MockVideoDecoder::MockVideoDecoder(int decoder_id) + : MockVideoDecoder(false, false, decoder_id) {} MockVideoDecoder::MockVideoDecoder(bool is_platform_decoder, bool supports_decryption, - std::string decoder_name) + int decoder_id) : is_platform_decoder_(is_platform_decoder), supports_decryption_(supports_decryption), - decoder_name_(std::move(decoder_name)) { + decoder_id_(decoder_id) { ON_CALL(*this, CanReadWithoutStalling()).WillByDefault(Return(true)); ON_CALL(*this, IsOptimizedForRTC()).WillByDefault(Return(false)); } @@ -97,14 +97,6 @@ bool MockVideoDecoder::SupportsDecryption() const { return supports_decryption_; } -std::string MockVideoDecoder::GetDisplayName() const { - return decoder_name_; -} - -VideoDecoderType MockVideoDecoder::GetDecoderType() const { - return VideoDecoderType::kUnknown; -} - MockAudioEncoder::MockAudioEncoder() = default; MockAudioEncoder::~MockAudioEncoder() { OnDestruct(); @@ -115,17 +107,17 @@ MockVideoEncoder::~MockVideoEncoder() { Dtor(); } -MockAudioDecoder::MockAudioDecoder() : MockAudioDecoder("MockAudioDecoder") {} +MockAudioDecoder::MockAudioDecoder() : MockAudioDecoder(0) {} -MockAudioDecoder::MockAudioDecoder(std::string decoder_name) - : MockAudioDecoder(false, false, std::move(decoder_name)) {} +MockAudioDecoder::MockAudioDecoder(int decoder_id) + : MockAudioDecoder(false, false, decoder_id) {} MockAudioDecoder::MockAudioDecoder(bool is_platform_decoder, bool supports_decryption, - std::string decoder_name) + int decoder_id) : is_platform_decoder_(is_platform_decoder), supports_decryption_(supports_decryption), - decoder_name_(decoder_name) {} + decoder_id_(decoder_id) {} MockAudioDecoder::~MockAudioDecoder() = default; @@ -137,14 +129,6 @@ bool MockAudioDecoder::SupportsDecryption() const { return supports_decryption_; } -std::string MockAudioDecoder::GetDisplayName() const { - return decoder_name_; -} - -AudioDecoderType MockAudioDecoder::GetDecoderType() const { - return AudioDecoderType::kUnknown; -} - MockRendererClient::MockRendererClient() = default; MockRendererClient::~MockRendererClient() = default; @@ -189,8 +173,8 @@ base::Optional<base::UnguessableToken> MockCdmContext::GetCdmId() const { return cdm_id_; } -void MockCdmContext::set_cdm_id(const base::UnguessableToken* cdm_id) { - cdm_id_ = (cdm_id) ? base::make_optional(*cdm_id) : base::nullopt; +void MockCdmContext::set_cdm_id(const base::UnguessableToken& cdm_id) { + cdm_id_ = base::make_optional(cdm_id); } MockCdmPromise::MockCdmPromise(bool expect_success) { @@ -241,19 +225,33 @@ MockCdmKeyStatusPromise::~MockCdmKeyStatusPromise() { MarkPromiseSettled(); } -MockCdm::MockCdm(const std::string& key_system, - const SessionMessageCB& session_message_cb, - const SessionClosedCB& session_closed_cb, - const SessionKeysChangeCB& session_keys_change_cb, - const SessionExpirationUpdateCB& session_expiration_update_cb) - : key_system_(key_system), - session_message_cb_(session_message_cb), - session_closed_cb_(session_closed_cb), - session_keys_change_cb_(session_keys_change_cb), - session_expiration_update_cb_(session_expiration_update_cb) {} +MockCdm::MockCdm() = default; + +MockCdm::MockCdm( + const std::string& key_system, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb) { + Initialize(key_system, session_message_cb, session_closed_cb, + session_keys_change_cb, session_expiration_update_cb); +} MockCdm::~MockCdm() = default; +void MockCdm::Initialize( + const std::string& key_system, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb) { + key_system_ = key_system; + session_message_cb_ = session_message_cb; + session_closed_cb_ = session_closed_cb; + session_keys_change_cb_ = session_keys_change_cb; + session_expiration_update_cb_ = session_expiration_update_cb; +} + void MockCdm::CallSessionMessageCB(const std::string& session_id, CdmMessageType message_type, const std::vector<uint8_t>& message) { @@ -276,7 +274,8 @@ void MockCdm::CallSessionExpirationUpdateCB(const std::string& session_id, session_expiration_update_cb_.Run(session_id, new_expiry_time); } -MockCdmFactory::MockCdmFactory() = default; +MockCdmFactory::MockCdmFactory(scoped_refptr<MockCdm> mock_cdm) + : mock_cdm_(mock_cdm) {} MockCdmFactory::~MockCdmFactory() = default; @@ -298,19 +297,9 @@ void MockCdmFactory::Create( if (before_creation_cb_) before_creation_cb_.Run(); - // Create and return a new MockCdm. Keep a pointer to the created CDM so - // that tests can access it. Test cases that expect calls on MockCdm should - // get the MockCdm via MockCdmFactory::GetCreatedCdm() and explicitly specify - // expectations using EXPECT_CALL. - scoped_refptr<MockCdm> cdm = new NiceMock<MockCdm>( - key_system, session_message_cb, session_closed_cb, session_keys_change_cb, - session_expiration_update_cb); - created_cdm_ = cdm.get(); - std::move(cdm_created_cb).Run(std::move(cdm), ""); -} - -MockCdm* MockCdmFactory::GetCreatedCdm() { - return created_cdm_.get(); + mock_cdm_->Initialize(key_system, session_message_cb, session_closed_cb, + session_keys_change_cb, session_expiration_update_cb); + std::move(cdm_created_cb).Run(mock_cdm_, ""); } void MockCdmFactory::SetBeforeCreationCB( diff --git a/chromium/media/base/mock_filters.h b/chromium/media/base/mock_filters.h index f9fae0efb25..281afd56335 100644 --- a/chromium/media/base/mock_filters.h +++ b/chromium/media/base/mock_filters.h @@ -220,17 +220,25 @@ class MockDemuxerStream : public DemuxerStream { class MockVideoDecoder : public VideoDecoder { public: MockVideoDecoder(); - explicit MockVideoDecoder(std::string decoder_name); + // Give a decoder a specific ID, like 42, so that different decoders in unit + // tests can be differentiated from one another. All of these decoders have + // a decoder type of kTesting, so that can't be used to differentiate them. + explicit MockVideoDecoder(int decoder_id); MockVideoDecoder(bool is_platform_decoder, bool supports_decryption, - std::string decoder_name); + int decoder_id); ~MockVideoDecoder() override; // Decoder implementation bool IsPlatformDecoder() const override; bool SupportsDecryption() const override; - std::string GetDisplayName() const override; - VideoDecoderType GetDecoderType() const override; + VideoDecoderType GetDecoderType() const override { + return VideoDecoderType::kTesting; + } + + // Allows getting the unique ID from a mock decoder so that they can be + // identified during tests without having to add unique VideoDecoderTypes. + int GetDecoderId() const { return decoder_id_; } // VideoDecoder implementation. void Initialize(const VideoDecoderConfig& config, @@ -262,7 +270,7 @@ class MockVideoDecoder : public VideoDecoder { private: const bool is_platform_decoder_; const bool supports_decryption_; - const std::string decoder_name_; + const int decoder_id_ = 0; DISALLOW_COPY_AND_ASSIGN(MockVideoDecoder); }; @@ -335,17 +343,22 @@ class MockVideoEncoder : public VideoEncoder { class MockAudioDecoder : public AudioDecoder { public: MockAudioDecoder(); - explicit MockAudioDecoder(std::string decoder_name); + explicit MockAudioDecoder(int decoder_id); explicit MockAudioDecoder(bool is_platform_decoder, bool supports_decryption, - std::string decoder_name); + int decoder_id); ~MockAudioDecoder() override; // Decoder implementation bool IsPlatformDecoder() const override; bool SupportsDecryption() const override; - std::string GetDisplayName() const override; - AudioDecoderType GetDecoderType() const override; + AudioDecoderType GetDecoderType() const override { + return AudioDecoderType::kTesting; + } + + // Allows getting the unique ID from a mock decoder so that they can be + // identified during tests without having to add unique VideoDecoderTypes. + int GetDecoderId() const { return decoder_id_; } // AudioDecoder implementation. void Initialize(const AudioDecoderConfig& config, @@ -368,7 +381,7 @@ class MockAudioDecoder : public AudioDecoder { private: const bool is_platform_decoder_; const bool supports_decryption_; - const std::string decoder_name_; + const int decoder_id_ = 0; DISALLOW_COPY_AND_ASSIGN(MockAudioDecoder); }; @@ -627,7 +640,7 @@ class MockCdmContext : public CdmContext { base::Optional<base::UnguessableToken> GetCdmId() const override; - void set_cdm_id(const base::UnguessableToken* cdm_id); + void set_cdm_id(const base::UnguessableToken& cdm_id); private: base::Optional<base::UnguessableToken> cdm_id_; @@ -684,12 +697,20 @@ class MockCdmKeyStatusPromise : public KeyStatusCdmPromise { class MockCdm : public ContentDecryptionModule { public: + MockCdm(); MockCdm(const std::string& key_system, const SessionMessageCB& session_message_cb, const SessionClosedCB& session_closed_cb, const SessionKeysChangeCB& session_keys_change_cb, const SessionExpirationUpdateCB& session_expiration_update_cb); + void Initialize( + const std::string& key_system, + const SessionMessageCB& session_message_cb, + const SessionClosedCB& session_closed_cb, + const SessionKeysChangeCB& session_keys_change_cb, + const SessionExpirationUpdateCB& session_expiration_update_cb); + // ContentDecryptionModule implementation. MOCK_METHOD2(SetServerCertificate, void(const std::vector<uint8_t>& certificate, @@ -727,16 +748,12 @@ class MockCdm : public ContentDecryptionModule { base::Time new_expiry_time); const std::string& GetKeySystem() const { return key_system_; } - const url::Origin& GetSecurityOrigin() const { return security_origin_; } protected: ~MockCdm() override; private: std::string key_system_; - url::Origin security_origin_; - - // Callbacks. SessionMessageCB session_message_cb_; SessionClosedCB session_closed_cb_; SessionKeysChangeCB session_keys_change_cb_; @@ -747,7 +764,7 @@ class MockCdm : public ContentDecryptionModule { class MockCdmFactory : public CdmFactory { public: - MockCdmFactory(); + explicit MockCdmFactory(scoped_refptr<MockCdm> cdm); ~MockCdmFactory() override; // CdmFactory implementation. @@ -762,15 +779,12 @@ class MockCdmFactory : public CdmFactory { const SessionExpirationUpdateCB& session_expiration_update_cb, CdmCreatedCB cdm_created_cb) override; - // Return a pointer to the created CDM. - MockCdm* GetCreatedCdm(); - // Provide a callback to be called before the CDM is created and returned. void SetBeforeCreationCB(base::RepeatingClosure before_creation_cb); private: // Reference to the created CDM. - scoped_refptr<MockCdm> created_cdm_; + scoped_refptr<MockCdm> mock_cdm_; // Callback to be used before Create() successfully calls |cdm_created_cb|. base::RepeatingClosure before_creation_cb_; diff --git a/chromium/media/base/null_video_sink.cc b/chromium/media/base/null_video_sink.cc index b490a756c37..3e23b2e8dcf 100644 --- a/chromium/media/base/null_video_sink.cc +++ b/chromium/media/base/null_video_sink.cc @@ -54,7 +54,10 @@ void NullVideoSink::CallRender() { const base::TimeTicks end_of_interval = current_render_time_ + interval_; scoped_refptr<VideoFrame> new_frame = callback_->Render( - current_render_time_, end_of_interval, background_render_); + current_render_time_, end_of_interval, + background_render_ + ? VideoRendererSink::RenderCallback::RenderingMode::kBackground + : VideoRendererSink::RenderCallback::RenderingMode::kNormal); DCHECK(new_frame); const bool is_new_frame = new_frame != last_frame_; last_frame_ = new_frame; diff --git a/chromium/media/base/null_video_sink_unittest.cc b/chromium/media/base/null_video_sink_unittest.cc index 4ead7a76dfc..4fb456bc062 100644 --- a/chromium/media/base/null_video_sink_unittest.cc +++ b/chromium/media/base/null_video_sink_unittest.cc @@ -23,6 +23,8 @@ using testing::Return; namespace media { +using RenderingMode = VideoRendererSink::RenderCallback::RenderingMode; + class NullVideoSinkTest : public testing::Test, public VideoRendererSink::RenderCallback { public: @@ -57,7 +59,7 @@ class NullVideoSinkTest : public testing::Test, MOCK_METHOD3(Render, scoped_refptr<VideoFrame>(base::TimeTicks, base::TimeTicks, - bool)); + RenderingMode)); MOCK_METHOD0(OnFrameDropped, void()); MOCK_METHOD1(FrameReceived, void(scoped_refptr<VideoFrame>)); @@ -80,7 +82,8 @@ TEST_F(NullVideoSinkTest, BasicFunctionality) { sink->Start(this); const base::TimeTicks current_time = tick_clock_.NowTicks(); const base::TimeTicks current_interval_end = current_time + kInterval; - EXPECT_CALL(*this, Render(current_time, current_interval_end, false)) + EXPECT_CALL(*this, Render(current_time, current_interval_end, + RenderingMode::kNormal)) .WillOnce(Return(test_frame)); WaitableMessageLoopEvent event; EXPECT_CALL(*this, FrameReceived(test_frame)) @@ -98,7 +101,7 @@ TEST_F(NullVideoSinkTest, BasicFunctionality) { SCOPED_TRACE("Waiting for second render call."); WaitableMessageLoopEvent event; scoped_refptr<VideoFrame> test_frame_2 = CreateFrame(kInterval); - EXPECT_CALL(*this, Render(_, _, true)) + EXPECT_CALL(*this, Render(_, _, RenderingMode::kBackground)) .WillOnce(Return(test_frame)) .WillOnce(Return(test_frame_2)); EXPECT_CALL(*this, FrameReceived(test_frame)).Times(0); @@ -141,11 +144,13 @@ TEST_F(NullVideoSinkTest, ClocklessFunctionality) { for (int i = 0; i < kTestRuns; ++i) { if (i < kTestRuns - 1) { EXPECT_CALL(*this, Render(current_time + i * interval, - current_time + (i + 1) * interval, false)) + current_time + (i + 1) * interval, + RenderingMode::kNormal)) .WillOnce(Return(test_frame)); } else { EXPECT_CALL(*this, Render(current_time + i * interval, - current_time + (i + 1) * interval, false)) + current_time + (i + 1) * interval, + RenderingMode::kNormal)) .WillOnce( DoAll(RunOnceClosure(event.GetClosure()), Return(test_frame_2))); } diff --git a/chromium/media/base/offloading_audio_encoder_unittest.cc b/chromium/media/base/offloading_audio_encoder_unittest.cc index aba0fd86ab7..b1377ae44c8 100644 --- a/chromium/media/base/offloading_audio_encoder_unittest.cc +++ b/chromium/media/base/offloading_audio_encoder_unittest.cc @@ -9,6 +9,7 @@ #include "base/callback_helpers.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h" +#include "base/task/thread_pool.h" #include "base/test/bind.h" #include "base/test/gmock_callback_support.h" #include "base/test/task_environment.h" diff --git a/chromium/media/base/offloading_video_encoder_unittest.cc b/chromium/media/base/offloading_video_encoder_unittest.cc index 3bccecf3552..8b2bc0a28b5 100644 --- a/chromium/media/base/offloading_video_encoder_unittest.cc +++ b/chromium/media/base/offloading_video_encoder_unittest.cc @@ -9,6 +9,7 @@ #include "base/callback_helpers.h" #include "base/run_loop.h" #include "base/sequenced_task_runner.h" +#include "base/task/thread_pool.h" #include "base/test/bind.h" #include "base/test/gmock_callback_support.h" #include "base/test/task_environment.h" diff --git a/chromium/media/base/pipeline_impl.cc b/chromium/media/base/pipeline_impl.cc index 2d4cdcc0274..9eeeb52b324 100644 --- a/chromium/media/base/pipeline_impl.cc +++ b/chromium/media/base/pipeline_impl.cc @@ -5,6 +5,7 @@ #include "media/base/pipeline_impl.h" #include <algorithm> +#include <memory> #include <utility> #include "base/bind.h" @@ -944,6 +945,7 @@ void PipelineImpl::RendererWrapper::SetState(State next_state) { void PipelineImpl::RendererWrapper::CompleteSeek(base::TimeDelta seek_time, PipelineStatus status) { + DVLOG(1) << __func__ << ": seek_time=" << seek_time << ", status=" << status; DCHECK(media_task_runner_->BelongsToCurrentThread()); DCHECK(state_ == kStarting || state_ == kSeeking || state_ == kResuming); @@ -1047,6 +1049,7 @@ void PipelineImpl::RendererWrapper::OnRendererCreated( void PipelineImpl::RendererWrapper::InitializeRenderer( PipelineStatusCallback done_cb) { + DVLOG(1) << __func__; DCHECK(media_task_runner_->BelongsToCurrentThread()); switch (demuxer_->GetType()) { @@ -1186,8 +1189,8 @@ PipelineImpl::PipelineImpl( DVLOG(2) << __func__; DCHECK(create_renderer_cb_); - renderer_wrapper_.reset(new RendererWrapper( - media_task_runner_, std::move(main_task_runner), media_log_)); + renderer_wrapper_ = std::make_unique<RendererWrapper>( + media_task_runner_, std::move(main_task_runner), media_log_); } PipelineImpl::~PipelineImpl() { @@ -1655,7 +1658,7 @@ void PipelineImpl::OnVideoDecoderChange(const VideoDecoderInfo& info) { } void PipelineImpl::OnSeekDone(bool is_suspended) { - DVLOG(3) << __func__; + DVLOG(3) << __func__ << ": is_suspended=" << is_suspended; DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(IsRunning()); diff --git a/chromium/media/base/pipeline_impl_unittest.cc b/chromium/media/base/pipeline_impl_unittest.cc index c3f411582b8..8ff37cf90bc 100644 --- a/chromium/media/base/pipeline_impl_unittest.cc +++ b/chromium/media/base/pipeline_impl_unittest.cc @@ -301,7 +301,7 @@ class PipelineImplTest : public ::testing::Test { void ResetRenderer() { // |renderer_| has been deleted, replace it. - scoped_renderer_.reset(new StrictMock<MockRenderer>()); + scoped_renderer_ = std::make_unique<StrictMock<MockRenderer>>(); renderer_ = scoped_renderer_.get(); EXPECT_CALL(*renderer_, SetPreservesPitch(_)).Times(AnyNumber()); } diff --git a/chromium/media/base/shared_memory_pool.cc b/chromium/media/base/shared_memory_pool.cc deleted file mode 100644 index acbca840f9d..00000000000 --- a/chromium/media/base/shared_memory_pool.cc +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2021 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/shared_memory_pool.h" - -#include "base/logging.h" - -namespace { -constexpr size_t kMaxStoredBuffers = 32; -} // namespace - -namespace media { - -SharedMemoryPool::SharedMemoryPool() = default; - -SharedMemoryPool::~SharedMemoryPool() = default; - -SharedMemoryPool::SharedMemoryHandle::SharedMemoryHandle( - base::UnsafeSharedMemoryRegion region, - base::WritableSharedMemoryMapping mapping, - scoped_refptr<SharedMemoryPool> pool) - : region_(std::move(region)), - mapping_(std::move(mapping)), - pool_(std::move(pool)) { - CHECK(pool_); - DCHECK(region_.IsValid()); - DCHECK(mapping_.IsValid()); -} - -SharedMemoryPool::SharedMemoryHandle::~SharedMemoryHandle() { - pool_->ReleaseBuffer(std::move(region_), std::move(mapping_)); -} - -base::UnsafeSharedMemoryRegion* -SharedMemoryPool::SharedMemoryHandle::GetRegion() { - return ®ion_; -} - -base::WritableSharedMemoryMapping* -SharedMemoryPool::SharedMemoryHandle::GetMapping() { - return &mapping_; -} - -std::unique_ptr<SharedMemoryPool::SharedMemoryHandle> -SharedMemoryPool::MaybeAllocateBuffer(size_t region_size) { - base::AutoLock lock(lock_); - - DCHECK_GE(region_size, 0u); - if (is_shutdown_) - return nullptr; - - // Only change the configured size if bigger region is requested to avoid - // unncecessary reallocations. - if (region_size > region_size_) { - mappings_.clear(); - regions_.clear(); - region_size_ = region_size; - } - if (!regions_.empty()) { - DCHECK_EQ(mappings_.size(), regions_.size()); - DCHECK_GE(regions_.back().GetSize(), region_size_); - auto handle = std::make_unique<SharedMemoryHandle>( - std::move(regions_.back()), std::move(mappings_.back()), this); - regions_.pop_back(); - mappings_.pop_back(); - return handle; - } - - auto region = base::UnsafeSharedMemoryRegion::Create(region_size_); - if (!region.IsValid()) - return nullptr; - - base::WritableSharedMemoryMapping mapping = region.Map(); - if (!mapping.IsValid()) - return nullptr; - - return std::make_unique<SharedMemoryHandle>(std::move(region), - std::move(mapping), this); -} - -void SharedMemoryPool::Shutdown() { - base::AutoLock lock(lock_); - DCHECK(!is_shutdown_); - is_shutdown_ = true; - mappings_.clear(); - regions_.clear(); -} - -void SharedMemoryPool::ReleaseBuffer( - base::UnsafeSharedMemoryRegion region, - base::WritableSharedMemoryMapping mapping) { - base::AutoLock lock(lock_); - // Only return regions which are at least as big as the current configuration. - if (is_shutdown_ || regions_.size() >= kMaxStoredBuffers || - !region.IsValid() || region.GetSize() < region_size_) { - DLOG(WARNING) << "Not returning SharedMemoryRegion to the pool:" - << " is_shutdown: " << (is_shutdown_ ? "true" : "false") - << " stored regions: " << regions_.size() - << " configured size: " << region_size_ - << " this region size: " << region.GetSize() - << " valid: " << (region.IsValid() ? "true" : "false"); - return; - } - regions_.emplace_back(std::move(region)); - mappings_.emplace_back(std::move(mapping)); -} - -} // namespace media diff --git a/chromium/media/base/shared_memory_pool.h b/chromium/media/base/shared_memory_pool.h deleted file mode 100644 index 4de5d710230..00000000000 --- a/chromium/media/base/shared_memory_pool.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2021 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_SHARED_MEMORY_POOL_H_ -#define MEDIA_BASE_SHARED_MEMORY_POOL_H_ - -#include <vector> - -#include "base/memory/ref_counted.h" -#include "base/memory/unsafe_shared_memory_region.h" -#include "base/synchronization/lock.h" -#include "media/base/media_export.h" - -namespace media { - -// SharedMemoryPool manages allocation and pooling of UnsafeSharedMemoryRegions. -// It is thread-safe. -// May return bigger regions than requested. -// If a requested size is increased, all stored regions are purged. -// Regions are returned to the buffer on destruction of |SharedMemoryHandle| if -// they are of a correct size. -class MEDIA_EXPORT SharedMemoryPool - : public base::RefCountedThreadSafe<SharedMemoryPool> { - public: - // Used to store the allocation result. - // This class returns memory to the pool upon destruction. - class MEDIA_EXPORT SharedMemoryHandle { - public: - SharedMemoryHandle(base::UnsafeSharedMemoryRegion region, - base::WritableSharedMemoryMapping mapping, - scoped_refptr<SharedMemoryPool> pool); - ~SharedMemoryHandle(); - // Disallow copy and assign. - SharedMemoryHandle(const SharedMemoryHandle&) = delete; - SharedMemoryHandle& operator=(const SharedMemoryHandle&) = delete; - - base::UnsafeSharedMemoryRegion* GetRegion(); - - base::WritableSharedMemoryMapping* GetMapping(); - - private: - base::UnsafeSharedMemoryRegion region_; - base::WritableSharedMemoryMapping mapping_; - scoped_refptr<SharedMemoryPool> pool_; - }; - - SharedMemoryPool(); - // Disallow copy and assign. - SharedMemoryPool(const SharedMemoryPool&) = delete; - SharedMemoryPool& operator=(const SharedMemoryPool&) = delete; - - // Allocates a region of the given |size| or reuses a previous allocation if - // possible. - std::unique_ptr<SharedMemoryHandle> MaybeAllocateBuffer(size_t size); - - // Shuts down the pool, freeing all currently unused allocations and freeing - // outstanding ones as they are returned. - void Shutdown(); - - private: - friend class base::RefCountedThreadSafe<SharedMemoryPool>; - ~SharedMemoryPool(); - - void ReleaseBuffer(base::UnsafeSharedMemoryRegion region, - base::WritableSharedMemoryMapping mapping); - - base::Lock lock_; - size_t region_size_ GUARDED_BY(lock_) = 0u; - std::vector<base::UnsafeSharedMemoryRegion> regions_ GUARDED_BY(lock_); - std::vector<base::WritableSharedMemoryMapping> mappings_ GUARDED_BY(lock_); - bool is_shutdown_ GUARDED_BY(lock_) = false; -}; - -} // namespace media - -#endif // MEDIA_BASE_SHARED_MEMORY_POOL_H_ diff --git a/chromium/media/base/shared_memory_pool_unittest.cc b/chromium/media/base/shared_memory_pool_unittest.cc deleted file mode 100644 index 2fb9f951621..00000000000 --- a/chromium/media/base/shared_memory_pool_unittest.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2021 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/shared_memory_pool.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -TEST(SharedMemoryPoolTest, CreatesRegion) { - scoped_refptr<SharedMemoryPool> pool( - base::MakeRefCounted<SharedMemoryPool>()); - auto handle = pool->MaybeAllocateBuffer(1000); - ASSERT_TRUE(handle); - ASSERT_TRUE(handle->GetRegion()); - EXPECT_TRUE(handle->GetRegion()->IsValid()); - ASSERT_TRUE(handle->GetMapping()); - EXPECT_TRUE(handle->GetMapping()->IsValid()); -} - -TEST(SharedMemoryPoolTest, ReusesRegions) { - scoped_refptr<SharedMemoryPool> pool( - base::MakeRefCounted<SharedMemoryPool>()); - auto handle = pool->MaybeAllocateBuffer(1000u); - ASSERT_TRUE(handle); - base::UnsafeSharedMemoryRegion* region = handle->GetRegion(); - auto id1 = region->GetGUID(); - - // Return memory to the pool. - handle.reset(); - - handle = pool->MaybeAllocateBuffer(1000u); - region = handle->GetRegion(); - // Should reuse the freed region. - EXPECT_EQ(id1, region->GetGUID()); -} - -TEST(SharedMemoryPoolTest, RespectsSize) { - scoped_refptr<SharedMemoryPool> pool( - base::MakeRefCounted<SharedMemoryPool>()); - auto handle = pool->MaybeAllocateBuffer(1000u); - ASSERT_TRUE(handle); - ASSERT_TRUE(handle->GetRegion()); - EXPECT_GE(handle->GetRegion()->GetSize(), 1000u); - - handle = pool->MaybeAllocateBuffer(100u); - ASSERT_TRUE(handle); - ASSERT_TRUE(handle->GetRegion()); - EXPECT_GE(handle->GetRegion()->GetSize(), 100u); - - handle = pool->MaybeAllocateBuffer(1100u); - ASSERT_TRUE(handle); - ASSERT_TRUE(handle->GetRegion()); - EXPECT_GE(handle->GetRegion()->GetSize(), 1100u); -} -} // namespace media diff --git a/chromium/media/base/sinc_resampler.cc b/chromium/media/base/sinc_resampler.cc index e6ff66411ff..06c85f9349b 100644 --- a/chromium/media/base/sinc_resampler.cc +++ b/chromium/media/base/sinc_resampler.cc @@ -84,13 +84,15 @@ #include "cc/base/math_util.h" #if defined(ARCH_CPU_X86_FAMILY) -#include <xmmintrin.h> -#define CONVOLVE_FUNC Convolve_SSE +#include <immintrin.h> +// Including these headers directly should generally be avoided. Since +// Chrome is compiled with -msse3 (the minimal requirement), we include the +// headers directly to make the intrinsics available. +#include <avxintrin.h> +#include <avx2intrin.h> +#include <fmaintrin.h> #elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) #include <arm_neon.h> -#define CONVOLVE_FUNC Convolve_NEON -#else -#define CONVOLVE_FUNC Convolve_C #endif namespace media { @@ -111,6 +113,25 @@ static double SincScaleFactor(double io_ratio) { return sinc_scale_factor; } +// If we know the minimum architecture at compile time, avoid CPU detection. +void SincResampler::InitializeCPUSpecificFeatures() { +#if defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) + convolve_proc_ = Convolve_NEON; +#elif defined(ARCH_CPU_X86_FAMILY) + base::CPU cpu; + // Using AVX2 instead of SSE2 when AVX2 supported. + if (cpu.has_avx2()) + convolve_proc_ = Convolve_AVX2; + else if (cpu.has_sse2()) + convolve_proc_ = Convolve_SSE; + else + convolve_proc_ = Convolve_C; +#else + // Unknown architecture. + convolve_proc_ = Convolve_C; +#endif +} + static int CalculateChunkSize(int block_size_, double io_ratio) { return block_size_ / io_ratio; } @@ -122,17 +143,19 @@ SincResampler::SincResampler(double io_sample_rate_ratio, read_cb_(std::move(read_cb)), request_frames_(request_frames), input_buffer_size_(request_frames_ + kKernelSize), - // Create input buffers with a 16-byte alignment for SSE optimizations. + // Create input buffers with a 32-byte alignment for SIMD optimizations. kernel_storage_(static_cast<float*>( - base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 16))), + base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 32))), kernel_pre_sinc_storage_(static_cast<float*>( - base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 16))), + base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 32))), kernel_window_storage_(static_cast<float*>( - base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 16))), + base::AlignedAlloc(sizeof(float) * kKernelStorageSize, 32))), input_buffer_(static_cast<float*>( - base::AlignedAlloc(sizeof(float) * input_buffer_size_, 16))), + base::AlignedAlloc(sizeof(float) * input_buffer_size_, 32))), r1_(input_buffer_.get()), r2_(input_buffer_.get() + kKernelSize / 2) { + InitializeCPUSpecificFeatures(); + DCHECK(convolve_proc_); CHECK_GT(request_frames_, 0); Flush(); CHECK_GT(block_size_, kKernelSize) @@ -259,10 +282,10 @@ void SincResampler::Resample(int frames, float* destination) { const float* k1 = kernel_storage_.get() + offset_idx * kKernelSize; const float* k2 = k1 + kKernelSize; - // Ensure |k1|, |k2| are 16-byte aligned for SIMD usage. Should always - // be true so long as kKernelSize is a multiple of 16. - DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(k1) & 0x0F); - DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(k2) & 0x0F); + // Ensure |k1|, |k2| are 32-byte aligned for SIMD usage. Should always + // be true so long as kKernelSize is a multiple of 32. + DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(k1) & 0x1F); + DCHECK_EQ(0u, reinterpret_cast<uintptr_t>(k2) & 0x1F); // Initialize input pointer based on quantized |virtual_source_idx_|. const float* input_ptr = r1_ + source_idx; @@ -271,7 +294,7 @@ void SincResampler::Resample(int frames, float* destination) { const double kernel_interpolation_factor = virtual_offset_idx - offset_idx; *destination++ = - CONVOLVE_FUNC(input_ptr, k1, k2, kernel_interpolation_factor); + convolve_proc_(input_ptr, k1, k2, kernel_interpolation_factor); // Advance the virtual index. virtual_source_idx_ += io_sample_rate_ratio_; @@ -383,6 +406,53 @@ float SincResampler::Convolve_SSE(const float* input_ptr, const float* k1, return result; } + +__attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2( + const float* input_ptr, + const float* k1, + const float* k2, + double kernel_interpolation_factor) { + __m256 m_input; + __m256 m_sums1 = _mm256_setzero_ps(); + __m256 m_sums2 = _mm256_setzero_ps(); + + // Based on |input_ptr| alignment, we need to use loadu or load. Unrolling + // these loops has not been tested or benchmarked. + bool aligned_input = (reinterpret_cast<uintptr_t>(input_ptr) & 0x1F) == 0; + if (!aligned_input) { + for (size_t i = 0; i < kKernelSize; i += 8) { + m_input = _mm256_loadu_ps(input_ptr + i); + m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1); + m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2); + } + } else { + for (size_t i = 0; i < kKernelSize; i += 8) { + m_input = _mm256_load_ps(input_ptr + i); + m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1); + m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2); + } + } + + // Linearly interpolate the two "convolutions". + __m128 m128_sums1 = _mm_add_ps(_mm256_extractf128_ps(m_sums1, 0), + _mm256_extractf128_ps(m_sums1, 1)); + __m128 m128_sums2 = _mm_add_ps(_mm256_extractf128_ps(m_sums2, 0), + _mm256_extractf128_ps(m_sums2, 1)); + m128_sums1 = _mm_mul_ps( + m128_sums1, + _mm_set_ps1(static_cast<float>(1.0 - kernel_interpolation_factor))); + m128_sums2 = _mm_mul_ps( + m128_sums2, _mm_set_ps1(static_cast<float>(kernel_interpolation_factor))); + m128_sums1 = _mm_add_ps(m128_sums1, m128_sums2); + + // Sum components together. + float result; + m128_sums2 = _mm_add_ps(_mm_movehl_ps(m128_sums1, m128_sums1), m128_sums1); + _mm_store_ss(&result, _mm_add_ss(m128_sums2, + _mm_shuffle_ps(m128_sums2, m128_sums2, 1))); + + return result; +} #elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) float SincResampler::Convolve_NEON(const float* input_ptr, const float* k1, const float* k2, diff --git a/chromium/media/base/sinc_resampler.h b/chromium/media/base/sinc_resampler.h index b8f42d691a2..93578c76513 100644 --- a/chromium/media/base/sinc_resampler.h +++ b/chromium/media/base/sinc_resampler.h @@ -106,12 +106,20 @@ class MEDIA_EXPORT SincResampler { static float Convolve_SSE(const float* input_ptr, const float* k1, const float* k2, double kernel_interpolation_factor); + static float Convolve_AVX2(const float* input_ptr, + const float* k1, + const float* k2, + double kernel_interpolation_factor); #elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) static float Convolve_NEON(const float* input_ptr, const float* k1, const float* k2, double kernel_interpolation_factor); #endif + // Selects runtime specific CPU features like SSE. Must be called before + // using SincResampler. + void InitializeCPUSpecificFeatures(); + // The ratio of input / output sample rates. double io_sample_rate_ratio_; @@ -148,6 +156,13 @@ class MEDIA_EXPORT SincResampler { // Data from the source is copied into this buffer for each processing pass. std::unique_ptr<float[], base::AlignedFreeDeleter> input_buffer_; + // Stores the runtime selection of which Convolve function to use. + using ConvolveProc = float (*)(const float*, + const float*, + const float*, + double); + ConvolveProc convolve_proc_; + // Pointers to the various regions inside |input_buffer_|. See the diagram at // the top of the .cc file for more information. float* r0_; diff --git a/chromium/media/base/sinc_resampler_perftest.cc b/chromium/media/base/sinc_resampler_perftest.cc index 905d8b98c2e..9570e792bd7 100644 --- a/chromium/media/base/sinc_resampler_perftest.cc +++ b/chromium/media/base/sinc_resampler_perftest.cc @@ -18,13 +18,6 @@ static const int kBenchmarkIterations = 50000000; static const double kSampleRateRatio = 192000.0 / 44100.0; static const double kKernelInterpolationFactor = 0.5; -// Define platform independent function name for Convolve* tests. -#if defined(ARCH_CPU_X86_FAMILY) -#define CONVOLVE_FUNC Convolve_SSE -#elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) -#define CONVOLVE_FUNC Convolve_NEON -#endif - static void RunConvolveBenchmark( float (*convolve_fn)(const float*, const float*, const float*, double), bool aligned, @@ -51,17 +44,35 @@ TEST(SincResamplerPerfTest, Convolve_unoptimized_aligned) { RunConvolveBenchmark(SincResampler::Convolve_C, true, "unoptimized_aligned"); } -#if defined(CONVOLVE_FUNC) TEST(SincResamplerPerfTest, Convolve_optimized_aligned) { - RunConvolveBenchmark(SincResampler::CONVOLVE_FUNC, true, "optimized_aligned"); +#if defined(ARCH_CPU_X86_FAMILY) + base::CPU cpu; + if (cpu.has_avx2()) { + RunConvolveBenchmark(SincResampler::Convolve_AVX2, true, + "optimized_aligned"); + } else if (cpu.has_sse2()) { + RunConvolveBenchmark(SincResampler::Convolve_SSE, true, + "optimized_aligned"); + } +#elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) + RunConvolveBenchmark(SincResampler::Convolve_NEON, true, "optimized_aligned"); +#endif } TEST(SincResamplerPerfTest, Convolve_optimized_unaligned) { - RunConvolveBenchmark(SincResampler::CONVOLVE_FUNC, false, +#if defined(ARCH_CPU_X86_FAMILY) + base::CPU cpu; + if (cpu.has_avx2()) { + RunConvolveBenchmark(SincResampler::Convolve_AVX2, false, + "optimized_unaligned"); + } else if (cpu.has_sse2()) { + RunConvolveBenchmark(SincResampler::Convolve_SSE, false, + "optimized_unaligned"); + } +#elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) + RunConvolveBenchmark(SincResampler::Convolve_NEON, false, "optimized_unaligned"); -} #endif - -#undef CONVOLVE_FUNC +} } // namespace media diff --git a/chromium/media/base/sinc_resampler_unittest.cc b/chromium/media/base/sinc_resampler_unittest.cc index 195da5d1f9e..79d393869ed 100644 --- a/chromium/media/base/sinc_resampler_unittest.cc +++ b/chromium/media/base/sinc_resampler_unittest.cc @@ -148,18 +148,9 @@ TEST(SincResamplerTest, DISABLED_SetRatioBench) { printf("SetRatio() took %.2fms.\n", total_time_c_ms); } - -// Define platform independent function name for Convolve* tests. -#if defined(ARCH_CPU_X86_FAMILY) -#define CONVOLVE_FUNC Convolve_SSE -#elif defined(ARCH_CPU_ARM_FAMILY) && defined(USE_NEON) -#define CONVOLVE_FUNC Convolve_NEON -#endif - // Ensure various optimized Convolve() methods return the same value. Only run // this test if other optimized methods exist, otherwise the default Convolve() // will be tested by the parameterized SincResampler tests below. -#if defined(CONVOLVE_FUNC) static const double kKernelInterpolationFactor = 0.5; TEST(SincResamplerTest, Convolve) { @@ -178,7 +169,7 @@ TEST(SincResamplerTest, Convolve) { double result = resampler.Convolve_C( resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), kKernelInterpolationFactor); - double result2 = resampler.CONVOLVE_FUNC( + double result2 = resampler.convolve_proc_( resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), kKernelInterpolationFactor); EXPECT_NEAR(result2, result, kEpsilon); @@ -187,12 +178,11 @@ TEST(SincResamplerTest, Convolve) { result = resampler.Convolve_C( resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), kKernelInterpolationFactor); - result2 = resampler.CONVOLVE_FUNC( + result2 = resampler.convolve_proc_( resampler.kernel_storage_.get() + 1, resampler.kernel_storage_.get(), resampler.kernel_storage_.get(), kKernelInterpolationFactor); EXPECT_NEAR(result2, result, kEpsilon); } -#endif // Fake audio source for testing the resampler. Generates a sinusoidal linear // chirp (http://en.wikipedia.org/wiki/Chirp) which can be tuned to stress the diff --git a/chromium/media/base/test_helpers.cc b/chromium/media/base/test_helpers.cc index 84f8a2047cf..3858e86f3bd 100644 --- a/chromium/media/base/test_helpers.cc +++ b/chromium/media/base/test_helpers.cc @@ -6,6 +6,8 @@ #include <stdint.h> +#include <memory> + #include "base/bind.h" #include "base/check_op.h" #include "base/macros.h" @@ -98,7 +100,7 @@ void WaitableMessageLoopEvent::RunAndWaitForStatus(PipelineStatus expected) { return; } - run_loop_.reset(new base::RunLoop()); + run_loop_ = std::make_unique<base::RunLoop>(); base::OneShotTimer timer; timer.Start(FROM_HERE, timeout_, base::BindOnce(&WaitableMessageLoopEvent::OnTimeout, diff --git a/chromium/media/base/text_renderer_unittest.cc b/chromium/media/base/text_renderer_unittest.cc index d6ab92c4733..b00a269c0ea 100644 --- a/chromium/media/base/text_renderer_unittest.cc +++ b/chromium/media/base/text_renderer_unittest.cc @@ -54,10 +54,10 @@ class TextRendererTest : public testing::Test { void CreateTextRenderer() { DCHECK(!text_renderer_); - text_renderer_.reset( - new TextRenderer(task_environment_.GetMainThreadTaskRunner(), - base::BindRepeating(&TextRendererTest::OnAddTextTrack, - base::Unretained(this)))); + text_renderer_ = std::make_unique<TextRenderer>( + task_environment_.GetMainThreadTaskRunner(), + base::BindRepeating(&TextRendererTest::OnAddTextTrack, + base::Unretained(this))); text_renderer_->Initialize( base::BindRepeating(&TextRendererTest::OnEnd, base::Unretained(this))); } @@ -206,10 +206,10 @@ class TextRendererTest : public testing::Test { }; TEST_F(TextRendererTest, CreateTextRendererNoInit) { - text_renderer_.reset( - new TextRenderer(task_environment_.GetMainThreadTaskRunner(), - base::BindRepeating(&TextRendererTest::OnAddTextTrack, - base::Unretained(this)))); + text_renderer_ = std::make_unique<TextRenderer>( + task_environment_.GetMainThreadTaskRunner(), + base::BindRepeating(&TextRendererTest::OnAddTextTrack, + base::Unretained(this))); text_renderer_.reset(); } diff --git a/chromium/media/base/user_input_monitor_mac.cc b/chromium/media/base/user_input_monitor_mac.cc index 585cb01b895..eac1a4fbd2d 100644 --- a/chromium/media/base/user_input_monitor_mac.cc +++ b/chromium/media/base/user_input_monitor_mac.cc @@ -9,6 +9,7 @@ #include <memory> #include "base/macros.h" +#include "base/single_thread_task_runner.h" #include "base/timer/timer.h" namespace media { diff --git a/chromium/media/base/video_encoder.h b/chromium/media/base/video_encoder.h index d1a590a4086..4a5eb6bda79 100644 --- a/chromium/media/base/video_encoder.h +++ b/chromium/media/base/video_encoder.h @@ -30,6 +30,7 @@ struct MEDIA_EXPORT VideoEncoderOutput { base::TimeDelta timestamp; bool key_frame = false; + int temporal_id = 0; }; class MEDIA_EXPORT VideoEncoder { @@ -50,6 +51,9 @@ class MEDIA_EXPORT VideoEncoder { base::Optional<int> keyframe_interval = 10000; + // Requested number of SVC temporal layers. + int temporal_layers = 1; + // Only used for H264 encoding. AvcOptions avc; }; diff --git a/chromium/media/base/video_frame.cc b/chromium/media/base/video_frame.cc index 914a4a3a267..452b1782164 100644 --- a/chromium/media/base/video_frame.cc +++ b/chromium/media/base/video_frame.cc @@ -157,13 +157,13 @@ gfx::Size VideoFrame::SampleSize(VideoPixelFormat format, size_t plane) { // Checks if |source_format| can be wrapped into a |target_format| frame. static bool AreValidPixelFormatsForWrap(VideoPixelFormat source_format, VideoPixelFormat target_format) { - if (source_format == target_format) - return true; - - // It is possible to add other planar to planar format conversions here if the - // use case is there. - return source_format == PIXEL_FORMAT_I420A && - target_format == PIXEL_FORMAT_I420; + return source_format == target_format || + (source_format == PIXEL_FORMAT_I420A && + target_format == PIXEL_FORMAT_I420) || + (source_format == PIXEL_FORMAT_ARGB && + target_format == PIXEL_FORMAT_XRGB) || + (source_format == PIXEL_FORMAT_ABGR && + target_format == PIXEL_FORMAT_XBGR); } // If it is required to allocate aligned to multiple-of-two size overall for the @@ -306,11 +306,6 @@ bool VideoFrame::IsValidConfig(VideoPixelFormat format, return false; } - // TODO(mcasas): Remove parameter |storage_type| when the opaque storage types - // comply with the checks below. Right now we skip them. - if (!IsStorageTypeMappable(storage_type)) - return true; - // Make sure new formats are properly accounted for in the method. static_assert(PIXEL_FORMAT_MAX == 33, "Added pixel format, please review IsValidConfig()"); @@ -1127,7 +1122,8 @@ void VideoFrame::HashFrameForTesting(base::MD5Context* context, } } -void VideoFrame::BackWithSharedMemory(base::UnsafeSharedMemoryRegion* region) { +void VideoFrame::BackWithSharedMemory( + const base::UnsafeSharedMemoryRegion* region) { DCHECK(!shm_region_); DCHECK(!owned_shm_region_.IsValid()); // Either we should be backing a frame created with WrapExternal*, or we are diff --git a/chromium/media/base/video_frame.h b/chromium/media/base/video_frame.h index 5bf0cacebf1..cf10ff045c1 100644 --- a/chromium/media/base/video_frame.h +++ b/chromium/media/base/video_frame.h @@ -404,7 +404,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { // // The region is NOT owned by the video frame. Both the region and its // associated mapping must outlive this instance. - void BackWithSharedMemory(base::UnsafeSharedMemoryRegion* region); + void BackWithSharedMemory(const base::UnsafeSharedMemoryRegion* region); // As above, but the VideoFrame owns the shared memory region as well as the // mapping. They will be destroyed with their VideoFrame. @@ -412,7 +412,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { base::WritableSharedMemoryMapping mapping); // Valid for shared memory backed VideoFrames. - base::UnsafeSharedMemoryRegion* shm_region() { + const base::UnsafeSharedMemoryRegion* shm_region() { DCHECK(IsValidSharedMemoryFrame()); DCHECK(storage_type_ == STORAGE_SHMEM); return shm_region_; @@ -578,9 +578,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { // This is the media timestamp, and not the reference time. // See VideoFrameMetadata::REFERENCE_TIME for details. base::TimeDelta timestamp() const { return timestamp_; } - void set_timestamp(base::TimeDelta timestamp) { - timestamp_ = timestamp; - } + void set_timestamp(base::TimeDelta timestamp) { timestamp_ = timestamp; } // It uses |client| to insert a new sync token and potentially waits on an // older sync token. The final sync point will be used to release this @@ -689,7 +687,7 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> { // Shared memory handle, if this frame is STORAGE_SHMEM. The region pointed // to is unowned. - base::UnsafeSharedMemoryRegion* shm_region_ = nullptr; + const base::UnsafeSharedMemoryRegion* shm_region_ = nullptr; // Used if this is a STORAGE_SHMEM frame with owned shared memory. In that // case, shm_region_ will refer to this region. diff --git a/chromium/media/base/video_frame_feedback.cc b/chromium/media/base/video_frame_feedback.cc deleted file mode 100644 index 9dcfae837e1..00000000000 --- a/chromium/media/base/video_frame_feedback.cc +++ /dev/null @@ -1,50 +0,0 @@ -// 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 deleted file mode 100644 index 348412b1349..00000000000 --- a/chromium/media/base/video_frame_feedback.h +++ /dev/null @@ -1,83 +0,0 @@ -// 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 "base/callback.h" -#include "media/base/media_export.h" - -namespace media { - -struct VideoFrameFeedback; - -using VideoCaptureFeedbackCB = - base::RepeatingCallback<void(const VideoFrameFeedback&)>; - -// 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; - } - - bool operator!=(const VideoFrameFeedback& other) const { - return !(*this == other); - } - - // 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_renderer_sink.h b/chromium/media/base/video_renderer_sink.h index 62442035a12..b7b034cdd02 100644 --- a/chromium/media/base/video_renderer_sink.h +++ b/chromium/media/base/video_renderer_sink.h @@ -19,6 +19,12 @@ class MEDIA_EXPORT VideoRendererSink { public: class RenderCallback { public: + enum class RenderingMode { + kNormal, // Normal operation. + kStartup, // Render() is requested during Start(). + kBackground, // Render() is being driven by background timer. + }; + // Returns a VideoFrame for rendering which should be displayed within the // presentation interval [|deadline_min|, |deadline_max|]. Returns NULL if // no frame or no new frame (since the last Render() call) is available for @@ -31,7 +37,7 @@ class MEDIA_EXPORT VideoRendererSink { // Render() call may not be used. virtual scoped_refptr<VideoFrame> Render(base::TimeTicks deadline_min, base::TimeTicks deadline_max, - bool background_rendering) = 0; + RenderingMode rendering_mode) = 0; // Called by the sink when a VideoFrame previously returned via Render() was // not actually rendered. Must be called before the next Render() call. diff --git a/chromium/media/base/video_types.h b/chromium/media/base/video_types.h index 2187f23272c..b0ce5ceeebf 100644 --- a/chromium/media/base/video_types.h +++ b/chromium/media/base/video_types.h @@ -10,7 +10,7 @@ #include <string> #include "build/build_config.h" -#include "media/base/media_export.h" +#include "media/base/media_shmem_export.h" namespace media { @@ -85,26 +85,27 @@ enum VideoPixelFormat { }; // Returns the name of a Format as a string. -MEDIA_EXPORT std::string VideoPixelFormatToString(VideoPixelFormat format); +MEDIA_SHMEM_EXPORT std::string VideoPixelFormatToString( + VideoPixelFormat format); // Stream operator of Format for logging etc. -MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, - VideoPixelFormat format); +MEDIA_SHMEM_EXPORT std::ostream& operator<<(std::ostream& os, + VideoPixelFormat format); // Returns human readable fourcc string. // If any of the four characters is non-printable, it outputs // "0x<32-bit integer in hex>", e.g. FourccToString(0x66616b00) returns // "0x66616b00". -MEDIA_EXPORT std::string FourccToString(uint32_t fourcc); +MEDIA_SHMEM_EXPORT std::string FourccToString(uint32_t fourcc); // Returns true if |format| is a YUV format with multiple planes. -MEDIA_EXPORT bool IsYuvPlanar(VideoPixelFormat format); +MEDIA_SHMEM_EXPORT bool IsYuvPlanar(VideoPixelFormat format); // Returns true if |format| has no Alpha channel (hence is always opaque). -MEDIA_EXPORT bool IsOpaque(VideoPixelFormat format); +MEDIA_SHMEM_EXPORT bool IsOpaque(VideoPixelFormat format); // Returns the number of significant bits per channel. -MEDIA_EXPORT size_t BitDepth(VideoPixelFormat format); +MEDIA_SHMEM_EXPORT size_t BitDepth(VideoPixelFormat format); } // namespace media diff --git a/chromium/media/base/video_util.cc b/chromium/media/base/video_util.cc index 5f26611aa07..ba9fa0799f3 100644 --- a/chromium/media/base/video_util.cc +++ b/chromium/media/base/video_util.cc @@ -944,16 +944,34 @@ Status ConvertAndScaleFrame(const VideoFrame& src_frame, .WithData("dst", dst_frame.AsHumanReadableString()); } +MEDIA_EXPORT VideoPixelFormat +VideoPixelFormatFromSkColorType(SkColorType sk_color_type, bool is_opaque) { + switch (sk_color_type) { + case kRGBA_8888_SkColorType: + return is_opaque ? media::PIXEL_FORMAT_XBGR : media::PIXEL_FORMAT_ABGR; + case kBGRA_8888_SkColorType: + return is_opaque ? media::PIXEL_FORMAT_XRGB : media::PIXEL_FORMAT_ARGB; + default: + // TODO(crbug.com/1073995): Add F16 support. + return media::PIXEL_FORMAT_UNKNOWN; + } +} + scoped_refptr<VideoFrame> CreateFromSkImage(sk_sp<SkImage> sk_image, const gfx::Rect& visible_rect, const gfx::Size& natural_size, - base::TimeDelta timestamp) { + base::TimeDelta timestamp, + bool force_opaque) { DCHECK(!sk_image->isTextureBacked()); - // TODO(crbug.com/1073995): Add F16 support. - auto sk_color_type = sk_image->colorType(); - if (sk_color_type != kRGBA_8888_SkColorType && - sk_color_type != kBGRA_8888_SkColorType) { + // A given SkImage may not exist until it's rasterized. + if (sk_image->isLazyGenerated()) + sk_image = sk_image->makeRasterImage(); + + const auto format = VideoPixelFormatFromSkColorType( + sk_image->colorType(), sk_image->isOpaque() || force_opaque); + if (VideoFrameLayout::NumPlanes(format) != 1) { + DLOG(ERROR) << "Invalid SkColorType for CreateFromSkImage"; return nullptr; } @@ -961,13 +979,6 @@ scoped_refptr<VideoFrame> CreateFromSkImage(sk_sp<SkImage> sk_image, const bool peek_result = sk_image->peekPixels(&pm); DCHECK(peek_result); - const auto format = - sk_image->isOpaque() - ? (sk_color_type == kRGBA_8888_SkColorType ? PIXEL_FORMAT_XBGR - : PIXEL_FORMAT_XRGB) - : (sk_color_type == kRGBA_8888_SkColorType ? PIXEL_FORMAT_ABGR - : PIXEL_FORMAT_ARGB); - auto coded_size = gfx::Size(sk_image->width(), sk_image->height()); auto layout = VideoFrameLayout::CreateWithStrides( format, coded_size, std::vector<int32_t>(1, pm.rowBytes())); diff --git a/chromium/media/base/video_util.h b/chromium/media/base/video_util.h index 3590bf00e9a..64c62e69407 100644 --- a/chromium/media/base/video_util.h +++ b/chromium/media/base/video_util.h @@ -12,6 +12,7 @@ #include "base/memory/ref_counted.h" #include "media/base/media_export.h" #include "media/base/status.h" +#include "media/base/video_types.h" #include "third_party/skia/include/core/SkImage.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -149,7 +150,10 @@ MEDIA_EXPORT gfx::Size PadToMatchAspectRatio(const gfx::Size& size, // A helper function to map GpuMemoryBuffer-based VideoFrame. This function // maps the given GpuMemoryBuffer of |frame| as-is without converting pixel -// format. The returned VideoFrame owns the |frame|. +// format, unless the video frame is backed by DXGI GMB. +// The returned VideoFrame owns the |frame|. +// If the underlying buffer is DXGI, then it will be copied to shared memory +// in GPU process. MEDIA_EXPORT scoped_refptr<VideoFrame> ConvertToMemoryMappedFrame( scoped_refptr<VideoFrame> frame); @@ -197,6 +201,11 @@ MEDIA_EXPORT Status ConvertAndScaleFrame(const VideoFrame& src_frame, std::vector<uint8_t>& tmp_buf) WARN_UNUSED_RESULT; +// Converts kRGBA_8888_SkColorType and kBGRA_8888_SkColorType to the appropriate +// ARGB, XRGB, ABGR, or XBGR format. +MEDIA_EXPORT VideoPixelFormat +VideoPixelFormatFromSkColorType(SkColorType sk_color_type, bool is_opaque); + // Backs a VideoFrame with a SkImage. The created frame takes a ref on the // provided SkImage to make this operation zero copy. Only works with CPU // backed images. @@ -204,7 +213,8 @@ MEDIA_EXPORT scoped_refptr<VideoFrame> CreateFromSkImage( sk_sp<SkImage> sk_image, const gfx::Rect& visible_rect, const gfx::Size& natural_size, - base::TimeDelta timestamp); + base::TimeDelta timestamp, + bool force_opaque = false); } // namespace media diff --git a/chromium/media/base/win/dxgi_device_scope_handle_unittest.cc b/chromium/media/base/win/dxgi_device_scope_handle_unittest.cc index be16636583e..6e98c00436b 100644 --- a/chromium/media/base/win/dxgi_device_scope_handle_unittest.cc +++ b/chromium/media/base/win/dxgi_device_scope_handle_unittest.cc @@ -25,7 +25,7 @@ class DXGIDeviceScopedHandleTest : public testing::Test { if (!test_supported_) return; - ASSERT_NE(nullptr, session_ = InitializeMediaFoundation()); + ASSERT_TRUE(InitializeMediaFoundation()); // Get a shared DXGI Device Manager from Media Foundation. ASSERT_HRESULT_SUCCEEDED( @@ -60,7 +60,6 @@ class DXGIDeviceScopedHandleTest : public testing::Test { } } - MFSessionLifetime session_; Microsoft::WRL::ComPtr<IMFDXGIDeviceManager> dxgi_device_man_ = nullptr; UINT device_reset_token_ = 0; const bool test_supported_; diff --git a/chromium/media/base/win/mf_initializer.cc b/chromium/media/base/win/mf_initializer.cc index a19f79f6ff4..89b0644a73a 100644 --- a/chromium/media/base/win/mf_initializer.cc +++ b/chromium/media/base/win/mf_initializer.cc @@ -7,20 +7,59 @@ #include <mfapi.h> #include "base/logging.h" +#include "base/memory/singleton.h" -#include "base/optional.h" +namespace { -namespace media { +// MFShutdown() is sometimes very expensive if it's the last instance and +// shouldn't result in excessive memory usage to leave around, so only start it +// once and only shut it down at process exit. See https://crbug.com/1069603#c90 +// for details. +// +// Note: Most Chrome process exits will not invoke the AtExit handler, so +// MFShutdown() will generally not be called. However, we use the default +// singleton traits (which register an AtExit handler) for tests and remoting. +class MediaFoundationSession { + public: + static MediaFoundationSession* GetInstance() { + return base::Singleton<MediaFoundationSession>::get(); + } -MFSessionLifetime InitializeMediaFoundation() { - if (MFStartup(MF_VERSION, MFSTARTUP_LITE) == S_OK) - return std::make_unique<MFSession>(); - DVLOG(1) << "Media Foundation unavailable or it failed to initialize"; - return nullptr; -} + ~MediaFoundationSession() { + // The public documentation stating that it needs to have a corresponding + // shutdown for all startups (even failed ones) is wrong. + if (has_media_foundation_) + MFShutdown(); + } + + bool has_media_foundation() const { return has_media_foundation_; } + + private: + friend struct base::DefaultSingletonTraits<MediaFoundationSession>; + + MediaFoundationSession() { + const auto hr = MFStartup(MF_VERSION, MFSTARTUP_LITE); + has_media_foundation_ = hr == S_OK; + + LOG_IF(ERROR, !has_media_foundation_) + << "Failed to start Media Foundation, accelerated media functionality " + "may be disabled. If you're using Windows N, see " + "https://support.microsoft.com/en-us/topic/" + "media-feature-pack-for-windows-10-n-may-2020-ebbdf559-b84c-0fc2-" + "bd51-e23c9f6a4439 for information on how to install the Media " + "Feature Pack. Error: " + << logging::SystemErrorCodeToString(hr); + } + + bool has_media_foundation_ = false; +}; + +} // namespace + +namespace media { -MFSession::~MFSession() { - MFShutdown(); +bool InitializeMediaFoundation() { + return MediaFoundationSession::GetInstance()->has_media_foundation(); } } // namespace media diff --git a/chromium/media/base/win/mf_initializer.h b/chromium/media/base/win/mf_initializer.h index 714cf3c4501..2d48415c278 100644 --- a/chromium/media/base/win/mf_initializer.h +++ b/chromium/media/base/win/mf_initializer.h @@ -5,27 +5,13 @@ #ifndef MEDIA_BASE_WIN_MF_INITIALIZER_H_ #define MEDIA_BASE_WIN_MF_INITIALIZER_H_ -#include <mfapi.h> - -#include <memory> - #include "base/compiler_specific.h" #include "media/base/win/mf_initializer_export.h" namespace media { -// Handy-dandy wrapper struct that kills MediaFoundation on destruction. -struct MF_INITIALIZER_EXPORT MFSession { - ~MFSession(); -}; - -using MFSessionLifetime = std::unique_ptr<MFSession>; - -// Make sure that MFShutdown is called for each MFStartup that is successful. -// The public documentation stating that it needs to have a corresponding -// shutdown for all startups (even failed ones) is wrong. -MF_INITIALIZER_EXPORT MFSessionLifetime InitializeMediaFoundation() - WARN_UNUSED_RESULT; +// Must be called before any code that needs MediaFoundation. +MF_INITIALIZER_EXPORT bool InitializeMediaFoundation() WARN_UNUSED_RESULT; } // namespace media |