summaryrefslogtreecommitdiff
path: root/chromium/media/base
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-17 17:24:03 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-06-22 07:51:41 +0000
commit774f54339e5db91f785733232d3950366db65d07 (patch)
tree068e1b47bd1af94d77094ed12b604a6b83d9c22a /chromium/media/base
parentf7eaed5286974984ba5f9e3189d8f49d03e99f81 (diff)
downloadqtwebengine-chromium-774f54339e5db91f785733232d3950366db65d07.tar.gz
BASELINE: Update Chromium to 102.0.5005.57
Change-Id: I885f714bb40ee724c28f94ca6bd8dbdb39915158 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/media/base')
-rw-r--r--chromium/media/base/BUILD.gn3
-rw-r--r--chromium/media/base/android/media_codec_bridge_impl.cc16
-rw-r--r--chromium/media/base/android/media_codec_bridge_impl.h2
-rw-r--r--chromium/media/base/android/media_codec_bridge_impl_unittest.cc1
-rw-r--r--chromium/media/base/android/media_codec_util.cc17
-rw-r--r--chromium/media/base/android/media_codec_util.h3
-rw-r--r--chromium/media/base/android/media_drm_bridge.cc4
-rw-r--r--chromium/media/base/android/media_player_bridge.cc11
-rw-r--r--chromium/media/base/android/media_resource_getter.h7
-rw-r--r--chromium/media/base/android/media_service_throttler_unittest.cc1
-rw-r--r--chromium/media/base/audio_buffer_unittest.cc1
-rw-r--r--chromium/media/base/audio_bus_unittest.cc22
-rw-r--r--chromium/media/base/audio_decoder_config.cc34
-rw-r--r--chromium/media/base/audio_decoder_config.h11
-rw-r--r--chromium/media/base/audio_discard_helper.h2
-rw-r--r--chromium/media/base/audio_hash.cc11
-rw-r--r--chromium/media/base/audio_parameters.cc18
-rw-r--r--chromium/media/base/audio_parameters.h34
-rw-r--r--chromium/media/base/audio_parameters_unittest.cc8
-rw-r--r--chromium/media/base/audio_processor_controls.h40
-rw-r--r--chromium/media/base/audio_renderer_mixer_unittest.cc8
-rw-r--r--chromium/media/base/audio_shifter_unittest.cc1
-rw-r--r--chromium/media/base/audio_timestamp_helper.h7
-rw-r--r--chromium/media/base/audio_timestamp_helper_unittest.cc6
-rw-r--r--chromium/media/base/bit_reader_unittest.cc5
-rw-r--r--chromium/media/base/bitrate.cc24
-rw-r--r--chromium/media/base/bitrate.h43
-rw-r--r--chromium/media/base/bitrate_unittest.cc25
-rw-r--r--chromium/media/base/cdm_context.cc6
-rw-r--r--chromium/media/base/cdm_context.h23
-rw-r--r--chromium/media/base/channel_layout.cc15
-rw-r--r--chromium/media/base/channel_layout.h8
-rw-r--r--chromium/media/base/channel_mixer_unittest.cc16
-rw-r--r--chromium/media/base/channel_mixing_matrix_unittest.cc3
-rw-r--r--chromium/media/base/container_names.cc7
-rw-r--r--chromium/media/base/data_buffer_unittest.cc9
-rw-r--r--chromium/media/base/decoder.cc8
-rw-r--r--chromium/media/base/decoder.h17
-rw-r--r--chromium/media/base/decoder_buffer.cc27
-rw-r--r--chromium/media/base/decoder_buffer.h3
-rw-r--r--chromium/media/base/decoder_buffer_unittest.cc19
-rw-r--r--chromium/media/base/decoder_status.cc1
-rw-r--r--chromium/media/base/decoder_status.h1
-rw-r--r--chromium/media/base/demuxer_stream.cc15
-rw-r--r--chromium/media/base/demuxer_stream.h18
-rw-r--r--chromium/media/base/fake_audio_render_callback.h1
-rw-r--r--chromium/media/base/fake_demuxer_stream.cc8
-rw-r--r--chromium/media/base/fake_demuxer_stream.h1
-rw-r--r--chromium/media/base/fake_demuxer_stream_unittest.cc32
-rw-r--r--chromium/media/base/fake_single_thread_task_runner.h1
-rw-r--r--chromium/media/base/feedback_signal_accumulator_unittest.cc1
-rw-r--r--chromium/media/base/key_system_properties.h2
-rw-r--r--chromium/media/base/key_systems.cc27
-rw-r--r--chromium/media/base/key_systems.h3
-rw-r--r--chromium/media/base/key_systems_unittest.cc45
-rw-r--r--chromium/media/base/media_client.h5
-rw-r--r--chromium/media/base/media_log_events.cc31
-rw-r--r--chromium/media/base/media_log_events.h10
-rw-r--r--chromium/media/base/media_log_properties.h1
-rw-r--r--chromium/media/base/media_serializers.h10
-rw-r--r--chromium/media/base/media_switches.cc124
-rw-r--r--chromium/media/base/media_switches.h40
-rw-r--r--chromium/media/base/mime_util_unittest.cc9
-rw-r--r--chromium/media/base/mock_filters.cc7
-rw-r--r--chromium/media/base/mock_filters.h13
-rw-r--r--chromium/media/base/null_video_sink.h1
-rw-r--r--chromium/media/base/null_video_sink_unittest.cc1
-rw-r--r--chromium/media/base/offloading_audio_encoder_unittest.cc1
-rw-r--r--chromium/media/base/pipeline_impl.h1
-rw-r--r--chromium/media/base/pipeline_impl_unittest.cc1
-rw-r--r--chromium/media/base/renderer_factory_selector.h6
-rw-r--r--chromium/media/base/seekable_buffer_unittest.cc3
-rw-r--r--chromium/media/base/status.h86
-rw-r--r--chromium/media/base/status.md63
-rw-r--r--chromium/media/base/status_unittest.cc67
-rw-r--r--chromium/media/base/stream_parser.cc1
-rw-r--r--chromium/media/base/stream_parser.h2
-rw-r--r--chromium/media/base/supported_types.cc68
-rw-r--r--chromium/media/base/supported_types.h7
-rw-r--r--chromium/media/base/supported_types_unittest.cc20
-rw-r--r--chromium/media/base/test_data_util.cc5
-rw-r--r--chromium/media/base/text_renderer_unittest.cc1
-rw-r--r--chromium/media/base/time_delta_interpolator_unittest.cc3
-rw-r--r--chromium/media/base/tuneable.cc1
-rw-r--r--chromium/media/base/unaligned_shared_memory_unittest.cc5
-rw-r--r--chromium/media/base/video_bitrate_allocation.cc72
-rw-r--r--chromium/media/base/video_bitrate_allocation.h29
-rw-r--r--chromium/media/base/video_bitrate_allocation_unittest.cc130
-rw-r--r--chromium/media/base/video_frame.cc25
-rw-r--r--chromium/media/base/video_frame.h4
-rw-r--r--chromium/media/base/video_frame_layout.cc5
-rw-r--r--chromium/media/base/video_frame_metadata.cc1
-rw-r--r--chromium/media/base/video_frame_metadata.h4
-rw-r--r--chromium/media/base/video_frame_pool.cc1
-rw-r--r--chromium/media/base/video_frame_unittest.cc16
-rw-r--r--chromium/media/base/video_transformation.cc21
-rw-r--r--chromium/media/base/video_transformation_unittest.cc92
-rw-r--r--chromium/media/base/video_types.cc25
-rw-r--r--chromium/media/base/video_types.h11
-rw-r--r--chromium/media/base/video_util.cc55
-rw-r--r--chromium/media/base/video_util.h5
-rw-r--r--chromium/media/base/video_util_unittest.cc54
-rw-r--r--chromium/media/base/wall_clock_time_source_unittest.cc1
-rw-r--r--chromium/media/base/win/dcomp_texture_wrapper.h4
-rw-r--r--chromium/media/base/win/hresult_status_helper.cc27
-rw-r--r--chromium/media/base/win/media_foundation_cdm_proxy.h6
106 files changed, 1324 insertions, 539 deletions
diff --git a/chromium/media/base/BUILD.gn b/chromium/media/base/BUILD.gn
index 4ebdb112b14..619c3bf1995 100644
--- a/chromium/media/base/BUILD.gn
+++ b/chromium/media/base/BUILD.gn
@@ -73,6 +73,7 @@ source_set("base") {
"audio_power_monitor.h",
"audio_processing.cc",
"audio_processing.h",
+ "audio_processor_controls.h",
"audio_pull_fifo.cc",
"audio_pull_fifo.h",
"audio_push_fifo.cc",
@@ -573,6 +574,7 @@ source_set("unit_tests") {
"audio_shifter_unittest.cc",
"audio_timestamp_helper_unittest.cc",
"bit_reader_unittest.cc",
+ "bitrate_unittest.cc",
"callback_holder_unittest.cc",
"callback_registry_unittest.cc",
"channel_mixer_unittest.cc",
@@ -627,6 +629,7 @@ source_set("unit_tests") {
"video_frame_pool_unittest.cc",
"video_frame_unittest.cc",
"video_thumbnail_decoder_unittest.cc",
+ "video_transformation_unittest.cc",
"video_types_unittest.cc",
"video_util_unittest.cc",
"wall_clock_time_source_unittest.cc",
diff --git a/chromium/media/base/android/media_codec_bridge_impl.cc b/chromium/media/base/android/media_codec_bridge_impl.cc
index be63bd3653f..aac199d9b32 100644
--- a/chromium/media/base/android/media_codec_bridge_impl.cc
+++ b/chromium/media/base/android/media_codec_bridge_impl.cc
@@ -183,8 +183,9 @@ std::unique_ptr<MediaCodecBridge> MediaCodecBridgeImpl::CreateAudioDecoder(
DVLOG(2) << __func__ << ": " << config.AsHumanReadableString()
<< " media_crypto:" << media_crypto.obj();
- const std::string mime =
- MediaCodecUtil::CodecToAndroidMimeType(config.codec());
+ const std::string mime = MediaCodecUtil::CodecToAndroidMimeType(
+ config.codec(), config.target_output_sample_format());
+
if (mime.empty())
return nullptr;
@@ -280,12 +281,6 @@ std::unique_ptr<MediaCodecBridge> MediaCodecBridgeImpl::CreateVideoEncoder(
// static
void MediaCodecBridgeImpl::SetupCallbackHandlerForTesting() {
- // Callback APIs are only available on M+, so do nothing if below that.
- if (base::android::BuildInfo::GetInstance()->sdk_int() <
- base::android::SDK_VERSION_MARSHMALLOW) {
- return;
- }
-
JNIEnv* env = AttachCurrentThread();
Java_MediaCodecBridge_createCallbackHandlerForTesting(env);
}
@@ -304,9 +299,6 @@ MediaCodecBridgeImpl::MediaCodecBridgeImpl(
if (!on_buffers_available_cb_)
return;
- DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(),
- base::android::SDK_VERSION_MARSHMALLOW);
-
// Note this should be done last since setBuffersAvailableListener() may
// immediately invoke the callback if buffers came in during construction.
Java_MediaCodecBridge_setBuffersAvailableListener(
@@ -673,8 +665,6 @@ std::string MediaCodecBridgeImpl::GetName() {
}
bool MediaCodecBridgeImpl::SetSurface(const JavaRef<jobject>& surface) {
- DCHECK_GE(base::android::BuildInfo::GetInstance()->sdk_int(),
- base::android::SDK_VERSION_MARSHMALLOW);
JNIEnv* env = AttachCurrentThread();
return Java_MediaCodecBridge_setSurface(env, j_bridge_, surface);
}
diff --git a/chromium/media/base/android/media_codec_bridge_impl.h b/chromium/media/base/android/media_codec_bridge_impl.h
index c0874748d0d..5e64ddd20ff 100644
--- a/chromium/media/base/android/media_codec_bridge_impl.h
+++ b/chromium/media/base/android/media_codec_bridge_impl.h
@@ -62,8 +62,6 @@ class MEDIA_EXPORT VideoCodecConfig {
// Enables the async MediaCodec.Callback API. |on_buffers_available_cb|
// will be called when input or output buffers are available. This will be
// called on an arbitrary thread, so use BindToCurrentLoop if needed.
- //
- // May only be used on API level 23 and higher.
base::RepeatingClosure on_buffers_available_cb;
};
diff --git a/chromium/media/base/android/media_codec_bridge_impl_unittest.cc b/chromium/media/base/android/media_codec_bridge_impl_unittest.cc
index 322eb3d5cbe..d1010650e7e 100644
--- a/chromium/media/base/android/media_codec_bridge_impl_unittest.cc
+++ b/chromium/media/base/android/media_codec_bridge_impl_unittest.cc
@@ -11,6 +11,7 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/time/time.h"
#include "media/base/android/media_codec_bridge_impl.h"
#include "media/base/android/media_codec_util.h"
#include "media/base/decoder_buffer.h"
diff --git a/chromium/media/base/android/media_codec_util.cc b/chromium/media/base/android/media_codec_util.cc
index 34bcdbd310a..3b53e0125d9 100644
--- a/chromium/media/base/android/media_codec_util.cc
+++ b/chromium/media/base/android/media_codec_util.cc
@@ -118,7 +118,20 @@ static bool HasVp9Profile23Decoder() {
// static
std::string MediaCodecUtil::CodecToAndroidMimeType(AudioCodec codec) {
- if (IsPassthroughAudioFormat(codec))
+ return CodecToAndroidMimeType(codec, kUnknownSampleFormat);
+}
+
+// static
+std::string MediaCodecUtil::CodecToAndroidMimeType(AudioCodec codec,
+ SampleFormat sample_format) {
+ // Passthrough is possible for some bitstream formats.
+ const bool is_passthrough = sample_format == kSampleFormatDts ||
+ sample_format == kSampleFormatDtsxP2 ||
+ sample_format == kSampleFormatAc3 ||
+ sample_format == kSampleFormatEac3 ||
+ sample_format == kSampleFormatMpegHAudio;
+
+ if (IsPassthroughAudioFormat(codec) || is_passthrough)
return kBitstreamAudioMimeType;
switch (codec) {
@@ -278,8 +291,6 @@ bool MediaCodecUtil::IsPassthroughAudioFormat(AudioCodec codec) {
switch (codec) {
case AudioCodec::kAC3:
case AudioCodec::kEAC3:
- case AudioCodec::kDTS:
- case AudioCodec::kDTSXP2:
case AudioCodec::kMpegHAudio:
return true;
default:
diff --git a/chromium/media/base/android/media_codec_util.h b/chromium/media/base/android/media_codec_util.h
index 2825a7c8e54..1933e9c174b 100644
--- a/chromium/media/base/android/media_codec_util.h
+++ b/chromium/media/base/android/media_codec_util.h
@@ -14,6 +14,7 @@
#include "media/base/android/media_codec_direction.h"
#include "media/base/audio_codecs.h"
#include "media/base/media_export.h"
+#include "media/base/sample_format.h"
#include "media/base/video_codecs.h"
namespace media {
@@ -26,6 +27,8 @@ namespace media {
class MEDIA_EXPORT MediaCodecUtil {
public:
static std::string CodecToAndroidMimeType(AudioCodec codec);
+ static std::string CodecToAndroidMimeType(AudioCodec codec,
+ SampleFormat sample_format);
static std::string CodecToAndroidMimeType(VideoCodec codec);
// Returns true if MediaCodec supports CBCS Encryption.
diff --git a/chromium/media/base/android/media_drm_bridge.cc b/chromium/media/base/android/media_drm_bridge.cc
index 6bc445c0515..0c38fc73c66 100644
--- a/chromium/media/base/android/media_drm_bridge.cc
+++ b/chromium/media/base/android/media_drm_bridge.cc
@@ -6,6 +6,7 @@
#include <stddef.h>
#include <sys/system_properties.h>
+
#include <algorithm>
#include <memory>
#include <utility>
@@ -15,7 +16,6 @@
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
#include "base/feature_list.h"
#include "base/location.h"
#include "base/logging.h"
@@ -181,7 +181,7 @@ class KeySystemManager {
KeySystemManager::KeySystemManager() {
// Widevine is always supported in Android.
key_system_uuid_map_[kWidevineKeySystem] =
- UUID(kWidevineUuid, kWidevineUuid + base::size(kWidevineUuid));
+ UUID(kWidevineUuid, kWidevineUuid + std::size(kWidevineUuid));
MediaDrmBridgeClient* client = GetMediaDrmBridgeClient();
if (client)
client->AddKeySystemUUIDMappings(&key_system_uuid_map_);
diff --git a/chromium/media/base/android/media_player_bridge.cc b/chromium/media/base/android/media_player_bridge.cc
index 723837a9350..6a7eacdd39e 100644
--- a/chromium/media/base/android/media_player_bridge.cc
+++ b/chromium/media/base/android/media_player_bridge.cc
@@ -121,7 +121,7 @@ MediaPlayerBridge::~MediaPlayerBridge() {
void MediaPlayerBridge::Initialize() {
cookies_.clear();
- if (url_.SchemeIsBlob()) {
+ if (url_.SchemeIsBlob() || url_.SchemeIsFileSystem()) {
NOTREACHED();
return;
}
@@ -182,20 +182,13 @@ void MediaPlayerBridge::SetPlaybackRate(double playback_rate) {
void MediaPlayerBridge::Prepare() {
DCHECK(j_media_player_bridge_.is_null());
- if (url_.SchemeIsBlob()) {
+ if (url_.SchemeIsBlob() || url_.SchemeIsFileSystem()) {
NOTREACHED();
return;
}
CreateJavaMediaPlayerBridge();
- if (url_.SchemeIsFileSystem()) {
- client_->GetMediaResourceGetter()->GetPlatformPathFromURL(
- url_, base::BindOnce(&MediaPlayerBridge::SetDataSource,
- weak_factory_.GetWeakPtr()));
- return;
- }
-
SetDataSource(url_.spec());
}
diff --git a/chromium/media/base/android/media_resource_getter.h b/chromium/media/base/android/media_resource_getter.h
index 714e5f1d05d..b0b822261fa 100644
--- a/chromium/media/base/android/media_resource_getter.h
+++ b/chromium/media/base/android/media_resource_getter.h
@@ -31,9 +31,6 @@ class MEDIA_EXPORT MediaResourceGetter {
// Callback to get the cookies. Args: cookies string.
typedef base::OnceCallback<void(const std::string&)> GetCookieCB;
- // Callback to get the platform path. Args: platform path.
- typedef base::OnceCallback<void(const std::string&)> GetPlatformPathCB;
-
// Callback to get the auth credentials. Args: username and password.
typedef base::OnceCallback<void(const std::u16string&, const std::u16string&)>
GetAuthCredentialsCB;
@@ -53,10 +50,6 @@ class MEDIA_EXPORT MediaResourceGetter {
const net::SiteForCookies& site_for_cookies,
const url::Origin& top_frame_origin,
GetCookieCB callback) = 0;
-
- // Method for getting the platform path from a file system URL.
- virtual void GetPlatformPathFromURL(const GURL& url,
- GetPlatformPathCB callback) = 0;
};
} // namespace media
diff --git a/chromium/media/base/android/media_service_throttler_unittest.cc b/chromium/media/base/android/media_service_throttler_unittest.cc
index 0e3928f0bfd..7b12f8aef9b 100644
--- a/chromium/media/base/android/media_service_throttler_unittest.cc
+++ b/chromium/media/base/android/media_service_throttler_unittest.cc
@@ -8,6 +8,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
+#include "base/time/time.h"
#include "media/base/android/media_server_crash_listener.h"
#include "media/base/fake_single_thread_task_runner.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chromium/media/base/audio_buffer_unittest.cc b/chromium/media/base/audio_buffer_unittest.cc
index 7a11dcf12c5..e20fff84008 100644
--- a/chromium/media/base/audio_buffer_unittest.cc
+++ b/chromium/media/base/audio_buffer_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
#include "base/test/gtest_util.h"
+#include "base/time/time.h"
#include "media/base/audio_buffer.h"
#include "media/base/audio_bus.h"
#include "media/base/test_helpers.h"
diff --git a/chromium/media/base/audio_bus_unittest.cc b/chromium/media/base/audio_bus_unittest.cc
index 7b2f328582b..753b407d92f 100644
--- a/chromium/media/base/audio_bus_unittest.cc
+++ b/chromium/media/base/audio_bus_unittest.cc
@@ -2,19 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "media/base/audio_bus.h"
+
#include <stddef.h>
#include <stdint.h>
#include <limits>
#include <memory>
-#include "base/cxx17_backports.h"
#include "base/memory/aligned_memory.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/time/time.h"
#include "build/build_config.h"
-#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
#include "media/base/audio_sample_types.h"
#include "media/base/channel_layout.h"
@@ -333,7 +333,7 @@ static const int kTestVectorFrameCount = kTestVectorSize / 2;
static const float kTestVectorResult[][kTestVectorFrameCount] = {
{-1.0f, 1.0f, 0.5f, 0.0f, 0.0f},
{0.0f, -1.0f, -0.5f, 1.0f, 0.0f}};
-static const int kTestVectorChannelCount = base::size(kTestVectorResult);
+static const int kTestVectorChannelCount = std::size(kTestVectorResult);
// Verify FromInterleaved() deinterleaves audio in supported formats correctly.
TEST_F(AudioBusTest, FromInterleaved) {
@@ -424,26 +424,26 @@ TEST_F(AudioBusTest, ToInterleaved) {
{
SCOPED_TRACE("UnsignedInt8SampleTypeTraits");
- uint8_t test_array[base::size(kTestVectorUint8)];
+ uint8_t test_array[std::size(kTestVectorUint8)];
bus->ToInterleaved<UnsignedInt8SampleTypeTraits>(bus->frames(), test_array);
ASSERT_EQ(0,
memcmp(test_array, kTestVectorUint8, sizeof(kTestVectorUint8)));
}
{
SCOPED_TRACE("SignedInt16SampleTypeTraits");
- int16_t test_array[base::size(kTestVectorInt16)];
+ int16_t test_array[std::size(kTestVectorInt16)];
bus->ToInterleaved<SignedInt16SampleTypeTraits>(bus->frames(), test_array);
ASSERT_EQ(0,
memcmp(test_array, kTestVectorInt16, sizeof(kTestVectorInt16)));
}
{
SCOPED_TRACE("SignedInt32SampleTypeTraits");
- int32_t test_array[base::size(kTestVectorInt32)];
+ int32_t test_array[std::size(kTestVectorInt32)];
bus->ToInterleaved<SignedInt32SampleTypeTraits>(bus->frames(), test_array);
// Some compilers get better precision than others on the half-max test, so
// let the test pass with an off by one check on the half-max.
- int32_t alternative_acceptable_result[base::size(kTestVectorInt32)];
+ int32_t alternative_acceptable_result[std::size(kTestVectorInt32)];
memcpy(alternative_acceptable_result, kTestVectorInt32,
sizeof(kTestVectorInt32));
ASSERT_EQ(alternative_acceptable_result[4],
@@ -457,7 +457,7 @@ TEST_F(AudioBusTest, ToInterleaved) {
}
{
SCOPED_TRACE("Float32SampleTypeTraits");
- float test_array[base::size(kTestVectorFloat32)];
+ float test_array[std::size(kTestVectorFloat32)];
bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array);
ASSERT_EQ(
0, memcmp(test_array, kTestVectorFloat32, sizeof(kTestVectorFloat32)));
@@ -471,9 +471,9 @@ TEST_F(AudioBusTest, ToInterleavedSanitized) {
bus->frames());
// Verify FromInterleaved applied no sanity.
ASSERT_EQ(bus->channel(0)[0], kTestVectorFloat32Invalid[0]);
- float test_array[base::size(kTestVectorFloat32Sanitized)];
+ float test_array[std::size(kTestVectorFloat32Sanitized)];
bus->ToInterleaved<Float32SampleTypeTraits>(bus->frames(), test_array);
- for (size_t i = 0; i < base::size(kTestVectorFloat32Sanitized); ++i)
+ for (size_t i = 0; i < std::size(kTestVectorFloat32Sanitized); ++i)
ASSERT_EQ(kTestVectorFloat32Sanitized[i], test_array[i]);
// Verify that Float32SampleTypeTraitsNoClip applied no sanity. Note: We don't
@@ -531,7 +531,7 @@ TEST_F(AudioBusTest, ToInterleavedPartial) {
{
SCOPED_TRACE("Float32SampleTypeTraits");
- float test_array[base::size(kTestVectorFloat32)];
+ float test_array[std::size(kTestVectorFloat32)];
expected->ToInterleavedPartial<Float32SampleTypeTraits>(
kPartialStart, kPartialFrames, test_array);
ASSERT_EQ(0, memcmp(test_array, kTestVectorFloat32 +
diff --git a/chromium/media/base/audio_decoder_config.cc b/chromium/media/base/audio_decoder_config.cc
index 5bbd6f7a73c..1285f096f83 100644
--- a/chromium/media/base/audio_decoder_config.cc
+++ b/chromium/media/base/audio_decoder_config.cc
@@ -65,21 +65,23 @@ bool AudioDecoderConfig::IsValidConfig() const {
}
bool AudioDecoderConfig::Matches(const AudioDecoderConfig& config) const {
- return ((codec() == config.codec()) &&
- (bytes_per_channel() == config.bytes_per_channel()) &&
- (channel_layout() == config.channel_layout()) &&
- (samples_per_second() == config.samples_per_second()) &&
- (extra_data() == config.extra_data()) &&
- (encryption_scheme() == config.encryption_scheme()) &&
- (sample_format() == config.sample_format()) &&
- (seek_preroll() == config.seek_preroll()) &&
- (codec_delay() == config.codec_delay()) &&
- (profile() == config.profile()) &&
- (should_discard_decoder_delay() ==
- config.should_discard_decoder_delay()) &&
- (target_output_channel_layout() ==
- config.target_output_channel_layout()) &&
- (aac_extra_data() == config.aac_extra_data()));
+ return (
+ (codec() == config.codec()) &&
+ (bytes_per_channel() == config.bytes_per_channel()) &&
+ (channel_layout() == config.channel_layout()) &&
+ (samples_per_second() == config.samples_per_second()) &&
+ (extra_data() == config.extra_data()) &&
+ (encryption_scheme() == config.encryption_scheme()) &&
+ (sample_format() == config.sample_format()) &&
+ (seek_preroll() == config.seek_preroll()) &&
+ (codec_delay() == config.codec_delay()) &&
+ (profile() == config.profile()) &&
+ (should_discard_decoder_delay() ==
+ config.should_discard_decoder_delay()) &&
+ (target_output_channel_layout() ==
+ config.target_output_channel_layout()) &&
+ (target_output_sample_format() == config.target_output_sample_format()) &&
+ (aac_extra_data() == config.aac_extra_data()));
}
std::string AudioDecoderConfig::AsHumanReadableString() const {
@@ -100,6 +102,8 @@ std::string AudioDecoderConfig::AsHumanReadableString() const {
<< (should_discard_decoder_delay() ? "true" : "false")
<< ", target_output_channel_layout: "
<< ChannelLayoutToString(target_output_channel_layout())
+ << ", target_output_sample_format: "
+ << SampleFormatToString(target_output_sample_format())
<< ", has aac extra data: "
<< (aac_extra_data().empty() ? "false" : "true");
return s.str();
diff --git a/chromium/media/base/audio_decoder_config.h b/chromium/media/base/audio_decoder_config.h
index 6e1077dca89..63379a2c1e1 100644
--- a/chromium/media/base/audio_decoder_config.h
+++ b/chromium/media/base/audio_decoder_config.h
@@ -115,6 +115,14 @@ class MEDIA_EXPORT AudioDecoderConfig {
return target_output_channel_layout_;
}
+ // Optionally set by renderer to signal desired bitstream-passthru format.
+ void set_target_output_sample_format(SampleFormat sample_format) {
+ target_output_sample_format_ = sample_format;
+ }
+ SampleFormat target_output_sample_format() const {
+ return target_output_sample_format_;
+ }
+
void set_aac_extra_data(std::vector<uint8_t> aac_extra_data) {
aac_extra_data_ = std::move(aac_extra_data);
}
@@ -152,6 +160,9 @@ class MEDIA_EXPORT AudioDecoderConfig {
// Layout of the output hardware. Optionally set. See setter comments.
ChannelLayout target_output_channel_layout_ = CHANNEL_LAYOUT_NONE;
+ // Desired output format of bitstream. Optionally set. See setter comments.
+ SampleFormat target_output_sample_format_ = kUnknownSampleFormat;
+
// This is a hack for backward compatibility. For AAC, to preserve existing
// behavior, we set `aac_extra_data_` on all platforms but only set
// `extra_data` on Android.
diff --git a/chromium/media/base/audio_discard_helper.h b/chromium/media/base/audio_discard_helper.h
index 50ed4bff504..20e8d54ec81 100644
--- a/chromium/media/base/audio_discard_helper.h
+++ b/chromium/media/base/audio_discard_helper.h
@@ -73,6 +73,8 @@ class MEDIA_EXPORT AudioDiscardHelper {
return timestamp_helper_.base_timestamp() != kNoTimestamp;
}
+ size_t decoder_delay() const { return decoder_delay_; }
+
private:
// The sample rate of the decoded audio samples. Used by TimeDeltaToFrames()
// and the timestamp helper.
diff --git a/chromium/media/base/audio_hash.cc b/chromium/media/base/audio_hash.cc
index bf2c7baf0cd..236d92d8920 100644
--- a/chromium/media/base/audio_hash.cc
+++ b/chromium/media/base/audio_hash.cc
@@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "media/base/audio_hash.h"
+
#include <cmath>
#include <sstream>
-#include "media/base/audio_hash.h"
-
-#include "base/cxx17_backports.h"
#include "base/numerics/math_constants.h"
#include "base/strings/stringprintf.h"
#include "media/base/audio_bus.h"
@@ -29,7 +28,7 @@ void AudioHash::Update(const AudioBus* audio_bus, int frames) {
for (uint32_t i = 0; i < static_cast<uint32_t>(frames); ++i) {
const uint32_t kSampleIndex = sample_count_ + i;
const uint32_t kHashIndex =
- (kSampleIndex * (ch + 1)) % base::size(audio_hash_);
+ (kSampleIndex * (ch + 1)) % std::size(audio_hash_);
// Mix in a sine wave with the result so we ensure that sequences of empty
// buffers don't result in an empty hash.
@@ -48,7 +47,7 @@ void AudioHash::Update(const AudioBus* audio_bus, int frames) {
std::string AudioHash::ToString() const {
std::string result;
- for (size_t i = 0; i < base::size(audio_hash_); ++i)
+ for (size_t i = 0; i < std::size(audio_hash_); ++i)
result += base::StringPrintf("%.2f,", audio_hash_[i]);
return result;
}
@@ -58,7 +57,7 @@ bool AudioHash::IsEquivalent(const std::string& other, double tolerance) const {
char comma;
std::stringstream is(other);
- for (size_t i = 0; i < base::size(audio_hash_); ++i) {
+ for (size_t i = 0; i < std::size(audio_hash_); ++i) {
is >> other_hash >> comma;
if (std::fabs(audio_hash_[i] - other_hash) > tolerance)
return false;
diff --git a/chromium/media/base/audio_parameters.cc b/chromium/media/base/audio_parameters.cc
index 401d8034b67..ded8e403c9b 100644
--- a/chromium/media/base/audio_parameters.cc
+++ b/chromium/media/base/audio_parameters.cc
@@ -6,10 +6,22 @@
#include <sstream>
+#include "media/base/audio_bus.h"
#include "media/base/limits.h"
namespace media {
+static_assert(AudioBus::kChannelAlignment == kParametersAlignment,
+ "Audio buffer parameters struct alignment not same as AudioBus");
+static_assert(sizeof(AudioInputBufferParameters) %
+ AudioBus::kChannelAlignment ==
+ 0,
+ "AudioInputBufferParameters not aligned");
+static_assert(sizeof(AudioOutputBufferParameters) %
+ AudioBus::kChannelAlignment ==
+ 0,
+ "AudioOutputBufferParameters not aligned");
+
const char* FormatToString(AudioParameters::Format format) {
switch (format) {
case AudioParameters::AUDIO_PCM_LINEAR:
@@ -134,6 +146,7 @@ bool AudioParameters::IsValid() const {
(hardware_capabilities_->max_frames_per_buffer >=
hardware_capabilities_->min_frames_per_buffer))) &&
(channel_layout_ == CHANNEL_LAYOUT_DISCRETE ||
+ channel_layout_ == CHANNEL_LAYOUT_5_1_4_DOWNMIX ||
channels_ == ChannelLayoutToChannelCount(channel_layout_));
}
@@ -194,6 +207,11 @@ bool AudioParameters::IsBitstreamFormat() const {
}
}
+bool AudioParameters::IsFormatSupportedByHardware(Format format) const {
+ return hardware_capabilities_.has_value() &&
+ (hardware_capabilities_->bitstream_formats & format);
+}
+
// static
AudioParameters AudioParameters::UnavailableDeviceParams() {
// Using 10 ms buffer since WebAudioMediaStreamSource::DeliverRebufferedAudio
diff --git a/chromium/media/base/audio_parameters.h b/chromium/media/base/audio_parameters.h
index 17643d804c8..4293aeeb1c7 100644
--- a/chromium/media/base/audio_parameters.h
+++ b/chromium/media/base/audio_parameters.h
@@ -13,7 +13,6 @@
#include "base/numerics/checked_math.h"
#include "base/time/time.h"
#include "build/build_config.h"
-#include "media/base/audio_bus.h"
#include "media/base/audio_latency.h"
#include "media/base/audio_point.h"
#include "media/base/channel_layout.h"
@@ -27,19 +26,18 @@ namespace media {
// size as sizeof(Audio{Input,Output}BufferParameters) + #(bytes in audio
// buffer) without using packing. Also align Audio{Input,Output}BufferParameters
// instead of in Audio{Input,Output}Buffer to be able to calculate size like so.
-// Use a macro for the alignment value that's the same as
+// Use a constexpr for the alignment value that's the same as
// AudioBus::kChannelAlignment, since MSVC doesn't accept the latter to be used.
#if BUILDFLAG(IS_WIN)
#pragma warning(push)
#pragma warning(disable : 4324) // Disable warning for added padding.
#endif
-#define PARAMETERS_ALIGNMENT 16
-static_assert(AudioBus::kChannelAlignment == PARAMETERS_ALIGNMENT,
- "Audio buffer parameters struct alignment not same as AudioBus");
+constexpr int kParametersAlignment = 16;
+
// ****WARNING****: Do not change the field types or ordering of these fields
// without checking that alignment is correct. The structs may be concurrently
// accessed by both 32bit and 64bit process in shmem. http://crbug.com/781095.
-struct MEDIA_SHMEM_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT)
+struct MEDIA_SHMEM_EXPORT ALIGNAS(kParametersAlignment)
AudioInputBufferParameters {
double volume;
int64_t capture_time_us; // base::TimeTicks in microseconds.
@@ -47,7 +45,7 @@ struct MEDIA_SHMEM_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT)
uint32_t id;
bool key_pressed;
};
-struct MEDIA_SHMEM_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT)
+struct MEDIA_SHMEM_EXPORT ALIGNAS(kParametersAlignment)
AudioOutputBufferParameters {
int64_t delay_us; // base::TimeDelta in microseconds.
int64_t delay_timestamp_us; // base::TimeTicks in microseconds.
@@ -55,20 +53,10 @@ struct MEDIA_SHMEM_EXPORT ALIGNAS(PARAMETERS_ALIGNMENT)
uint32_t bitstream_data_size;
uint32_t bitstream_frames;
};
-#undef PARAMETERS_ALIGNMENT
#if BUILDFLAG(IS_WIN)
#pragma warning(pop)
#endif
-static_assert(sizeof(AudioInputBufferParameters) %
- AudioBus::kChannelAlignment ==
- 0,
- "AudioInputBufferParameters not aligned");
-static_assert(sizeof(AudioOutputBufferParameters) %
- AudioBus::kChannelAlignment ==
- 0,
- "AudioOutputBufferParameters not aligned");
-
struct MEDIA_SHMEM_EXPORT AudioInputBuffer {
AudioInputBufferParameters params;
int8_t audio[1];
@@ -94,6 +82,8 @@ struct MEDIA_SHMEM_EXPORT AudioRendererAlgorithmParameters {
base::TimeDelta starting_capacity_for_encrypted;
};
+class AudioParameters;
+
// These convenience function safely computes the size required for
// |shared_memory_count| AudioInputBuffers, with enough memory for AudioBus
// data, using |paremeters| (or alternatively |channels| and |frames|). The
@@ -124,8 +114,6 @@ MEDIA_SHMEM_EXPORT uint32_t ComputeAudioOutputBufferSize(int channels,
class MEDIA_SHMEM_EXPORT AudioParameters {
public:
- // TODO(miu): Rename this enum to something that correctly reflects its
- // semantics, such as "TransportScheme."
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: AudioEncodingFormat
// GENERATED_JAVA_PREFIX_TO_STRIP: AUDIO_
@@ -170,6 +158,9 @@ class MEDIA_SHMEM_EXPORT AudioParameters {
// experimentally be enabled.
MULTIZONE = 1 << 7,
AUDIO_PREFETCH = 1 << 8,
+ ALLOW_DSP_ECHO_CANCELLER = 1 << 9,
+ ALLOW_DSP_NOISE_SUPPRESSION = 1 << 10,
+ ALLOW_DSP_AUTOMATIC_GAIN_CONTROL = 1 << 11,
};
struct HardwareCapabilities {
@@ -177,7 +168,7 @@ class MEDIA_SHMEM_EXPORT AudioParameters {
: min_frames_per_buffer(min_frames_per_buffer),
max_frames_per_buffer(max_frames_per_buffer),
bitstream_formats(0) {}
- HardwareCapabilities(int bitstream_formats)
+ explicit HardwareCapabilities(int bitstream_formats)
: min_frames_per_buffer(0),
max_frames_per_buffer(0),
bitstream_formats(bitstream_formats) {}
@@ -246,6 +237,8 @@ class MEDIA_SHMEM_EXPORT AudioParameters {
// Return true if |format_| is compressed bitstream.
bool IsBitstreamFormat() const;
+ bool IsFormatSupportedByHardware(Format format) const;
+
void set_format(Format format) { format_ = format; }
Format format() const { return format_; }
@@ -256,6 +249,7 @@ class MEDIA_SHMEM_EXPORT AudioParameters {
// this explicitly is only required with CHANNEL_LAYOUT_DISCRETE.
void set_channels_for_discrete(int channels) {
DCHECK(channel_layout_ == CHANNEL_LAYOUT_DISCRETE ||
+ channel_layout_ == CHANNEL_LAYOUT_5_1_4_DOWNMIX ||
channels == ChannelLayoutToChannelCount(channel_layout_));
channels_ = channels;
}
diff --git a/chromium/media/base/audio_parameters_unittest.cc b/chromium/media/base/audio_parameters_unittest.cc
index 28bac4e0002..021f044991e 100644
--- a/chromium/media/base/audio_parameters_unittest.cc
+++ b/chromium/media/base/audio_parameters_unittest.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "media/base/audio_parameters.h"
+
#include <stddef.h>
-#include "base/cxx17_backports.h"
#include "base/strings/string_number_conversions.h"
-#include "media/base/audio_parameters.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
@@ -107,8 +107,8 @@ TEST(AudioParameters, Compare) {
CHANNEL_LAYOUT_STEREO, 2000, 200),
};
- for (size_t i = 0; i < base::size(values); ++i) {
- for (size_t j = 0; j < base::size(values); ++j) {
+ for (size_t i = 0; i < std::size(values); ++i) {
+ for (size_t j = 0; j < std::size(values); ++j) {
SCOPED_TRACE("i=" + base::NumberToString(i) +
" j=" + base::NumberToString(j));
EXPECT_EQ(i < j, values[i] < values[j]);
diff --git a/chromium/media/base/audio_processor_controls.h b/chromium/media/base/audio_processor_controls.h
new file mode 100644
index 00000000000..b429f8035a6
--- /dev/null
+++ b/chromium/media/base/audio_processor_controls.h
@@ -0,0 +1,40 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_BASE_AUDIO_PROCESSOR_CONTROLS_H_
+#define MEDIA_BASE_AUDIO_PROCESSOR_CONTROLS_H_
+
+#include "base/callback.h"
+#include "media/base/media_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace media {
+
+// Audio processing metrics that are reported by the audio service.
+struct MEDIA_EXPORT AudioProcessingStats {
+ absl::optional<double> echo_return_loss;
+ absl::optional<double> echo_return_loss_enhancement;
+};
+
+// Interactions with the audio service.
+class MEDIA_EXPORT AudioProcessorControls {
+ public:
+ using GetStatsCB =
+ base::OnceCallback<void(const media::AudioProcessingStats& stats)>;
+
+ // Request the latest stats from the audio processor. Stats are returned
+ // asynchronously through |callback|.
+ virtual void GetStats(GetStatsCB callback) = 0;
+
+ // Set preferred number of microphone channels.
+ virtual void SetPreferredNumCaptureChannels(
+ int32_t num_preferred_channels) = 0;
+
+ protected:
+ virtual ~AudioProcessorControls() = default;
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_AUDIO_PROCESSOR_CONTROLS_H_
diff --git a/chromium/media/base/audio_renderer_mixer_unittest.cc b/chromium/media/base/audio_renderer_mixer_unittest.cc
index 3151b3153d6..d094586e7ab 100644
--- a/chromium/media/base/audio_renderer_mixer_unittest.cc
+++ b/chromium/media/base/audio_renderer_mixer_unittest.cc
@@ -14,11 +14,11 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
#include "base/memory/raw_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/task_environment.h"
#include "base/threading/platform_thread.h"
+#include "base/time/time.h"
#include "media/base/audio_renderer_mixer_input.h"
#include "media/base/audio_renderer_mixer_pool.h"
#include "media/base/fake_audio_render_callback.h"
@@ -536,19 +536,19 @@ INSTANTIATE_TEST_SUITE_P(
// Downsampling, multuple input sample rates.
std::make_tuple(static_cast<const int* const>(kTestInput3Rates),
- base::size(kTestInput3Rates),
+ std::size(kTestInput3Rates),
kTestInput3Rates[0],
0.01),
// Upsampling, multiple sinput sample rates.
std::make_tuple(static_cast<const int* const>(kTestInput3Rates),
- base::size(kTestInput3Rates),
+ std::size(kTestInput3Rates),
kTestInput3Rates[2],
0.01),
// Both downsampling and upsampling, multiple input sample rates
std::make_tuple(static_cast<const int* const>(kTestInput3Rates),
- base::size(kTestInput3Rates),
+ std::size(kTestInput3Rates),
kTestInput3Rates[1],
0.01)));
diff --git a/chromium/media/base/audio_shifter_unittest.cc b/chromium/media/base/audio_shifter_unittest.cc
index 206048ac445..4d99ceac4f7 100644
--- a/chromium/media/base/audio_shifter_unittest.cc
+++ b/chromium/media/base/audio_shifter_unittest.cc
@@ -8,6 +8,7 @@
#include <memory>
#include <vector>
+#include "base/time/time.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_shifter.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/media/base/audio_timestamp_helper.h b/chromium/media/base/audio_timestamp_helper.h
index 8ec5be76604..116826d800e 100644
--- a/chromium/media/base/audio_timestamp_helper.h
+++ b/chromium/media/base/audio_timestamp_helper.h
@@ -59,10 +59,9 @@ class MEDIA_EXPORT AudioTimestampHelper {
// and the number of sample frames that have been added so far.
base::TimeDelta GetTimestamp() const;
- // Gets the duration if |frame_count| frames were added to the current
- // timestamp reported by GetTimestamp(). This method ensures that
- // (GetTimestamp() + GetFrameDuration(n)) will equal the timestamp that
- // GetTimestamp() will return if AddFrames(n) is called.
+ // Gets the duration of |frame_count| frames by calculating the difference
+ // between the current timestamp and what the timestamp would be if
+ // |frame_count| frames were added.
base::TimeDelta GetFrameDuration(int frame_count) const;
// Returns the number of frames needed to reach the target timestamp.
diff --git a/chromium/media/base/audio_timestamp_helper_unittest.cc b/chromium/media/base/audio_timestamp_helper_unittest.cc
index af4144cebc9..2beb9414f11 100644
--- a/chromium/media/base/audio_timestamp_helper_unittest.cc
+++ b/chromium/media/base/audio_timestamp_helper_unittest.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "media/base/audio_timestamp_helper.h"
+
#include <stddef.h>
#include <stdint.h>
-#include "base/cxx17_backports.h"
-#include "media/base/audio_timestamp_helper.h"
#include "media/base/timestamp_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -132,7 +132,7 @@ TEST_F(AudioTimestampHelperTest, GetDuration) {
int frame_count = 5;
int64_t expected_durations[] = {113, 113, 114, 113, 113, 114};
- for (size_t i = 0; i < base::size(expected_durations); ++i) {
+ for (size_t i = 0; i < std::size(expected_durations); ++i) {
base::TimeDelta duration = helper_.GetFrameDuration(frame_count);
EXPECT_EQ(expected_durations[i], duration.InMicroseconds());
diff --git a/chromium/media/base/bit_reader_unittest.cc b/chromium/media/base/bit_reader_unittest.cc
index ee04e3603d5..e8ba51c12f7 100644
--- a/chromium/media/base/bit_reader_unittest.cc
+++ b/chromium/media/base/bit_reader_unittest.cc
@@ -7,7 +7,6 @@
#include <stddef.h>
#include <stdint.h>
-#include "base/cxx17_backports.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
@@ -97,7 +96,7 @@ TEST(BitReaderTest, VariableSkipBitsTest) {
// Set bits to one only for the first and last bit of each read
// in the pattern.
size_t pos = 0;
- for (size_t k = 0; k < base::size(pattern_read_skip); ++k) {
+ for (size_t k = 0; k < std::size(pattern_read_skip); ++k) {
const size_t read_bit_count = pattern_read_skip[k][0];
if (read_bit_count > 0) {
SetBit(buffer, sizeof(buffer), pos);
@@ -110,7 +109,7 @@ TEST(BitReaderTest, VariableSkipBitsTest) {
// Run the test.
BitReader bit_reader(buffer, sizeof(buffer));
EXPECT_EQ(bit_reader.bits_available(), static_cast<int>(sizeof(buffer) * 8));
- for (size_t k = 0; k < base::size(pattern_read_skip); ++k) {
+ for (size_t k = 0; k < std::size(pattern_read_skip); ++k) {
const size_t read_bit_count = pattern_read_skip[k][0];
if (read_bit_count > 0) {
int value;
diff --git a/chromium/media/base/bitrate.cc b/chromium/media/base/bitrate.cc
index bc904dfe388..b265cc90d1e 100644
--- a/chromium/media/base/bitrate.cc
+++ b/chromium/media/base/bitrate.cc
@@ -9,33 +9,33 @@
namespace media {
// static
-Bitrate Bitrate::VariableBitrate(uint32_t target_bitrate,
- uint32_t peak_bitrate) {
- DCHECK_GE(peak_bitrate, target_bitrate);
- return Bitrate(Mode::kVariable, target_bitrate, peak_bitrate);
+Bitrate Bitrate::VariableBitrate(uint32_t target_bps, uint32_t peak_bps) {
+ DCHECK_GE(peak_bps, target_bps);
+ return Bitrate(Mode::kVariable, target_bps, peak_bps);
}
bool Bitrate::operator==(const Bitrate& right) const {
- return (this->mode_ == right.mode_) && (this->target_ == right.target_) &&
- (this->peak_ == right.peak_);
+ return (this->mode_ == right.mode_) &&
+ (this->target_bps_ == right.target_bps_) &&
+ (this->peak_bps_ == right.peak_bps_);
}
bool Bitrate::operator!=(const Bitrate& right) const {
return !(*this == right);
}
-uint32_t Bitrate::peak() const {
- DCHECK_EQ(mode_ == Mode::kConstant, peak_ == 0u);
- return peak_;
+uint32_t Bitrate::peak_bps() const {
+ DCHECK_EQ(mode_ == Mode::kConstant, peak_bps_ == 0u);
+ return peak_bps_;
}
std::string Bitrate::ToString() const {
switch (mode_) {
case Mode::kConstant:
- return base::StringPrintf("CBR: %d bps", target_);
+ return base::StringPrintf("CBR: %d bps", target_bps_);
case Mode::kVariable:
- return base::StringPrintf("VBR: target %d bps, peak %d bps", target_,
- peak_);
+ return base::StringPrintf("VBR: target %d bps, peak %d bps", target_bps_,
+ peak_bps_);
}
}
diff --git a/chromium/media/base/bitrate.h b/chromium/media/base/bitrate.h
index 1d189621908..f72692b5b8f 100644
--- a/chromium/media/base/bitrate.h
+++ b/chromium/media/base/bitrate.h
@@ -30,28 +30,25 @@ class MEDIA_EXPORT Bitrate {
// or 64-bit value you want to use as input, you must explicitly convert to
// uint32_t before calling. This is intended to prevent implicit and unsafe
// type conversion.
- static constexpr Bitrate ConstantBitrate(uint32_t target_bitrate) {
- return Bitrate(Mode::kConstant, target_bitrate, 0);
+ static constexpr Bitrate ConstantBitrate(uint32_t target_bps) {
+ return Bitrate(Mode::kConstant, target_bps, 0);
}
- static Bitrate VariableBitrate(uint32_t target_bitrate,
- uint32_t peak_bitrate);
+ static Bitrate VariableBitrate(uint32_t target_bps, uint32_t peak_bps);
// Deleted variants: you must SAFELY convert to uint32_t before calling.
// See base/numerics/safe_conversions.h for functions to safely convert
// between types.
- static Bitrate ConstantBitrate(int target_bitrate) = delete;
- static Bitrate VariableBitrate(int target_bitrate, int peak_bitrate) = delete;
- static Bitrate VariableBitrate(int target_bitrate,
- uint32_t peak_bitrate) = delete;
- static Bitrate VariableBitrate(uint32_t target_bitrate,
- int peak_bitrate) = delete;
- static Bitrate ConstantBitrate(uint64_t target_bitrate) = delete;
- static Bitrate VariableBitrate(uint64_t target_bitrate,
- uint64_t peak_bitrate) = delete;
- static Bitrate VariableBitrate(uint64_t target_bitrate,
- uint32_t peak_bitrate) = delete;
- static Bitrate VariableBitrate(uint32_t target_bitrate,
- uint64_t peak_bitrate) = delete;
+ static Bitrate ConstantBitrate(int target_bps) = delete;
+ static Bitrate VariableBitrate(int target_bps, int peak_bps) = delete;
+ static Bitrate VariableBitrate(int target_bps, uint32_t peak_bps) = delete;
+ static Bitrate VariableBitrate(uint32_t target_bps, int peak_bps) = delete;
+ static Bitrate ConstantBitrate(uint64_t target_bps) = delete;
+ static Bitrate VariableBitrate(uint64_t target_bps,
+ uint64_t peak_bps) = delete;
+ static Bitrate VariableBitrate(uint64_t target_bps,
+ uint32_t peak_bps) = delete;
+ static Bitrate VariableBitrate(uint32_t target_bps,
+ uint64_t peak_bps) = delete;
bool operator==(const Bitrate& right) const;
bool operator!=(const Bitrate& right) const;
@@ -60,17 +57,17 @@ class MEDIA_EXPORT Bitrate {
constexpr Mode mode() const { return mode_; }
// Accessor for |target_|.
- constexpr uint32_t target() const { return target_; }
+ constexpr uint32_t target_bps() const { return target_bps_; }
// Accessor for |peak_|. Returns 0 if |mode_| is
// Mode::kConstantBitrate.
- uint32_t peak() const;
+ uint32_t peak_bps() const;
std::string ToString() const;
private:
- constexpr Bitrate(Mode mode, uint32_t target_bitrate, uint32_t peak_bitrate)
- : mode_(mode), target_(target_bitrate), peak_(peak_bitrate) {}
+ constexpr Bitrate(Mode mode, uint32_t target_bps, uint32_t peak_bps)
+ : mode_(mode), target_bps_(target_bps), peak_bps_(peak_bps) {}
// These member variables cannot be const (despite the intent that we do not
// change them after creation) because we must have an assignment operator for
@@ -81,10 +78,10 @@ class MEDIA_EXPORT Bitrate {
Mode mode_ = Mode::kConstant;
// Target bitrate for the stream in bits per second.
- uint32_t target_ = 0u;
+ uint32_t target_bps_ = 0u;
// For use with Mode::kVariable. Peak bitrate in bits per second.
- uint32_t peak_ = 0u;
+ uint32_t peak_bps_ = 0u;
};
} // namespace media
diff --git a/chromium/media/base/bitrate_unittest.cc b/chromium/media/base/bitrate_unittest.cc
new file mode 100644
index 00000000000..0e385b2c3b7
--- /dev/null
+++ b/chromium/media/base/bitrate_unittest.cc
@@ -0,0 +1,25 @@
+// Copyright 2022 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/bitrate.h"
+
+#include <string>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+TEST(BitrateTest, ConstantBitrate_ToString) {
+ Bitrate bitrate = Bitrate::ConstantBitrate(1234u);
+
+ EXPECT_EQ("CBR: 1234 bps", bitrate.ToString());
+}
+
+TEST(BitrateTest, VariableBitrate_ToString) {
+ Bitrate bitrate = Bitrate::VariableBitrate(0u, 123456u);
+
+ EXPECT_EQ("VBR: target 0 bps, peak 123456 bps", bitrate.ToString());
+}
+
+} // namespace media
diff --git a/chromium/media/base/cdm_context.cc b/chromium/media/base/cdm_context.cc
index 3742b25f881..0a3ee1a1414 100644
--- a/chromium/media/base/cdm_context.cc
+++ b/chromium/media/base/cdm_context.cc
@@ -35,9 +35,9 @@ bool CdmContext::RequiresMediaFoundationRenderer() {
return false;
}
-bool CdmContext::GetMediaFoundationCdmProxy(
- GetMediaFoundationCdmProxyCB get_mf_cdm_proxy_cb) {
- return false;
+scoped_refptr<MediaFoundationCdmProxy>
+CdmContext::GetMediaFoundationCdmProxy() {
+ return nullptr;
}
#endif
diff --git a/chromium/media/base/cdm_context.h b/chromium/media/base/cdm_context.h
index c48d2a47d0e..2e206d2c022 100644
--- a/chromium/media/base/cdm_context.h
+++ b/chromium/media/base/cdm_context.h
@@ -13,6 +13,10 @@
#include "media/media_buildflags.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
+#if BUILDFLAG(IS_WIN)
+#include "media/base/win/media_foundation_cdm_proxy.h"
+#endif
+
#if BUILDFLAG(IS_CHROMEOS)
namespace chromeos {
class ChromeOsCdmContext;
@@ -29,10 +33,6 @@ class MediaCryptoContext;
class FuchsiaCdmContext;
#endif
-#if BUILDFLAG(IS_WIN)
-class MediaFoundationCdmProxy;
-#endif
-
// An interface representing the context that a media player needs from a
// content decryption module (CDM) to decrypt (and decode) encrypted buffers.
// Typically this will be passed to the media player (e.g. using SetCdm()).
@@ -101,17 +101,10 @@ class MEDIA_EXPORT CdmContext {
// a sync call called in the render process to setup the media pipeline.
virtual bool RequiresMediaFoundationRenderer();
- using GetMediaFoundationCdmProxyCB =
- base::OnceCallback<void(scoped_refptr<MediaFoundationCdmProxy>)>;
- // This allows a CdmContext to expose an IMFTrustedInput instance for use in
- // a Media Foundation rendering pipeline. This method is asynchronous because
- // the underlying MF-based CDM might not have a native session created yet.
- // When the return value is true, the callback might also not be invoked
- // if the application has never caused the MF-based CDM to create its
- // native session.
- // NOTE: the callback should always be fired asynchronously.
- virtual bool GetMediaFoundationCdmProxy(
- GetMediaFoundationCdmProxyCB get_mf_cdm_proxy_cb);
+ // Returns a MediaFoundationCdmProxy to expose an IMFTrustedInput instance for
+ // use in a Media Foundation rendering pipeline. Returns nullptr if the CDM is
+ // in an invalid state or if MediaFoundationCdmProxy is not available.
+ virtual scoped_refptr<MediaFoundationCdmProxy> GetMediaFoundationCdmProxy();
#endif
#if BUILDFLAG(IS_ANDROID)
diff --git a/chromium/media/base/channel_layout.cc b/chromium/media/base/channel_layout.cc
index 07546f3ae32..b1be4cb5162 100644
--- a/chromium/media/base/channel_layout.cc
+++ b/chromium/media/base/channel_layout.cc
@@ -7,7 +7,6 @@
#include <stddef.h>
#include "base/check_op.h"
-#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/notreached.h"
@@ -47,6 +46,7 @@ static const int kLayoutToChannels[] = {
3, // CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC, deprecated
5, // CHANNEL_LAYOUT_4_1_QUAD_SIDE
0, // CHANNEL_LAYOUT_BITSTREAM
+ 6, // CHANNEL_LAYOUT_5_1_4 (downmixed to 5.1)
};
// The channel orderings for each layout as specified by FFmpeg. Each value
@@ -162,10 +162,13 @@ static const int kChannelOrderings[CHANNEL_LAYOUT_MAX + 1][CHANNELS_MAX + 1] = {
{ -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 },
// FL | FR | FC | LFE | BL | BR | FLofC | FRofC | BC | SL | SR
+
+ // CHANNEL_LAYOUT_5_1_4, downmixed to six channels (5.1)
+ { 0 , 1 , 2 , 3 , -1 , -1 , -1 , -1 , -1 , 4 , 5 },
};
int ChannelLayoutToChannelCount(ChannelLayout layout) {
- DCHECK_LT(static_cast<size_t>(layout), base::size(kLayoutToChannels));
+ DCHECK_LT(static_cast<size_t>(layout), std::size(kLayoutToChannels));
DCHECK_LE(kLayoutToChannels[layout], kMaxConcurrentChannels);
return kLayoutToChannels[layout];
}
@@ -189,6 +192,8 @@ ChannelLayout GuessChannelLayout(int channels) {
return CHANNEL_LAYOUT_6_1;
case 8:
return CHANNEL_LAYOUT_7_1;
+ case 10:
+ return CHANNEL_LAYOUT_5_1_4_DOWNMIX;
default:
DVLOG(1) << "Unsupported channel count: " << channels;
}
@@ -196,8 +201,8 @@ ChannelLayout GuessChannelLayout(int channels) {
}
int ChannelOrder(ChannelLayout layout, Channels channel) {
- DCHECK_LT(static_cast<size_t>(layout), base::size(kChannelOrderings));
- DCHECK_LT(static_cast<size_t>(channel), base::size(kChannelOrderings[0]));
+ DCHECK_LT(static_cast<size_t>(layout), std::size(kChannelOrderings));
+ DCHECK_LT(static_cast<size_t>(channel), std::size(kChannelOrderings[0]));
return kChannelOrderings[layout][channel];
}
@@ -269,6 +274,8 @@ const char* ChannelLayoutToString(ChannelLayout layout) {
return "4.1_QUAD_SIDE";
case CHANNEL_LAYOUT_BITSTREAM:
return "BITSTREAM";
+ case CHANNEL_LAYOUT_5_1_4_DOWNMIX:
+ return "5.1.4 DOWNMIX";
}
NOTREACHED() << "Invalid channel layout provided: " << layout;
return "";
diff --git a/chromium/media/base/channel_layout.h b/chromium/media/base/channel_layout.h
index c208eb6f4f9..2bf24ef8b1f 100644
--- a/chromium/media/base/channel_layout.h
+++ b/chromium/media/base/channel_layout.h
@@ -114,8 +114,14 @@ enum ChannelLayout {
// pass-through mode).
CHANNEL_LAYOUT_BITSTREAM = 32,
+ // Front L, Front R, Front C, LFE, Side L, Side R,
+ // Front Height L, Front Height R, Rear Height L, Rear Height R
+ // Will be represented as six channels (5.1) due to eight channel limit
+ // kMaxConcurrentChannels
+ CHANNEL_LAYOUT_5_1_4_DOWNMIX = 33,
+
// Max value, must always equal the largest entry ever logged.
- CHANNEL_LAYOUT_MAX = CHANNEL_LAYOUT_BITSTREAM
+ CHANNEL_LAYOUT_MAX = CHANNEL_LAYOUT_5_1_4_DOWNMIX
};
// Note: Do not reorder or reassign these values; other code depends on their
diff --git a/chromium/media/base/channel_mixer_unittest.cc b/chromium/media/base/channel_mixer_unittest.cc
index f89cc7954c3..56facff6325 100644
--- a/chromium/media/base/channel_mixer_unittest.cc
+++ b/chromium/media/base/channel_mixer_unittest.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "media/base/channel_mixer.h"
+
#include <memory>
-#include "base/cxx17_backports.h"
#include "base/strings/stringprintf.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"
-#include "media/base/channel_mixer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
@@ -166,35 +166,35 @@ INSTANTIATE_TEST_SUITE_P(
testing::Values(ChannelMixerTestData(CHANNEL_LAYOUT_STEREO,
CHANNEL_LAYOUT_MONO,
kStereoToMonoValues,
- base::size(kStereoToMonoValues),
+ std::size(kStereoToMonoValues),
0.5f),
ChannelMixerTestData(CHANNEL_LAYOUT_MONO,
CHANNEL_LAYOUT_STEREO,
kMonoToStereoValues,
- base::size(kMonoToStereoValues),
+ std::size(kMonoToStereoValues),
1.0f),
ChannelMixerTestData(CHANNEL_LAYOUT_5_1,
CHANNEL_LAYOUT_MONO,
kFiveOneToMonoValues,
- base::size(kFiveOneToMonoValues),
+ std::size(kFiveOneToMonoValues),
ChannelMixer::kHalfPower),
ChannelMixerTestData(CHANNEL_LAYOUT_DISCRETE,
2,
CHANNEL_LAYOUT_DISCRETE,
2,
kStereoToMonoValues,
- base::size(kStereoToMonoValues)),
+ std::size(kStereoToMonoValues)),
ChannelMixerTestData(CHANNEL_LAYOUT_DISCRETE,
2,
CHANNEL_LAYOUT_DISCRETE,
5,
kStereoToMonoValues,
- base::size(kStereoToMonoValues)),
+ std::size(kStereoToMonoValues)),
ChannelMixerTestData(CHANNEL_LAYOUT_DISCRETE,
5,
CHANNEL_LAYOUT_DISCRETE,
2,
kFiveDiscreteValues,
- base::size(kFiveDiscreteValues))));
+ std::size(kFiveDiscreteValues))));
} // namespace media
diff --git a/chromium/media/base/channel_mixing_matrix_unittest.cc b/chromium/media/base/channel_mixing_matrix_unittest.cc
index 7da150e258d..3bee28210a7 100644
--- a/chromium/media/base/channel_mixing_matrix_unittest.cc
+++ b/chromium/media/base/channel_mixing_matrix_unittest.cc
@@ -6,7 +6,6 @@
#include <stddef.h>
-#include "base/cxx17_backports.h"
#include "base/strings/stringprintf.h"
#include "media/base/channel_mixer.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -161,7 +160,7 @@ TEST(ChannelMixingMatrixTest, DiscreteToDiscrete) {
{2, 2}, {2, 5}, {5, 2},
};
- for (size_t n = 0; n < base::size(test_case); n++) {
+ for (size_t n = 0; n < std::size(test_case); n++) {
int input_channels = test_case[n].input_channels;
int output_channels = test_case[n].output_channels;
ChannelMixingMatrix matrix_builder(CHANNEL_LAYOUT_DISCRETE,
diff --git a/chromium/media/base/container_names.cc b/chromium/media/base/container_names.cc
index 75816aaab82..08315dcdb55 100644
--- a/chromium/media/base/container_names.cc
+++ b/chromium/media/base/container_names.cc
@@ -11,7 +11,6 @@
#include <limits>
#include "base/check_op.h"
-#include "base/cxx17_backports.h"
#include "base/numerics/safe_conversions.h"
#include "media/base/bit_reader.h"
@@ -312,7 +311,7 @@ static bool CheckDts(const uint8_t* buffer, int buffer_size) {
// Verify core audio sampling frequency is an allowed value.
size_t sampling_freq_index = ReadBits(&reader, 4);
- RCHECK(sampling_freq_index < base::size(kSamplingFrequencyValid));
+ RCHECK(sampling_freq_index < std::size(kSamplingFrequencyValid));
RCHECK(kSamplingFrequencyValid[sampling_freq_index]);
// Verify transmission bit rate is valid.
@@ -326,7 +325,7 @@ static bool CheckDts(const uint8_t* buffer, int buffer_size) {
// Verify extension audio descriptor flag is an allowed value.
size_t audio_id_index = ReadBits(&reader, 3);
- RCHECK(audio_id_index < base::size(kExtAudioIdValid));
+ RCHECK(audio_id_index < std::size(kExtAudioIdValid));
RCHECK(kExtAudioIdValid[audio_id_index]);
// Skip extended coding flag and audio sync word insertion flag.
@@ -386,7 +385,7 @@ static bool CheckDV(const uint8_t* buffer, int buffer_size) {
reader.SkipBits(3);
RCHECK(ReadBits(&reader, 24) == 0xffffff);
current_sequence_number = sequence_number;
- for (size_t i = 0; i < base::size(last_block_number); ++i)
+ for (size_t i = 0; i < std::size(last_block_number); ++i)
last_block_number[i] = -1;
} else {
// Sequence number must match (this will also fail if no header seen).
diff --git a/chromium/media/base/data_buffer_unittest.cc b/chromium/media/base/data_buffer_unittest.cc
index e4f53040b00..0faaecd8b48 100644
--- a/chromium/media/base/data_buffer_unittest.cc
+++ b/chromium/media/base/data_buffer_unittest.cc
@@ -5,11 +5,12 @@
#include "media/base/data_buffer.h"
#include <stdint.h>
+
#include <memory>
#include <utility>
-#include "base/cxx17_backports.h"
#include "base/strings/string_util.h"
+#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
@@ -49,7 +50,7 @@ TEST(DataBufferTest, Constructor_ScopedArray) {
TEST(DataBufferTest, CopyFrom) {
const uint8_t kTestData[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- const int kTestDataSize = base::size(kTestData);
+ const int kTestDataSize = std::size(kTestData);
scoped_refptr<DataBuffer> buffer =
DataBuffer::CopyFrom(kTestData, kTestDataSize);
@@ -99,9 +100,9 @@ TEST(DataBufferTest, Duration) {
TEST(DataBufferTest, ReadingWriting) {
const char kData[] = "hello";
- const int kDataSize = base::size(kData);
+ const int kDataSize = std::size(kData);
const char kNewData[] = "chromium";
- const int kNewDataSize = base::size(kNewData);
+ const int kNewDataSize = std::size(kNewData);
// Create a DataBuffer.
scoped_refptr<DataBuffer> buffer(new DataBuffer(kDataSize));
diff --git a/chromium/media/base/decoder.cc b/chromium/media/base/decoder.cc
index 738c6856442..24a73f3dcb2 100644
--- a/chromium/media/base/decoder.cc
+++ b/chromium/media/base/decoder.cc
@@ -54,9 +54,6 @@ std::string GetDecoderName(VideoDecoderType type) {
return "V4L2VideoDecoder";
case VideoDecoderType::kTesting:
return "Testing or Mock Video decoder";
- default:
- NOTREACHED();
- return "VideoDecoderType created through invalid static_cast";
}
}
@@ -76,9 +73,8 @@ std::string GetDecoderName(AudioDecoderType type) {
return "AudioDecoderBroker";
case AudioDecoderType::kTesting:
return "Testing or Mock Audio decoder";
- default:
- NOTREACHED();
- return "VideoDecoderType created through invalid static_cast";
+ case AudioDecoderType::kAudioToolbox:
+ return "AudioToolbox";
}
}
diff --git a/chromium/media/base/decoder.h b/chromium/media/base/decoder.h
index b0705fe9c6c..f4370b12226 100644
--- a/chromium/media/base/decoder.h
+++ b/chromium/media/base/decoder.h
@@ -16,16 +16,17 @@ namespace media {
// List of known AudioDecoder implementations; recorded to UKM, always add new
// values to the end and do not reorder or delete values from this list.
enum class AudioDecoderType : int {
- kUnknown = 0, // Decoder name string is not recognized or n/a.
- kFFmpeg = 1, // FFmpegAudioDecoder
- kMojo = 2, // MojoAudioDecoder
- kDecrypting = 3, // DecryptingAudioDecoder
- kMediaCodec = 4, // MediaCodecAudioDecoder (Android)
- kBroker = 5, // AudioDecoderBroker
- kTesting = 6, // Never send this to UKM, for tests only.
+ kUnknown = 0, // Decoder name string is not recognized or n/a.
+ kFFmpeg = 1, // FFmpegAudioDecoder
+ kMojo = 2, // MojoAudioDecoder
+ kDecrypting = 3, // DecryptingAudioDecoder
+ kMediaCodec = 4, // MediaCodecAudioDecoder (Android)
+ kBroker = 5, // AudioDecoderBroker
+ kTesting = 6, // Never send this to UKM, for tests only.
+ kAudioToolbox = 7, // AudioToolbox (macOS)
// Keep this at the end and equal to the last entry.
- kMaxValue = kTesting,
+ kMaxValue = kAudioToolbox,
};
// List of known VideoDecoder implementations; recorded to UKM, always add new
diff --git a/chromium/media/base/decoder_buffer.cc b/chromium/media/base/decoder_buffer.cc
index 2cf6d59bb2e..4d98e2c4bd1 100644
--- a/chromium/media/base/decoder_buffer.cc
+++ b/chromium/media/base/decoder_buffer.cc
@@ -142,7 +142,8 @@ scoped_refptr<DecoderBuffer> DecoderBuffer::CreateEOSBuffer() {
return base::WrapRefCounted(new DecoderBuffer(NULL, 0, NULL, 0));
}
-bool DecoderBuffer::MatchesForTesting(const DecoderBuffer& buffer) const {
+bool DecoderBuffer::MatchesMetadataForTesting(
+ const DecoderBuffer& buffer) const {
if (end_of_stream() != buffer.end_of_stream())
return false;
@@ -152,14 +153,7 @@ bool DecoderBuffer::MatchesForTesting(const DecoderBuffer& buffer) const {
if (timestamp() != buffer.timestamp() || duration() != buffer.duration() ||
is_key_frame() != buffer.is_key_frame() ||
- discard_padding() != buffer.discard_padding() ||
- data_size() != buffer.data_size() ||
- side_data_size() != buffer.side_data_size()) {
- return false;
- }
-
- if (memcmp(data(), buffer.data(), data_size()) != 0 ||
- memcmp(side_data(), buffer.side_data(), side_data_size()) != 0) {
+ discard_padding() != buffer.discard_padding()) {
return false;
}
@@ -170,6 +164,21 @@ bool DecoderBuffer::MatchesForTesting(const DecoderBuffer& buffer) const {
: true;
}
+bool DecoderBuffer::MatchesForTesting(const DecoderBuffer& buffer) const {
+ if (!MatchesMetadataForTesting(buffer)) // IN-TEST
+ return false;
+
+ // It is illegal to call any member function if eos is true.
+ if (end_of_stream())
+ return true;
+
+ DCHECK(!buffer.end_of_stream());
+ return data_size() == buffer.data_size() &&
+ side_data_size() == buffer.side_data_size() &&
+ memcmp(data(), buffer.data(), data_size()) == 0 &&
+ memcmp(side_data(), buffer.side_data(), side_data_size()) == 0;
+}
+
std::string DecoderBuffer::AsHumanReadableString(bool verbose) const {
if (end_of_stream())
return "EOS";
diff --git a/chromium/media/base/decoder_buffer.h b/chromium/media/base/decoder_buffer.h
index 852f5943f3c..f44b8792d2b 100644
--- a/chromium/media/base/decoder_buffer.h
+++ b/chromium/media/base/decoder_buffer.h
@@ -215,6 +215,9 @@ class MEDIA_EXPORT DecoderBuffer
// including |data_| and |side_data_|.
bool MatchesForTesting(const DecoderBuffer& buffer) const;
+ // As above, except that |data_| and |side_data_| are not compared.
+ bool MatchesMetadataForTesting(const DecoderBuffer& buffer) const;
+
// Returns a human-readable string describing |*this|.
std::string AsHumanReadableString(bool verbose = false) const;
diff --git a/chromium/media/base/decoder_buffer_unittest.cc b/chromium/media/base/decoder_buffer_unittest.cc
index 2d6c257b923..2f80d5e92d8 100644
--- a/chromium/media/base/decoder_buffer_unittest.cc
+++ b/chromium/media/base/decoder_buffer_unittest.cc
@@ -9,7 +9,6 @@
#include <memory>
-#include "base/cxx17_backports.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/strings/string_util.h"
@@ -38,7 +37,7 @@ TEST(DecoderBufferTest, CreateEOSBuffer) {
TEST(DecoderBufferTest, CopyFrom) {
const uint8_t kData[] = "hello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
scoped_refptr<DecoderBuffer> buffer2(DecoderBuffer::CopyFrom(
reinterpret_cast<const uint8_t*>(&kData), kDataSize));
@@ -65,7 +64,7 @@ TEST(DecoderBufferTest, CopyFrom) {
TEST(DecoderBufferTest, FromArray) {
const uint8_t kData[] = "hello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
std::unique_ptr<uint8_t[]> ptr(new uint8_t[kDataSize]);
memcpy(ptr.get(), kData, kDataSize);
@@ -80,7 +79,7 @@ TEST(DecoderBufferTest, FromArray) {
TEST(DecoderBufferTest, FromPlatformSharedMemoryRegion) {
const uint8_t kData[] = "hello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
auto region = base::UnsafeSharedMemoryRegion::Create(kDataSize);
auto mapping = region.Map();
@@ -100,7 +99,7 @@ TEST(DecoderBufferTest, FromPlatformSharedMemoryRegion) {
TEST(DecoderBufferTest, FromPlatformSharedMemoryRegion_Unaligned) {
const uint8_t kData[] = "XXXhello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
const off_t kDataOffset = 3;
auto region = base::UnsafeSharedMemoryRegion::Create(kDataSize);
@@ -122,7 +121,7 @@ TEST(DecoderBufferTest, FromPlatformSharedMemoryRegion_Unaligned) {
TEST(DecoderBufferTest, FromPlatformSharedMemoryRegion_ZeroSize) {
const uint8_t kData[] = "hello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
auto region = base::UnsafeSharedMemoryRegion::Create(kDataSize);
auto mapping = region.Map();
@@ -138,7 +137,7 @@ TEST(DecoderBufferTest, FromPlatformSharedMemoryRegion_ZeroSize) {
TEST(DecoderBufferTest, FromSharedMemoryRegion) {
const uint8_t kData[] = "hello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
auto mapping_region = base::ReadOnlySharedMemoryRegion::Create(kDataSize);
ASSERT_TRUE(mapping_region.IsValid());
@@ -155,7 +154,7 @@ TEST(DecoderBufferTest, FromSharedMemoryRegion) {
TEST(DecoderBufferTest, FromSharedMemoryRegion_Unaligned) {
const uint8_t kData[] = "XXXhello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
const off_t kDataOffset = 3;
auto mapping_region = base::ReadOnlySharedMemoryRegion::Create(kDataSize);
@@ -175,7 +174,7 @@ TEST(DecoderBufferTest, FromSharedMemoryRegion_Unaligned) {
TEST(DecoderBufferTest, FromSharedMemoryRegion_ZeroSize) {
const uint8_t kData[] = "hello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
auto mapping_region = base::ReadOnlySharedMemoryRegion::Create(kDataSize);
memcpy(mapping_region.mapping.GetMemoryAs<uint8_t>(), kData, kDataSize);
@@ -188,7 +187,7 @@ TEST(DecoderBufferTest, FromSharedMemoryRegion_ZeroSize) {
TEST(DecoderBufferTest, ReadingWriting) {
const char kData[] = "hello";
- const size_t kDataSize = base::size(kData);
+ const size_t kDataSize = std::size(kData);
scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(kDataSize));
ASSERT_TRUE(buffer.get());
diff --git a/chromium/media/base/decoder_status.cc b/chromium/media/base/decoder_status.cc
index 9fffd5fe5ee..44d0aaf1351 100644
--- a/chromium/media/base/decoder_status.cc
+++ b/chromium/media/base/decoder_status.cc
@@ -39,6 +39,7 @@ const std::string GetDecodeStatusString(const DecoderStatus& status) {
STRINGIFY(DecoderStatus::Codes::kCantChangeCodec);
STRINGIFY(DecoderStatus::Codes::kFailedToCreateDecoder);
STRINGIFY(DecoderStatus::Codes::kKeyFrameRequired);
+ STRINGIFY(DecoderStatus::Codes::kMissingTimestamp);
}
#undef STRINGIFY
}
diff --git a/chromium/media/base/decoder_status.h b/chromium/media/base/decoder_status.h
index 209d4b20309..dd2a0c6548a 100644
--- a/chromium/media/base/decoder_status.h
+++ b/chromium/media/base/decoder_status.h
@@ -31,6 +31,7 @@ struct DecoderStatusTraits {
kDecoderStreamReinitFailed = 109,
kDecoderStreamDemuxerError = 110,
kKeyFrameRequired = 111,
+ kMissingTimestamp = 112,
// Reasons for failing to initialize
kUnsupportedProfile = 200,
diff --git a/chromium/media/base/demuxer_stream.cc b/chromium/media/base/demuxer_stream.cc
index 9fad473f2db..ccc922440e5 100644
--- a/chromium/media/base/demuxer_stream.cc
+++ b/chromium/media/base/demuxer_stream.cc
@@ -6,6 +6,17 @@
namespace media {
+std::string GetStreamLivenessName(StreamLiveness liveness) {
+ switch (liveness) {
+ case StreamLiveness::kUnknown:
+ return "unknown";
+ case StreamLiveness::kRecorded:
+ return "recorded";
+ case StreamLiveness::kLive:
+ return "live";
+ }
+}
+
// static
const char* DemuxerStream::GetTypeName(Type type) {
switch (type) {
@@ -38,8 +49,8 @@ DemuxerStream::~DemuxerStream() = default;
// Most DemuxerStream implementations don't specify liveness. Returns unknown
// liveness by default.
-DemuxerStream::Liveness DemuxerStream::liveness() const {
- return DemuxerStream::LIVENESS_UNKNOWN;
+StreamLiveness DemuxerStream::liveness() const {
+ return StreamLiveness::kUnknown;
}
// Most DemuxerStream implementations don't need to convert bit stream.
diff --git a/chromium/media/base/demuxer_stream.h b/chromium/media/base/demuxer_stream.h
index 3b10523f7fb..f866d62c0cb 100644
--- a/chromium/media/base/demuxer_stream.h
+++ b/chromium/media/base/demuxer_stream.h
@@ -16,6 +16,15 @@ class AudioDecoderConfig;
class DecoderBuffer;
class VideoDecoderConfig;
+enum class StreamLiveness {
+ kUnknown,
+ kRecorded,
+ kLive,
+ kMaxValue = kLive,
+};
+
+MEDIA_EXPORT std::string GetStreamLivenessName(StreamLiveness liveness);
+
class MEDIA_EXPORT DemuxerStream {
public:
enum Type {
@@ -29,13 +38,6 @@ class MEDIA_EXPORT DemuxerStream {
// Returns a string representation of |type|.
static const char* GetTypeName(Type type);
- enum Liveness {
- LIVENESS_UNKNOWN,
- LIVENESS_RECORDED,
- LIVENESS_LIVE,
- LIVENESS_MAX = LIVENESS_LIVE,
- };
-
// Status returned in the Read() callback.
// kOk : Indicates the second parameter is Non-NULL and contains media data
// or the end of the stream.
@@ -83,7 +85,7 @@ class MEDIA_EXPORT DemuxerStream {
virtual Type type() const = 0;
// Returns liveness of the streams provided, i.e. whether recorded or live.
- virtual Liveness liveness() const;
+ virtual StreamLiveness liveness() const;
virtual void EnableBitstreamConverter();
diff --git a/chromium/media/base/fake_audio_render_callback.h b/chromium/media/base/fake_audio_render_callback.h
index 3fe33f202e6..1f5e39bf7e0 100644
--- a/chromium/media/base/fake_audio_render_callback.h
+++ b/chromium/media/base/fake_audio_render_callback.h
@@ -7,6 +7,7 @@
#include <stdint.h>
+#include "base/time/time.h"
#include "media/base/audio_converter.h"
#include "media/base/audio_renderer_sink.h"
#include "testing/gmock/include/gmock/gmock.h"
diff --git a/chromium/media/base/fake_demuxer_stream.cc b/chromium/media/base/fake_demuxer_stream.cc
index 771795dea62..d6020caddc1 100644
--- a/chromium/media/base/fake_demuxer_stream.cc
+++ b/chromium/media/base/fake_demuxer_stream.cc
@@ -5,14 +5,13 @@
#include "media/base/fake_demuxer_stream.h"
#include <stdint.h>
-#include <memory>
+#include <memory>
#include <vector>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/check_op.h"
-#include "base/cxx17_backports.h"
#include "base/location.h"
#include "base/notreached.h"
#include "base/task/single_thread_task_runner.h"
@@ -206,9 +205,8 @@ void FakeDemuxerStream::DoRead() {
// TODO(xhwang): Output out-of-order buffers if needed.
if (is_encrypted_) {
buffer->set_decrypt_config(DecryptConfig::CreateCencConfig(
- std::string(kKeyId, kKeyId + base::size(kKeyId)),
- std::string(kIv, kIv + base::size(kIv)),
- std::vector<SubsampleEntry>()));
+ std::string(kKeyId, kKeyId + std::size(kKeyId)),
+ std::string(kIv, kIv + std::size(kIv)), std::vector<SubsampleEntry>()));
}
buffer->set_timestamp(current_timestamp_);
buffer->set_duration(duration_);
diff --git a/chromium/media/base/fake_demuxer_stream.h b/chromium/media/base/fake_demuxer_stream.h
index c0a19a31891..1a2251e0515 100644
--- a/chromium/media/base/fake_demuxer_stream.h
+++ b/chromium/media/base/fake_demuxer_stream.h
@@ -6,6 +6,7 @@
#define MEDIA_BASE_FAKE_DEMUXER_STREAM_H_
#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/demuxer_stream.h"
#include "media/base/media_resource.h"
diff --git a/chromium/media/base/fake_demuxer_stream_unittest.cc b/chromium/media/base/fake_demuxer_stream_unittest.cc
index ccfc880150c..04437210db9 100644
--- a/chromium/media/base/fake_demuxer_stream_unittest.cc
+++ b/chromium/media/base/fake_demuxer_stream_unittest.cc
@@ -326,4 +326,36 @@ TEST_F(FakeDemuxerStreamTest, SeekToStart_AfterEOS) {
ReadAllBuffers(3, 5);
}
+TEST_F(FakeDemuxerStreamTest, DemuxerStream_GetTypeName) {
+ EXPECT_TRUE(DemuxerStream::GetTypeName(DemuxerStream::Type::AUDIO) ==
+ std::string("audio"));
+ EXPECT_TRUE(DemuxerStream::GetTypeName(DemuxerStream::Type::VIDEO) ==
+ std::string("video"));
+ EXPECT_TRUE(DemuxerStream::GetTypeName(DemuxerStream::Type::TEXT) ==
+ std::string("text"));
+ EXPECT_TRUE(DemuxerStream::GetTypeName(DemuxerStream::Type::UNKNOWN) ==
+ std::string("unknown"));
+}
+
+TEST_F(FakeDemuxerStreamTest, DemuxerStream_GetStatusName) {
+ EXPECT_TRUE(DemuxerStream::GetStatusName(DemuxerStream::Status::kOk) ==
+ std::string("okay"));
+ EXPECT_TRUE(DemuxerStream::GetStatusName(DemuxerStream::Status::kAborted) ==
+ std::string("aborted"));
+ EXPECT_TRUE(
+ DemuxerStream::GetStatusName(DemuxerStream::Status::kConfigChanged) ==
+ std::string("config_changed"));
+ EXPECT_TRUE(DemuxerStream::GetStatusName(DemuxerStream::Status::kError) ==
+ std::string("error"));
+}
+
+TEST_F(FakeDemuxerStreamTest, DemuxerStream_GetLivenessName) {
+ EXPECT_TRUE(GetStreamLivenessName(StreamLiveness::kUnknown) ==
+ std::string("unknown"));
+ EXPECT_TRUE(GetStreamLivenessName(StreamLiveness::kRecorded) ==
+ std::string("recorded"));
+ EXPECT_TRUE(GetStreamLivenessName(StreamLiveness::kLive) ==
+ std::string("live"));
+}
+
} // namespace media
diff --git a/chromium/media/base/fake_single_thread_task_runner.h b/chromium/media/base/fake_single_thread_task_runner.h
index 84e302f87e3..fd61d665b0b 100644
--- a/chromium/media/base/fake_single_thread_task_runner.h
+++ b/chromium/media/base/fake_single_thread_task_runner.h
@@ -11,6 +11,7 @@
#include "base/memory/raw_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/simple_test_tick_clock.h"
+#include "base/time/time.h"
namespace media {
diff --git a/chromium/media/base/feedback_signal_accumulator_unittest.cc b/chromium/media/base/feedback_signal_accumulator_unittest.cc
index d6c11a91673..f1d09baa765 100644
--- a/chromium/media/base/feedback_signal_accumulator_unittest.cc
+++ b/chromium/media/base/feedback_signal_accumulator_unittest.cc
@@ -4,6 +4,7 @@
#include "media/base/feedback_signal_accumulator.h"
+#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
diff --git a/chromium/media/base/key_system_properties.h b/chromium/media/base/key_system_properties.h
index 6eeb8775875..f80ba87203a 100644
--- a/chromium/media/base/key_system_properties.h
+++ b/chromium/media/base/key_system_properties.h
@@ -82,7 +82,7 @@ using KeySystemPropertiesVector =
std::vector<std::unique_ptr<KeySystemProperties>>;
using GetSupportedKeySystemsCB =
- base::OnceCallback<void(KeySystemPropertiesVector)>;
+ base::RepeatingCallback<void(KeySystemPropertiesVector)>;
} // namespace media
diff --git a/chromium/media/base/key_systems.cc b/chromium/media/base/key_systems.cc
index adf33338922..744b47f7078 100644
--- a/chromium/media/base/key_systems.cc
+++ b/chromium/media/base/key_systems.cc
@@ -18,7 +18,6 @@
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_checker.h"
-#include "base/time/time.h"
#include "build/build_config.h"
#include "media/base/key_system_names.h"
#include "media/base/key_system_properties.h"
@@ -276,7 +275,6 @@ class KeySystemsImpl : public KeySystems {
// Implementation of KeySystems interface.
void UpdateIfNeeded(base::OnceClosure done_cb) override;
- bool IsUpToDate() override;
std::string GetBaseKeySystemName(
const std::string& key_system) const override;
bool IsSupportedKeySystem(const std::string& key_system) const override;
@@ -323,7 +321,6 @@ class KeySystemsImpl : public KeySystems {
KeySystemsImpl();
~KeySystemsImpl() override;
- bool IsUpdateNeeded();
void UpdateSupportedKeySystems();
void OnSupportedKeySystemsUpdated(KeySystemPropertiesVector key_systems);
void ProcessSupportedKeySystems(KeySystemPropertiesVector key_systems);
@@ -387,10 +384,6 @@ KeySystemsImpl::~KeySystemsImpl() {
update_callbacks_.Notify();
}
-bool KeySystemsImpl::IsUpdateNeeded() {
- return GetMediaClient() && GetMediaClient()->IsKeySystemsUpdateNeeded();
-}
-
void KeySystemsImpl::UpdateSupportedKeySystems() {
DCHECK(!is_updating_);
is_updating_ = true;
@@ -401,28 +394,18 @@ void KeySystemsImpl::UpdateSupportedKeySystems() {
}
GetMediaClient()->GetSupportedKeySystems(
- base::BindOnce(&KeySystemsImpl::OnSupportedKeySystemsUpdated,
- weak_factory_.GetWeakPtr()));
+ base::BindRepeating(&KeySystemsImpl::OnSupportedKeySystemsUpdated,
+ weak_factory_.GetWeakPtr()));
}
void KeySystemsImpl::UpdateIfNeeded(base::OnceClosure done_cb) {
if (is_updating_) {
+ // The callback will be resolved in OnSupportedKeySystemsUpdated().
update_callbacks_.AddUnsafe(std::move(done_cb));
return;
}
- DCHECK(update_callbacks_.empty());
- if (!IsUpdateNeeded()) {
- std::move(done_cb).Run();
- return;
- }
-
- update_callbacks_.AddUnsafe(std::move(done_cb));
- UpdateSupportedKeySystems();
-}
-
-bool KeySystemsImpl::IsUpToDate() {
- return !is_updating_ && !IsUpdateNeeded();
+ std::move(done_cb).Run();
}
SupportedCodecs KeySystemsImpl::GetCodecMaskForMimeType(
@@ -483,7 +466,6 @@ void KeySystemsImpl::OnSupportedKeySystemsUpdated(
KeySystemPropertiesVector key_systems) {
DVLOG(1) << __func__;
- DCHECK(is_updating_);
is_updating_ = false;
// Clear Key is always supported.
@@ -550,6 +532,7 @@ void KeySystemsImpl::ProcessSupportedKeySystems(
const KeySystemProperties* KeySystemsImpl::GetKeySystemProperties(
const std::string& key_system) const {
+ DCHECK(!is_updating_);
for (const auto& entry : key_system_properties_map_) {
const auto& base_key_system = entry.first;
const auto* properties = entry.second.get();
diff --git a/chromium/media/base/key_systems.h b/chromium/media/base/key_systems.h
index b13bf6d9a49..7165a179c82 100644
--- a/chromium/media/base/key_systems.h
+++ b/chromium/media/base/key_systems.h
@@ -35,9 +35,6 @@ class MEDIA_EXPORT KeySystems {
// out of date. Calls the `done_cb` when done.
virtual void UpdateIfNeeded(base::OnceClosure done_cb) = 0;
- // Whether the list of available key systems is up to date.
- virtual bool IsUpToDate() = 0;
-
// Gets the base key system name, e.g. "org.chromium.foo".
virtual std::string GetBaseKeySystemName(
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 cd4b7924d7f..7a9b977589f 100644
--- a/chromium/media/base/key_systems_unittest.cc
+++ b/chromium/media/base/key_systems_unittest.cc
@@ -247,16 +247,11 @@ class TestMediaClient : public MediaClient {
~TestMediaClient() override;
// MediaClient implementation.
- bool IsKeySystemsUpdateNeeded() final;
void GetSupportedKeySystems(GetSupportedKeySystemsCB cb) final;
bool IsSupportedAudioType(const media::AudioType& type) final;
bool IsSupportedVideoType(const media::VideoType& type) final;
bool IsSupportedBitstreamAudioCodec(AudioCodec codec) final;
- // Helper function to test the case where IsKeySystemsUpdateNeeded() is true
- // after GetSupportedKeySystems() is called.
- void SetKeySystemsUpdateNeeded();
-
// Helper function to disable "kExternal" key system support so that we can
// test the key system update case.
void DisableExternalKeySystemSupport();
@@ -265,28 +260,21 @@ class TestMediaClient : public MediaClient {
GetAudioRendererAlgorithmParameters(AudioParameters audio_parameters) final;
private:
- bool is_update_needed_ = true;
+ KeySystemPropertiesVector GetSupportedKeySystemsInternal();
+
+ GetSupportedKeySystemsCB get_supported_key_systems_cb_;
bool supports_external_key_system_ = true;
};
TestMediaClient::TestMediaClient() = default;
TestMediaClient::~TestMediaClient() = default;
-bool TestMediaClient::IsKeySystemsUpdateNeeded() {
- return is_update_needed_;
-}
-
void TestMediaClient::GetSupportedKeySystems(GetSupportedKeySystemsCB cb) {
- DCHECK(is_update_needed_);
- KeySystemPropertiesVector key_systems;
+ // Save the callback for future updates.
+ DCHECK(!get_supported_key_systems_cb_);
+ get_supported_key_systems_cb_ = cb;
- key_systems.emplace_back(new AesKeySystemProperties(kUsesAes));
-
- if (supports_external_key_system_)
- key_systems.emplace_back(new ExternalKeySystemProperties());
-
- is_update_needed_ = false;
- std::move(cb).Run(std::move(key_systems));
+ get_supported_key_systems_cb_.Run(GetSupportedKeySystemsInternal());
}
bool TestMediaClient::IsSupportedAudioType(const media::AudioType& type) {
@@ -301,12 +289,9 @@ bool TestMediaClient::IsSupportedBitstreamAudioCodec(AudioCodec codec) {
return false;
}
-void TestMediaClient::SetKeySystemsUpdateNeeded() {
- is_update_needed_ = true;
-}
-
void TestMediaClient::DisableExternalKeySystemSupport() {
supports_external_key_system_ = false;
+ get_supported_key_systems_cb_.Run(GetSupportedKeySystemsInternal());
}
absl::optional<::media::AudioRendererAlgorithmParameters>
@@ -315,6 +300,17 @@ TestMediaClient::GetAudioRendererAlgorithmParameters(
return absl::nullopt;
}
+KeySystemPropertiesVector TestMediaClient::GetSupportedKeySystemsInternal() {
+ KeySystemPropertiesVector key_systems;
+
+ key_systems.emplace_back(new AesKeySystemProperties(kUsesAes));
+
+ if (supports_external_key_system_)
+ key_systems.emplace_back(new ExternalKeySystemProperties());
+
+ return key_systems;
+}
+
} // namespace
class KeySystemsTest : public testing::Test {
@@ -365,7 +361,6 @@ class KeySystemsTest : public testing::Test {
base::RunLoop run_loop;
KeySystems::GetInstance()->UpdateIfNeeded(run_loop.QuitClosure());
run_loop.Run();
- ASSERT_TRUE(KeySystems::GetInstance()->IsUpToDate());
}
~KeySystemsTest() override {
@@ -376,13 +371,11 @@ class KeySystemsTest : public testing::Test {
}
void UpdateClientKeySystems() {
- test_media_client_.SetKeySystemsUpdateNeeded();
test_media_client_.DisableExternalKeySystemSupport();
base::RunLoop run_loop;
KeySystems::GetInstance()->UpdateIfNeeded(run_loop.QuitClosure());
run_loop.Run();
- ASSERT_TRUE(KeySystems::GetInstance()->IsUpToDate());
}
typedef std::vector<std::string> CodecVector;
diff --git a/chromium/media/base/media_client.h b/chromium/media/base/media_client.h
index 7fc3ddf6112..5e8ac795f72 100644
--- a/chromium/media/base/media_client.h
+++ b/chromium/media/base/media_client.h
@@ -43,11 +43,6 @@ class MEDIA_EXPORT MediaClient {
// Adds properties for supported key systems.
virtual void GetSupportedKeySystems(GetSupportedKeySystemsCB cb) = 0;
- // Returns whether client key systems properties should be updated.
- // TODO(xhwang): Refactor this to a proper change "observer" API that is
- // less fragile (don't assume GetSupportedKeySystems has just one caller).
- virtual bool IsKeySystemsUpdateNeeded() = 0;
-
// Returns true if the given audio config is supported.
virtual bool IsSupportedAudioType(const AudioType& type) = 0;
diff --git a/chromium/media/base/media_log_events.cc b/chromium/media/base/media_log_events.cc
index f6b3b1e97ec..c628a511c1b 100644
--- a/chromium/media/base/media_log_events.cc
+++ b/chromium/media/base/media_log_events.cc
@@ -10,37 +10,6 @@
namespace media {
-std::string MediaLogEventToString(MediaLogEvent level) {
- switch (level) {
- case MediaLogEvent::kPlay:
- return "PLAY";
- case MediaLogEvent::kPause:
- return "PAUSE";
- case MediaLogEvent::kSeek:
- return "SEEK";
- case MediaLogEvent::kPipelineStateChange:
- return "PIPELINE_STATE_CHANGED";
- case MediaLogEvent::kWebMediaPlayerCreated:
- return "WEBMEDIAPLAYER_CREATED";
- case MediaLogEvent::kWebMediaPlayerDestroyed:
- return "WEBMEDIAPLAYER_DESTROYED";
- case MediaLogEvent::kLoad:
- return "LOAD";
- case MediaLogEvent::kVideoSizeChanged:
- return "VIDEO_SIZE_SET";
- case MediaLogEvent::kDurationChanged:
- return "DURATION_SET";
- case MediaLogEvent::kEnded:
- return "ENDED";
- case MediaLogEvent::kBufferingStateChanged:
- return "BUFFERING_STATE_CHANGE";
- case MediaLogEvent::kSuspended:
- return "SUSPENDED";
- }
- NOTREACHED();
- return "";
-}
-
std::string TruncateUrlString(const std::string& url) {
if (url.length() > kMaxUrlLength) {
// Take substring and _then_ replace, to avoid copying unused data.
diff --git a/chromium/media/base/media_log_events.h b/chromium/media/base/media_log_events.h
index c61ff4676f6..ddf71e1f5a2 100644
--- a/chromium/media/base/media_log_events.h
+++ b/chromium/media/base/media_log_events.h
@@ -63,12 +63,11 @@ enum class MediaLogEvent {
// The player has been suspended to save resources.
kSuspended,
-};
-// This has to be declared before the macros use it - Some infra code relies on
-// the enum names to be UPPER_CASE, so this will convert them manually
-// instead of using macro stringification.
-MEDIA_EXPORT std::string MediaLogEventToString(MediaLogEvent level);
+ // An internal-only event that the media log sends when it is created, and
+ // includes a wall-clock timestamp.
+ kMediaLogCreated,
+};
// Sometimes URLs can have encoded data that can be exteremly large.
MEDIA_EXPORT std::string TruncateUrlString(const std::string& url);
@@ -92,6 +91,7 @@ MEDIA_LOG_EVENT_NAMED_DATA_OP(kWebMediaPlayerCreated,
std::string,
"origin_url",
TruncateUrlString);
+MEDIA_LOG_EVENT_NAMED_DATA(kMediaLogCreated, base::Time, "created");
// Each type of buffering state gets a different name.
MEDIA_LOG_EVENT_NAMED_DATA(
diff --git a/chromium/media/base/media_log_properties.h b/chromium/media/base/media_log_properties.h
index 3bca8a08869..ddd20e971d6 100644
--- a/chromium/media/base/media_log_properties.h
+++ b/chromium/media/base/media_log_properties.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/media_export.h"
#include "media/base/media_log_type_enforcement.h"
diff --git a/chromium/media/base/media_serializers.h b/chromium/media/base/media_serializers.h
index f20a307899a..401acac1114 100644
--- a/chromium/media/base/media_serializers.h
+++ b/chromium/media/base/media_serializers.h
@@ -156,6 +156,16 @@ struct MediaSerializer<base::TimeDelta> {
}
};
+// enum (simple)
+template <>
+struct MediaSerializer<base::Time> {
+ static inline base::Value Serialize(const base::Time value) {
+ std::stringstream formatted;
+ formatted << value;
+ return MediaSerializer<std::string>::Serialize(formatted.str());
+ }
+};
+
// Enum (simple)
template <>
struct MediaSerializer<RendererType> {
diff --git a/chromium/media/base/media_switches.cc b/chromium/media/base/media_switches.cc
index 71b1563c8f8..ebd93cf54a2 100644
--- a/chromium/media/base/media_switches.cc
+++ b/chromium/media/base/media_switches.cc
@@ -8,15 +8,12 @@
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/system_media_controls/linux/buildflags/buildflags.h"
+#include "media/media_buildflags.h"
#if BUILDFLAG(IS_LINUX)
#include "base/cpu.h"
#endif
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "ash/constants/ash_features.h"
-#endif
-
namespace switches {
// Allow users to specify a custom buffer size for debugging purpose.
@@ -256,10 +253,6 @@ const base::Feature kFFmpegDecodeOpaqueVP8{"FFmpegDecodeOpaqueVP8",
const base::Feature kOverlayFullscreenVideo{"overlay-fullscreen-video",
base::FEATURE_ENABLED_BY_DEFAULT};
-// TODO(crbug.com/1146594): Flip this to disabled in M92.
-const base::Feature kEnableMediaInternals{"enable-media-internals",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
// Enables user control over muting tab audio from the tab strip.
const base::Feature kEnableTabMuting{"EnableTabMuting",
base::FEATURE_DISABLED_BY_DEFAULT};
@@ -348,6 +341,27 @@ const base::Feature kCdmHostVerification{"CdmHostVerification",
const base::Feature kCdmProcessSiteIsolation{"CdmProcessSiteIsolation",
base::FEATURE_ENABLED_BY_DEFAULT};
+#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
+// If echo cancellation for a mic signal is requested, mix and cancel all audio
+// playback going to a specific output device in the audio service.
+const base::Feature kChromeWideEchoCancellation{
+ "ChromeWideEchoCancellation", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// If non-zero, audio processing is done on a dedicated processing thread which
+// receives audio from the audio capture thread via a fifo of a specified size.
+// Zero fifo size means the usage of such processing thread is disabled and
+// processing is done on the audio capture thread itself.
+const base::FeatureParam<int> kChromeWideEchoCancellationProcessingFifoSize{
+ &kChromeWideEchoCancellation, "processing_fifo_size", 0};
+
+// When audio processing is done in the audio process, at the renderer side IPC
+// is set up to receive audio at the processing sample rate. This is a
+// kill-switch to fallback to receiving audio at the default sample rate of the
+// audio capture device.
+const base::FeatureParam<bool> kChromeWideEchoCancellationMinimizeResampling{
+ &kChromeWideEchoCancellation, "minimize_resampling", true};
+#endif
+
// Make MSE garbage collection algorithm more aggressive when we are under
// moderate or critical memory pressure. This will relieve memory pressure by
// releasing stale data from MSE buffers.
@@ -575,6 +589,17 @@ const base::Feature kLiveCaption{"LiveCaption",
// tab instead" button is shown for chrome.desktopCapture captures.
const base::Feature kShareThisTabInsteadButtonGetDisplayMedia{
"ShareThisTabInsteadButtonGetDisplayMedia",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
+// If kShareThisTabInsteadButtonGetDisplayMedia is ENABLED, this flag controls
+// whether a "Share this tab instead" button should be enabled for
+// getDisplayMedia captures with audio.
+// If kShareThisTabInsteadButtonGetDisplayMedia is DISABLED, this flag has no
+// effect.
+// Note: This flag does not control if the "Share this tab instead" button is
+// shown for chrome.desktopCapture captures.
+const base::Feature kShareThisTabInsteadButtonGetDisplayMediaAudio{
+ "ShareThisTabInsteadButtonGetDisplayMediaAudio",
base::FEATURE_ENABLED_BY_DEFAULT};
// Enable the Speaker Change Detection feature, which inserts a line break when
@@ -609,6 +634,13 @@ const base::Feature kHardwareSecureDecryption{
const base::Feature kHardwareSecureDecryptionExperiment{
"HardwareSecureDecryptionExperiment", base::FEATURE_DISABLED_BY_DEFAULT};
+// Allows automatically disabling hardware secure Content Decryption Module
+// (CDM) after failures or crashes to fallback to software secure CDMs. If this
+// feature is disabled, the fallback will never happen and users could be stuck
+// in playback failures.
+const base::Feature kHardwareSecureDecryptionFallback{
+ "HardwareSecureDecryptionFallback", base::FEATURE_ENABLED_BY_DEFAULT};
+
const base::Feature kWakeLockOptimisationHiddenMuted{
"kWakeLockOptimisationHiddenMuted", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -729,6 +761,14 @@ const base::Feature kUseRealColorSpaceForAndroidVideo{
const base::Feature kUseChromeOSDirectVideoDecoder{
"UseChromeOSDirectVideoDecoder", base::FEATURE_ENABLED_BY_DEFAULT};
+#if defined(ARCH_CPU_ARM_FAMILY)
+// Some architectures have separate image processor hardware that
+// can be used by Chromium's ImageProcessor to color convert/crop/etc.
+// video buffers. Sometimes it is more efficient/performant/correct
+// to use libYUV instead of the hardware to do this processing.
+const base::Feature kPreferLibYuvImageProcessor{
+ "prefer-libyuv-image-processor", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif // defined(ARCH_CPU_ARM_FAMILY)
#if BUILDFLAG(IS_CHROMEOS)
// ChromeOS has one of two VideoDecoder implementations active based on
// SoC/board specific configurations that are sent via command line flags. This
@@ -741,11 +781,17 @@ const base::Feature kUseAlternateVideoDecoderImplementation{
#endif // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
#if BUILDFLAG(IS_MAC)
+
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
+const base::Feature kVideoToolboxHEVCDecoding{
+ "VideoToolboxHEVCDecoding", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
+
// Enable binding multiple shared images to a single GpuMemoryBuffer for
// accelerated video decode using VideoToolbox.
const base::Feature kMultiPlaneVideoToolboxSharedImages{
"MultiPlaneVideoToolboxSharedImages", base::FEATURE_ENABLED_BY_DEFAULT};
-#endif
+#endif // BUILDFLAG(IS_MAC)
#if BUILDFLAG(IS_WIN)
// Does NV12->NV12 video copy on the main thread right before the texture's
@@ -768,11 +814,19 @@ const base::Feature kIncludeIRCamerasInDeviceEnumeration{
const base::Feature MEDIA_EXPORT kMediaFoundationAV1Encoding{
"MediaFoundationAV1Encoding", base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables H.264 CBP encode acceleration for Windows.
+// For feature check of kMediaFoundationH264CbpEncoding at runtime,
+// please use IsMediaFoundationH264CbpEncodingEnabled() instead.
+const base::Feature MEDIA_EXPORT kMediaFoundationH264CbpEncoding{
+ "MediaFoundationH264CbpEncoding", base::FEATURE_DISABLED_BY_DEFAULT};
+
// Enables MediaFoundation based video capture
const base::Feature kMediaFoundationVideoCapture{
"MediaFoundationVideoCapture", base::FEATURE_ENABLED_BY_DEFAULT};
// Enables MediaFoundation based video capture with D3D11
+// For feature check of kMediaFoundationD3D11VideoCapture at runtime,
+// please use IsMediaFoundationD3D11VideoCaptureEnabled() instead.
const base::Feature kMediaFoundationD3D11VideoCapture{
"MediaFoundationD3D11VideoCapture", base::FEATURE_DISABLED_BY_DEFAULT};
@@ -809,6 +863,13 @@ const base::Feature MEDIA_EXPORT kDeprecateLowUsageCodecs{
"DeprecateLowUsageCodecs", base::FEATURE_ENABLED_BY_DEFAULT};
#endif // BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+// Spawn utility processes to perform hardware decode acceleration instead of
+// using the GPU process.
+const base::Feature MEDIA_EXPORT kUseOutOfProcessVideoDecoding{
+ "UseOutOfProcessVideoDecoding", base::FEATURE_DISABLED_BY_DEFAULT};
+#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+
std::string GetEffectiveAutoplayPolicy(const base::CommandLine& command_line) {
// Return the autoplay policy set in the command line, if any.
if (command_line.HasSwitch(switches::kAutoplayPolicy))
@@ -931,38 +992,19 @@ const base::Feature kBresenhamCadence{"BresenhamCadence",
const base::Feature kPlaybackSpeedButton{"PlaybackSpeedButton",
base::FEATURE_ENABLED_BY_DEFAULT};
+bool IsChromeWideEchoCancellationEnabled() {
+#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
+ return base::FeatureList::IsEnabled(kChromeWideEchoCancellation);
+#else
+ return false;
+#endif
+}
+
bool IsHardwareSecureDecryptionEnabled() {
return base::FeatureList::IsEnabled(kHardwareSecureDecryption) ||
base::FeatureList::IsEnabled(kHardwareSecureDecryptionExperiment);
}
-bool IsLiveCaptionFeatureEnabled() {
- if (!base::FeatureList::IsEnabled(media::kLiveCaption))
- return false;
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
- // Some Chrome OS devices do not support on-device speech.
- if (!base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition))
- return false;
-#endif
-
-#if BUILDFLAG(IS_LINUX)
- // Check if the CPU has the required instruction set to run the Speech
- // On-Device API (SODA) library.
- static bool has_sse41 = base::CPU().has_sse41();
- if (!has_sse41)
- return false;
-#endif
-
-#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_ARM64)
- // The Speech On-Device API (SODA) component does not support Windows on
- // arm64.
- return false;
-#else
- return true;
-#endif
-}
-
bool IsVideoCaptureAcceleratedJpegDecodingEnabled() {
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableAcceleratedMjpegDecode)) {
@@ -979,4 +1021,14 @@ bool IsVideoCaptureAcceleratedJpegDecodingEnabled() {
#endif
}
+#if BUILDFLAG(IS_WIN)
+bool IsMediaFoundationH264CbpEncodingEnabled() {
+ return base::FeatureList::IsEnabled(kMediaFoundationH264CbpEncoding);
+}
+
+bool IsMediaFoundationD3D11VideoCaptureEnabled() {
+ return base::FeatureList::IsEnabled(kMediaFoundationD3D11VideoCapture);
+}
+#endif
+
} // namespace media
diff --git a/chromium/media/base/media_switches.h b/chromium/media/base/media_switches.h
index 92087150b55..c6715ac3cec 100644
--- a/chromium/media/base/media_switches.h
+++ b/chromium/media/base/media_switches.h
@@ -125,8 +125,14 @@ MEDIA_EXPORT extern const base::Feature kBackgroundVideoPauseOptimization;
MEDIA_EXPORT extern const base::Feature kBresenhamCadence;
MEDIA_EXPORT extern const base::Feature kCdmHostVerification;
MEDIA_EXPORT extern const base::Feature kCdmProcessSiteIsolation;
+#if BUILDFLAG(CHROME_WIDE_ECHO_CANCELLATION)
+MEDIA_EXPORT extern const base::Feature kChromeWideEchoCancellation;
+MEDIA_EXPORT extern const base::FeatureParam<int>
+ kChromeWideEchoCancellationProcessingFifoSize;
+MEDIA_EXPORT extern const base::FeatureParam<bool>
+ kChromeWideEchoCancellationMinimizeResampling;
+#endif
MEDIA_EXPORT extern const base::Feature kD3D11VideoDecoderUseSharedHandle;
-MEDIA_EXPORT extern const base::Feature kEnableMediaInternals;
MEDIA_EXPORT extern const base::Feature kEnableTabMuting;
MEDIA_EXPORT extern const base::Feature kExposeSwDecodersToWebRTC;
MEDIA_EXPORT extern const base::Feature kExternalClearKeyForTesting;
@@ -143,6 +149,7 @@ MEDIA_EXPORT extern const base::Feature kGlobalMediaControlsModernUI;
MEDIA_EXPORT extern const base::Feature kHardwareMediaKeyHandling;
MEDIA_EXPORT extern const base::Feature kHardwareSecureDecryption;
MEDIA_EXPORT extern const base::Feature kHardwareSecureDecryptionExperiment;
+MEDIA_EXPORT extern const base::Feature kHardwareSecureDecryptionFallback;
MEDIA_EXPORT extern const base::Feature kInternalMediaSession;
MEDIA_EXPORT extern const base::Feature kKeepRvfcFrameAlive;
MEDIA_EXPORT extern const base::Feature kKeyPressMonitoring;
@@ -176,6 +183,8 @@ MEDIA_EXPORT extern const base::Feature kReuseMediaPlayer;
MEDIA_EXPORT extern const base::Feature kRevokeMediaSourceObjectURLOnAttach;
MEDIA_EXPORT extern const base::Feature
kShareThisTabInsteadButtonGetDisplayMedia;
+MEDIA_EXPORT extern const base::Feature
+ kShareThisTabInsteadButtonGetDisplayMediaAudio;
MEDIA_EXPORT extern const base::Feature kSpeakerChangeDetection;
MEDIA_EXPORT extern const base::Feature kSpecCompliantCanPlayThrough;
MEDIA_EXPORT extern const base::Feature kSurfaceLayerForMediaStreams;
@@ -227,24 +236,38 @@ MEDIA_EXPORT extern const base::Feature kUseRealColorSpaceForAndroidVideo;
#if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
MEDIA_EXPORT extern const base::Feature kUseChromeOSDirectVideoDecoder;
-
+#if defined(ARCH_CPU_ARM_FAMILY)
+MEDIA_EXPORT extern const base::Feature kPreferLibYuvImageProcessor;
+#endif // defined(ARCH_CPU_ARM_FAMILY)
#if BUILDFLAG(IS_CHROMEOS)
MEDIA_EXPORT extern const base::Feature kUseAlternateVideoDecoderImplementation;
#endif // BUILDFLAG(IS_CHROMEOS)
#endif // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
#if BUILDFLAG(IS_MAC)
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
+MEDIA_EXPORT extern const base::Feature kVideoToolboxHEVCDecoding;
+#endif // BUILDFLAG(ENABLE_PLATFORM_HEVC_DECODING)
MEDIA_EXPORT extern const base::Feature kMultiPlaneVideoToolboxSharedImages;
-#endif
+#endif // BUILDFLAG(IS_MAC)
#if BUILDFLAG(IS_WIN)
MEDIA_EXPORT extern const base::Feature kDelayCopyNV12Textures;
MEDIA_EXPORT extern const base::Feature kDirectShowGetPhotoState;
MEDIA_EXPORT extern const base::Feature kIncludeIRCamerasInDeviceEnumeration;
MEDIA_EXPORT extern const base::Feature kMediaFoundationAV1Encoding;
+
+// For feature check of kMediaFoundationH264CbpEncoding at runtime,
+// please use IsMediaFoundationH264CbpEncodingEnabled() instead.
+MEDIA_EXPORT extern const base::Feature kMediaFoundationH264CbpEncoding;
+
MEDIA_EXPORT extern const base::Feature kMediaFoundationVideoCapture;
MEDIA_EXPORT extern const base::Feature kMediaFoundationVP8Decoding;
+
+// For feature check of kMediaFoundationD3D11VideoCapture at runtime,
+// please use IsMediaFoundationD3D11VideoCaptureEnabled() instead.
MEDIA_EXPORT extern const base::Feature kMediaFoundationD3D11VideoCapture;
+
MEDIA_EXPORT extern const base::Feature kMediaFoundationClearPlayback;
MEDIA_EXPORT extern const base::Feature kWasapiRawAudioCapture;
MEDIA_EXPORT extern const base::Feature kD3D11HEVCDecoding;
@@ -255,6 +278,10 @@ MEDIA_EXPORT extern const base::Feature kD3D11Vp9kSVCHWDecoding;
MEDIA_EXPORT extern const base::Feature kDeprecateLowUsageCodecs;
#endif
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+MEDIA_EXPORT extern const base::Feature kUseOutOfProcessVideoDecoding;
+#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+
// Based on a |command_line| and the current platform, returns the effective
// autoplay policy. In other words, it will take into account the default policy
// if none is specified via the command line and options passed for testing.
@@ -263,10 +290,15 @@ MEDIA_EXPORT extern const base::Feature kDeprecateLowUsageCodecs;
MEDIA_EXPORT std::string GetEffectiveAutoplayPolicy(
const base::CommandLine& command_line);
+MEDIA_EXPORT bool IsChromeWideEchoCancellationEnabled();
MEDIA_EXPORT bool IsHardwareSecureDecryptionEnabled();
-MEDIA_EXPORT bool IsLiveCaptionFeatureEnabled();
MEDIA_EXPORT bool IsVideoCaptureAcceleratedJpegDecodingEnabled();
+#if BUILDFLAG(IS_WIN)
+MEDIA_EXPORT bool IsMediaFoundationH264CbpEncodingEnabled();
+MEDIA_EXPORT bool IsMediaFoundationD3D11VideoCaptureEnabled();
+#endif
+
enum class kCrosGlobalMediaControlsPinOptions {
kPin,
kNotPin,
diff --git a/chromium/media/base/mime_util_unittest.cc b/chromium/media/base/mime_util_unittest.cc
index 7ebc35762e0..8137fbc7d5b 100644
--- a/chromium/media/base/mime_util_unittest.cc
+++ b/chromium/media/base/mime_util_unittest.cc
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "media/base/mime_util.h"
+
#include <stddef.h>
-#include "base/cxx17_backports.h"
#include "base/strings/string_split.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_command_line.h"
@@ -12,7 +13,6 @@
#include "media/base/audio_codecs.h"
#include "media/base/media.h"
#include "media/base/media_switches.h"
-#include "media/base/mime_util.h"
#include "media/base/mime_util_internal.h"
#include "media/base/video_codecs.h"
#include "media/base/video_color_space.h"
@@ -53,8 +53,7 @@ static std::vector<bool> CreateTestVector(bool test_all_values,
bool single_value) {
const bool kTestStates[] = {true, false};
if (test_all_values)
- return std::vector<bool>(kTestStates,
- kTestStates + base::size(kTestStates));
+ return std::vector<bool>(kTestStates, kTestStates + std::size(kTestStates));
return std::vector<bool>(1, single_value);
}
@@ -212,7 +211,7 @@ TEST(MimeUtilTest, SplitAndStripCodecs) {
{",", 2, {"", ""}, {"", ""}},
};
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < std::size(tests); ++i) {
std::vector<std::string> codecs_out;
SplitCodecs(tests[i].original, &codecs_out);
diff --git a/chromium/media/base/mock_filters.cc b/chromium/media/base/mock_filters.cc
index e1658c63468..3ab836a646c 100644
--- a/chromium/media/base/mock_filters.cc
+++ b/chromium/media/base/mock_filters.cc
@@ -33,8 +33,7 @@ std::string MockDemuxer::GetDisplayName() const {
return "MockDemuxer";
}
-MockDemuxerStream::MockDemuxerStream(DemuxerStream::Type type)
- : type_(type), liveness_(LIVENESS_UNKNOWN) {}
+MockDemuxerStream::MockDemuxerStream(DemuxerStream::Type type) : type_(type) {}
MockDemuxerStream::~MockDemuxerStream() = default;
@@ -42,7 +41,7 @@ DemuxerStream::Type MockDemuxerStream::type() const {
return type_;
}
-DemuxerStream::Liveness MockDemuxerStream::liveness() const {
+StreamLiveness MockDemuxerStream::liveness() const {
return liveness_;
}
@@ -68,7 +67,7 @@ void MockDemuxerStream::set_video_decoder_config(
video_decoder_config_ = config;
}
-void MockDemuxerStream::set_liveness(DemuxerStream::Liveness liveness) {
+void MockDemuxerStream::set_liveness(StreamLiveness liveness) {
liveness_ = liveness;
}
diff --git a/chromium/media/base/mock_filters.h b/chromium/media/base/mock_filters.h
index dbc853ccced..31f3dbe4948 100644
--- a/chromium/media/base/mock_filters.h
+++ b/chromium/media/base/mock_filters.h
@@ -202,8 +202,8 @@ class MockDemuxerStream : public DemuxerStream {
// DemuxerStream implementation.
Type type() const override;
- Liveness liveness() const override;
- void Read(ReadCB read_cb) { OnRead(read_cb); }
+ StreamLiveness liveness() const override;
+ void Read(ReadCB read_cb) override { OnRead(read_cb); }
MOCK_METHOD1(OnRead, void(ReadCB& read_cb));
AudioDecoderConfig audio_decoder_config() override;
VideoDecoderConfig video_decoder_config() override;
@@ -212,11 +212,11 @@ class MockDemuxerStream : public DemuxerStream {
void set_audio_decoder_config(const AudioDecoderConfig& config);
void set_video_decoder_config(const VideoDecoderConfig& config);
- void set_liveness(Liveness liveness);
+ void set_liveness(StreamLiveness liveness);
private:
Type type_;
- Liveness liveness_;
+ StreamLiveness liveness_ = StreamLiveness::kUnknown;
AudioDecoderConfig audio_decoder_config_;
VideoDecoderConfig video_decoder_config_;
};
@@ -658,8 +658,8 @@ class MockCdmContext : public CdmContext {
#if BUILDFLAG(IS_WIN)
MOCK_METHOD0(RequiresMediaFoundationRenderer, bool());
- MOCK_METHOD1(GetMediaFoundationCdmProxy,
- bool(GetMediaFoundationCdmProxyCB get_mf_cdm_proxy_cb));
+ MOCK_METHOD0(GetMediaFoundationCdmProxy,
+ scoped_refptr<MediaFoundationCdmProxy>());
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
MOCK_METHOD0(GetChromeOsCdmContext, chromeos::ChromeOsCdmContext*());
@@ -858,7 +858,6 @@ class MockMediaClient : public media::MediaClient {
// MediaClient implementation.
MOCK_METHOD1(GetSupportedKeySystems, void(GetSupportedKeySystemsCB cb));
- MOCK_METHOD0(IsKeySystemsUpdateNeeded, bool());
MOCK_METHOD1(IsSupportedAudioType, bool(const media::AudioType& type));
MOCK_METHOD1(IsSupportedVideoType, bool(const media::VideoType& type));
MOCK_METHOD1(IsSupportedBitstreamAudioCodec, bool(media::AudioCodec codec));
diff --git a/chromium/media/base/null_video_sink.h b/chromium/media/base/null_video_sink.h
index f113e09286a..28ddf2a6043 100644
--- a/chromium/media/base/null_video_sink.h
+++ b/chromium/media/base/null_video_sink.h
@@ -9,6 +9,7 @@
#include "base/memory/raw_ptr.h"
#include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h"
+#include "base/time/time.h"
#include "media/base/media_export.h"
#include "media/base/video_renderer_sink.h"
diff --git a/chromium/media/base/null_video_sink_unittest.cc b/chromium/media/base/null_video_sink_unittest.cc
index cbb954f27ac..cc89d6fa45e 100644
--- a/chromium/media/base/null_video_sink_unittest.cc
+++ b/chromium/media/base/null_video_sink_unittest.cc
@@ -9,6 +9,7 @@
#include "base/test/gmock_callback_support.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
+#include "base/time/time.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "media/base/null_video_sink.h"
#include "media/base/test_helpers.h"
diff --git a/chromium/media/base/offloading_audio_encoder_unittest.cc b/chromium/media/base/offloading_audio_encoder_unittest.cc
index 467ce4174e7..39c2719ac85 100644
--- a/chromium/media/base/offloading_audio_encoder_unittest.cc
+++ b/chromium/media/base/offloading_audio_encoder_unittest.cc
@@ -14,6 +14,7 @@
#include "base/test/bind.h"
#include "base/test/gmock_callback_support.h"
#include "base/test/task_environment.h"
+#include "base/time/time.h"
#include "media/base/media_util.h"
#include "media/base/mock_filters.h"
#include "media/base/offloading_audio_encoder.h"
diff --git a/chromium/media/base/pipeline_impl.h b/chromium/media/base/pipeline_impl.h
index d88da084f35..6262fa9bbcc 100644
--- a/chromium/media/base/pipeline_impl.h
+++ b/chromium/media/base/pipeline_impl.h
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
+#include "base/time/time.h"
#include "media/base/media_export.h"
#include "media/base/pipeline.h"
#include "media/base/renderer.h"
diff --git a/chromium/media/base/pipeline_impl_unittest.cc b/chromium/media/base/pipeline_impl_unittest.cc
index 07c95300f21..c9f047b0cb8 100644
--- a/chromium/media/base/pipeline_impl_unittest.cc
+++ b/chromium/media/base/pipeline_impl_unittest.cc
@@ -20,6 +20,7 @@
#include "base/threading/simple_thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/clock.h"
+#include "base/time/time.h"
#include "media/base/fake_text_track_stream.h"
#include "media/base/media_util.h"
#include "media/base/mock_filters.h"
diff --git a/chromium/media/base/renderer_factory_selector.h b/chromium/media/base/renderer_factory_selector.h
index bc83cf8260c..8be6f06500e 100644
--- a/chromium/media/base/renderer_factory_selector.h
+++ b/chromium/media/base/renderer_factory_selector.h
@@ -66,7 +66,7 @@ class MEDIA_EXPORT RendererFactorySelector {
RendererFactorySelector(const RendererFactorySelector&) = delete;
RendererFactorySelector& operator=(const RendererFactorySelector&) = delete;
- ~RendererFactorySelector();
+ virtual ~RendererFactorySelector();
// See file level comments above.
void AddBaseFactory(RendererType type,
@@ -85,11 +85,11 @@ class MEDIA_EXPORT RendererFactorySelector {
// Returns the type of the Renderer for what GetCurrentFactory() would return.
// NOTE: SetBaseRendererType() must be called before calling this method.
- RendererType GetCurrentRendererType();
+ virtual RendererType GetCurrentRendererType();
// Updates |current_factory_| if necessary, and returns its value.
// NOTE: SetBaseRendererType() must be called before calling this method.
- RendererFactory* GetCurrentFactory();
+ virtual RendererFactory* GetCurrentFactory();
#if BUILDFLAG(IS_ANDROID)
// Starts a request to receive a RemotePlayStateChangeCB, to be fulfilled
diff --git a/chromium/media/base/seekable_buffer_unittest.cc b/chromium/media/base/seekable_buffer_unittest.cc
index d1df6a3ca9b..df18af5d516 100644
--- a/chromium/media/base/seekable_buffer_unittest.cc
+++ b/chromium/media/base/seekable_buffer_unittest.cc
@@ -9,7 +9,6 @@
#include <cstdlib>
-#include "base/cxx17_backports.h"
#include "base/time/time.h"
#include "media/base/data_buffer.h"
#include "media/base/timestamp_constants.h"
@@ -337,7 +336,7 @@ TEST_F(SeekableBufferTest, GetTime) {
scoped_refptr<DataBuffer> buffer = DataBuffer::CopyFrom(data_, kWriteSize);
- for (size_t i = 0; i < base::size(tests); ++i) {
+ for (size_t i = 0; i < std::size(tests); ++i) {
buffer->set_timestamp(base::Microseconds(tests[i].first_time_useconds));
buffer->set_duration(base::Microseconds(tests[i].duration_useconds));
buffer_.Append(buffer.get());
diff --git a/chromium/media/base/status.h b/chromium/media/base/status.h
index 155db110a04..abcffbc394b 100644
--- a/chromium/media/base/status.h
+++ b/chromium/media/base/status.h
@@ -50,6 +50,14 @@ using UKMPackedType = uint64_t;
namespace internal {
+template <typename T>
+struct SecondArgType {};
+
+template <typename R, typename A1, typename A2>
+struct SecondArgType<R(A1, A2)> {
+ using Type = A2;
+};
+
union UKMPackHelper {
struct bits {
uint16_t group;
@@ -224,20 +232,70 @@ class MEDIA_EXPORT TypedStatus {
using Traits = T;
using Codes = typename T::Codes;
- // default constructor to please the Mojo Gods.
- TypedStatus() = default;
+ // See media/base/status.md for the ways that an instantiation of TypedStatus
+ // can be constructed, since there are a few.
+
+ // Default constructor to please the Mojo Gods.
+ TypedStatus() : data_(nullptr) {}
+
+ // Copy constructor (also as a sacrifice to Lord Mojo)
+ TypedStatus(const TypedStatus<T>& copy) { *this = copy; }
- // For TypedStatus(OkStatus())
+ // Special constructor use by OkStatus() to implicitly be cast to any required
+ // status type.
TypedStatus(const internal::OkStatusImplicitConstructionHelper&)
: TypedStatus(Codes::kOk) {}
+ // Used to implicitly create a TypedStatus from a TypedStatus::Codes value.
+ TypedStatus(Codes code,
+ const base::Location& location = base::Location::Current())
+ : TypedStatus(code, "", location) {}
+
+ TypedStatus(std::tuple<Codes, base::StringPiece> pack,
+ const base::Location& location = base::Location::Current())
+ : TypedStatus(std::get<0>(pack), std::get<1>(pack), location) {}
+
+ // Used to allow returning {TypedStatus::Codes::kValue, CastFrom} implicitly
+ // iff TypedStatus::Traits::OnCreateFrom is implemented.
+ template <
+ typename _T = Traits,
+ typename = std::enable_if<std::is_pointer_v<decltype(&_T::OnCreateFrom)>>>
+ TypedStatus(
+ Codes code,
+ const typename internal::SecondArgType<decltype(_T::OnCreateFrom)>::Type&
+ data,
+ const base::Location& location = base::Location::Current())
+ : TypedStatus(code, "", location) {
+ // TODO(tmathmeyer) I think we can make this dcheck a static assert.
+ DCHECK(data_);
+ Traits::OnCreateFrom(this, data);
+ }
+
+ // Used to allow returning {TypedStatus::Codes::kValue, "message", CastFrom}
+ // implicitly iff TypedStatus::Traits::OnCreateFrom is implemented.
+ template <
+ typename _T = Traits,
+ typename = std::enable_if<std::is_pointer_v<decltype(&_T::OnCreateFrom)>>>
+ TypedStatus(
+ Codes code,
+ base::StringPiece message,
+ const typename internal::SecondArgType<decltype(_T::OnCreateFrom)>::Type&
+ data,
+ const base::Location& location = base::Location::Current())
+ : TypedStatus(code, message, location) {
+ DCHECK(data_);
+ Traits::OnCreateFrom(this, data);
+ }
+
// Constructor to create a new TypedStatus from a numeric code & message.
// These are immutable; if you'd like to change them, then you likely should
// create a new TypedStatus.
// NOTE: This should never be given a location parameter when called - It is
// defaulted in order to grab the caller location.
+ // Also used to allow returning {TypedStatus::Codes::kValue, "message"}
+ // implicitly as a typed status.
TypedStatus(Codes code,
- base::StringPiece message = "",
+ base::StringPiece message,
const base::Location& location = base::Location::Current()) {
// Note that |message| would be dropped when code is the default value,
// so DCHECK that it is not set.
@@ -251,8 +309,6 @@ class MEDIA_EXPORT TypedStatus {
data_->AddLocation(location);
}
- TypedStatus(const TypedStatus<T>& copy) { *this = copy; }
-
TypedStatus<T>& operator=(const TypedStatus<T>& copy) {
if (!copy.data_) {
data_.reset();
@@ -384,24 +440,38 @@ class MEDIA_EXPORT TypedStatus {
~Or() = default;
- // Implicit constructors allow returning |OtherType| or |TypedStatus|
- // directly.
+ // Create an Or type implicitly from a TypedStatus
Or(TypedStatus<T>&& error) : error_(std::move(error)) {
// `error_` must not be `kOk`, if there is such a value.
DCHECK(!error_->is_ok());
}
+
Or(const TypedStatus<T>& error) : error_(error) {
DCHECK(!error_->is_ok());
}
+ // Create an Or type implicitly from the alternate OtherType.
Or(OtherType&& value) : value_(std::move(value)) {}
Or(const OtherType& value) : value_(value) {}
+
+ // Create an Or type explicitly from a code
Or(typename T::Codes code,
const base::Location& location = base::Location::Current())
: error_(TypedStatus<T>(code, "", location)) {
DCHECK(!error_->is_ok());
}
+ // Create an Or type implicitly from any brace-initializer list that could
+ // have been used to create the typed status
+ template <typename First, typename... Rest>
+ Or(typename T::Codes code,
+ const First& first,
+ const Rest&... rest,
+ const base::Location& location = base::Location::Current())
+ : error_(TypedStatus<T>(code, first, rest..., location)) {
+ DCHECK(!error_->is_ok());
+ }
+
// Move- and copy- construction and assignment are okay.
Or(const Or&) = default;
Or(Or&&) = default;
diff --git a/chromium/media/base/status.md b/chromium/media/base/status.md
index deb5b06ee2c..288e9d5791d 100644
--- a/chromium/media/base/status.md
+++ b/chromium/media/base/status.md
@@ -5,32 +5,52 @@ enums that support causality tracking, data attachment, and general assistance
with debugging, without adding slowdowns due to returning large structs,
pointers, or more complicated types.
-TypedStatus<T> should be instantiated with a traits struct that defines:
-
- Codes - enum (usually enum class) that would be the return type, if we weren't
- using TypedStatus.
- static constexpr StatusGroupType Group() { return "NameOfStatus"; }
-
- // If DefaultEnumValue is present, then it returns the code that should be
- // treated as the common, optimized case. Generally, this is the "success"
- // case, unless you are unlucky. This function can be omitted if you do not
- // want any of the codes to be optimized.
- static constexpr Codes DefaultEnumValue() {
- return Codes::kCodeThatShouldBeSuperOptimized;
+A use-every-feature example:
+```c++
+struct MyExampleStatusTraits {
+ // [REQUIRED] Declare your enum
+ enum class Codes : StatusCodeType {
+ kSomething = 9090,
+ kAnotherThing = 92,
+ kAThirdThing = 458,
+ kAFinalThing = 438,
+ };
+
+ // [REQUIRED] Declare your group name
+ static constexpr StatusGroupType Group() { return "MyExampleStatus"; }
+
+ // [OPTIONAL] Declare your "default" code. If this method is defined,
+ // then the function OkStatus() can be used to return a status with this
+ // code. Statuses created with this default code can not have any data,
+ // causes, or a message attached.
+ static constexpr Codes DefaultEnumValue() { return Codes::kSomething; }
+
+ // [OPTIONAL] If |OnCreateFrom| is declared, then TypedStatus<T> can be
+ // created with {T::Codes, SomeOtherType} or {T::Codes, string, SomeOtherType}
+ // The pre-created TypedStatus is passed into this method for additional
+ // manipulation.
+ static void OnCreateFrom(TypedStatus<MyExampleStatusTraits>* impl,
+ const SomeOtherType& t) {
+ impl->WithData("key", SomeOtherTypeToString(t));
}
-Typically one would:
+ // [OPTIONAL] If you'd like to be able to send your status to UKM, declare
+ // this method in your traits. This allows you to pack any part of the
+ // status internal data into a single ukm-ready uint32.
+ static uint32_t PackExtraData(const internal::StatusData& data) {
+ return 0;
+ }
+};
- struct MyStatusTraits { ... };
- using MyStatus = TypedStatus<MyStatusTraits>;
+// Typically, you'd want to redefine your template instantiation, like this.
+using MyExampleStatus = TypedStatus<MyExampleStatusTraits>;
-## Using an existing `TypedStatus<T>`
+```
-The current canonical TypedStatus is called `Status` for historical reasons,
-though that will soon change.
-All TypedStatus specializations have the following common API:
+## Using an existing `TypedStatus<T>`
+All TypedStatus specializations have the following common API:
```c++
// The underlying code value.
T::Codes code() const;
@@ -78,8 +98,6 @@ Define an |TypedStatusTraits|, picking a name for the group of codes:
```c++
struct MyExampleStatusTraits {
- // If you do not have an existing enum, you can `enum class Codes { ... };`
- // here, instead of `using`.
using Codes = MyExampleEnum;
static constexpr StatusGroupType Group() { return "MyExampleStatus"; }
static constexpr Codes DefaultEnumValue() { return Codes::kDefaultValue; }
@@ -107,6 +125,9 @@ int main() {
}
```
+
+## TypedStatus<T>::Or<D>
+
For the common case where you'd like to return some constructed thing OR
an error type, we've also created `TypedStatus<T>::Or<D>`.
diff --git a/chromium/media/base/status_unittest.cc b/chromium/media/base/status_unittest.cc
index 60eba31436b..f49bbb66c17 100644
--- a/chromium/media/base/status_unittest.cc
+++ b/chromium/media/base/status_unittest.cc
@@ -68,6 +68,22 @@ struct TraitsWithCustomUKMSerializer {
}
};
+struct TraitsWithDataPacking {
+ enum class Codes { kOk, kFail };
+ struct PackThis {
+ int a;
+ int b;
+ std::string c;
+ };
+ static constexpr StatusGroupType Group() { return "GroupWithDataPacking"; }
+ static void OnCreateFrom(TypedStatus<TraitsWithDataPacking>* status,
+ const PackThis& data) {
+ status->WithData("DataA", data.a);
+ status->WithData("DataB", data.b);
+ status->WithData("DataC", data.c);
+ }
+};
+
class StatusTest : public testing::Test {
public:
using NormalStatus = TypedStatus<ZeroValueOkTypeTraits>;
@@ -149,6 +165,57 @@ class StatusTest : public testing::Test {
}
};
+TEST_F(StatusTest, DifferentModesOfConstruction) {
+ // Can construct any type with OkStatus
+ NormalStatus ok = OkStatus();
+ ASSERT_TRUE(ok.is_ok());
+
+ // Can construct implicitly from a code
+ NormalStatus ok2 = NormalStatus::Codes::kOk;
+ ASSERT_TRUE(ok.is_ok());
+
+ // Can construct implicitly from a {code, message} braced initializer.
+ NormalStatus foo = {NormalStatus::Codes::kFoo, "msg"};
+ ASSERT_EQ(foo.code(), NormalStatus::Codes::kFoo);
+ ASSERT_EQ(foo.message(), "msg");
+
+ // Can construct explicitly from a code and message
+ NormalStatus foo2 = NormalStatus(NormalStatus::Codes::kFoo, "msg2");
+ ASSERT_EQ(foo2.code(), NormalStatus::Codes::kFoo);
+ ASSERT_EQ(foo2.message(), "msg2");
+
+ using PackingStatus = TypedStatus<TraitsWithDataPacking>;
+ TraitsWithDataPacking::PackThis data = {7, 3, "apple pie"};
+
+ // Can construct implicitly from a {code, data} for a type with OnCreateFrom
+ // in it's traits
+ PackingStatus packed = {PackingStatus::Codes::kFail, data};
+ ASSERT_EQ(packed.code(), PackingStatus::Codes::kFail);
+ ASSERT_EQ(packed.message(), "");
+ // Keep serialized around, accessing |data| from it inline causes it
+ // to be destructed and |unpacked| to be used after being freed.
+ auto serialized = MediaSerialize(packed);
+ auto* unpacked = serialized.FindDictPath("data");
+ ASSERT_NE(unpacked, nullptr);
+ ASSERT_EQ(unpacked->DictSize(), 3ul);
+ ASSERT_EQ(unpacked->FindIntPath("DataA"), 7);
+ ASSERT_EQ(unpacked->FindIntPath("DataB"), 3);
+ ASSERT_EQ(*unpacked->FindStringPath("DataC"), "apple pie");
+
+ // Can construct implicitly from a {code, "message", data} for a type with
+ // OnCreateFrom in it's traits
+ PackingStatus packed2 = {PackingStatus::Codes::kFail, "*explosion*", data};
+ ASSERT_EQ(packed2.code(), PackingStatus::Codes::kFail);
+ ASSERT_EQ(packed2.message(), "*explosion*");
+ serialized = MediaSerialize(packed);
+ unpacked = serialized.FindDictPath("data");
+ ASSERT_NE(unpacked, nullptr);
+ ASSERT_EQ(unpacked->DictSize(), 3ul);
+ ASSERT_EQ(unpacked->FindIntPath("DataA"), 7);
+ ASSERT_EQ(unpacked->FindIntPath("DataB"), 3);
+ ASSERT_EQ(*unpacked->FindStringPath("DataC"), "apple pie");
+}
+
TEST_F(StatusTest, StaticOKMethodGivesCorrectSerialization) {
NormalStatus ok = DontFail();
base::Value actual = MediaSerialize(ok);
diff --git a/chromium/media/base/stream_parser.cc b/chromium/media/base/stream_parser.cc
index eeaf07616f0..904e16fe32d 100644
--- a/chromium/media/base/stream_parser.cc
+++ b/chromium/media/base/stream_parser.cc
@@ -10,7 +10,6 @@ namespace media {
StreamParser::InitParameters::InitParameters(base::TimeDelta duration)
: duration(duration),
- liveness(DemuxerStream::LIVENESS_UNKNOWN),
detected_audio_track_count(0),
detected_video_track_count(0),
detected_text_track_count(0) {}
diff --git a/chromium/media/base/stream_parser.h b/chromium/media/base/stream_parser.h
index 63a81d98ee4..4a0b0cae194 100644
--- a/chromium/media/base/stream_parser.h
+++ b/chromium/media/base/stream_parser.h
@@ -60,7 +60,7 @@ class MEDIA_EXPORT StreamParser {
base::Time timeline_offset;
// Indicates live stream.
- DemuxerStream::Liveness liveness;
+ StreamLiveness liveness = StreamLiveness::kUnknown;
// Counts of tracks detected by type within this stream. Not all of these
// tracks may be selected for use by the parser.
diff --git a/chromium/media/base/supported_types.cc b/chromium/media/base/supported_types.cc
index e45abab5c2d..41a4609a2a7 100644
--- a/chromium/media/base/supported_types.cc
+++ b/chromium/media/base/supported_types.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/logging.h"
+#include "base/no_destructor.h"
#include "base/notreached.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
@@ -36,6 +37,28 @@ namespace media {
namespace {
+class SupplementalProfileCache {
+ public:
+ void UpdateCache(const base::flat_set<media::VideoCodecProfile>& profiles) {
+ base::AutoLock lock(profiles_lock_);
+ DCHECK_EQ(profiles_.size(), 0u);
+ profiles_ = profiles;
+ }
+ bool IsProfileSupported(media::VideoCodecProfile profile) {
+ base::AutoLock lock(profiles_lock_);
+ return profiles_.find(profile) != profiles_.end();
+ }
+
+ private:
+ base::Lock profiles_lock_;
+ base::flat_set<media::VideoCodecProfile> profiles_ GUARDED_BY(profiles_lock_);
+};
+
+SupplementalProfileCache* GetSupplementalProfileCache() {
+ static base::NoDestructor<SupplementalProfileCache> cache;
+ return cache.get();
+}
+
bool IsSupportedHdrMetadata(const gfx::HdrMetadataType& hdr_metadata_type) {
switch (hdr_metadata_type) {
case gfx::HdrMetadataType::kNone:
@@ -179,7 +202,16 @@ bool IsAudioCodecProprietary(AudioCodec codec) {
#endif // !BUILDFLAG(USE_PROPRIETARY_CODECS)
bool IsHevcProfileSupported(const VideoType& type) {
-#if BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_HEVC)
+ if (!IsColorSpaceSupported(type.color_space))
+ return false;
+
+#if BUILDFLAG(ENABLE_PLATFORM_HEVC)
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+ return GetSupplementalProfileCache()->IsProfileSupported(type.profile);
+#else
+ return true;
+#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
+#elif BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_HEVC)
// Only encrypted HEVC content is supported, and normally MSE.isTypeSupported
// returns false for HEVC. The kEnableClearHevcForTesting flag allows it to
// return true to enable a wider array of test scenarios to function properly.
@@ -187,22 +219,10 @@ bool IsHevcProfileSupported(const VideoType& type) {
switches::kEnableClearHevcForTesting)) {
return false;
}
-
- // Color management required for HDR to not look terrible.
- if (!IsColorSpaceSupported(type.color_space))
- return false;
-
- switch (type.profile) {
- case HEVCPROFILE_MAIN:
- case HEVCPROFILE_MAIN10:
- return true;
- case HEVCPROFILE_MAIN_STILL_PICTURE:
- return false;
- default:
- NOTREACHED();
- }
-#endif // BUILDFLAG(ENABLE_PLATFORM_ENCRYPTED_HEVC)
+ return type.profile == HEVCPROFILE_MAIN || type.profile == HEVCPROFILE_MAIN10;
+#else
return false;
+#endif
}
bool IsVp9ProfileSupported(const VideoType& type) {
@@ -266,6 +286,10 @@ bool IsAACSupported(const AudioType& type) {
#if BUILDFLAG(IS_ANDROID)
return base::android::BuildInfo::GetInstance()->sdk_int() >=
base::android::SDK_VERSION_P;
+#elif BUILDFLAG(IS_MAC)
+ if (__builtin_available(macOS 10.15, *))
+ return true;
+ return false;
#else
return false;
#endif
@@ -355,11 +379,21 @@ bool IsDefaultSupportedAudioType(const AudioType& type) {
case AudioCodec::kALAC:
case AudioCodec::kAC3:
case AudioCodec::kMpegHAudio:
+ case AudioCodec::kUnknown:
+ return false;
case AudioCodec::kDTS:
case AudioCodec::kDTSXP2:
- case AudioCodec::kUnknown:
+#if BUILDFLAG(ENABLE_PLATFORM_DTS_AUDIO)
+ return true;
+#else
return false;
+#endif
}
}
+void UpdateDefaultSupportedVideoProfiles(
+ const base::flat_set<media::VideoCodecProfile>& profiles) {
+ GetSupplementalProfileCache()->UpdateCache(profiles);
+}
+
} // namespace media
diff --git a/chromium/media/base/supported_types.h b/chromium/media/base/supported_types.h
index ba4ab01c37e..0bbb6e6cc3f 100644
--- a/chromium/media/base/supported_types.h
+++ b/chromium/media/base/supported_types.h
@@ -5,6 +5,7 @@
#ifndef MEDIA_BASE_SUPPORTED_TYPES_H_
#define MEDIA_BASE_SUPPORTED_TYPES_H_
+#include "base/containers/flat_set.h"
#include "media/base/media_types.h"
namespace media {
@@ -21,6 +22,12 @@ MEDIA_EXPORT bool IsSupportedVideoType(const VideoType& type);
MEDIA_EXPORT bool IsDefaultSupportedAudioType(const AudioType& type);
MEDIA_EXPORT bool IsDefaultSupportedVideoType(const VideoType& type);
+// This function lets the caller add additional codec profiles to those
+// supported by default. Used primarily to add hardware codec profiles once
+// support is known.
+MEDIA_EXPORT void UpdateDefaultSupportedVideoProfiles(
+ const base::flat_set<VideoCodecProfile>& profiles);
+
} // namespace media
#endif // MEDIA_BASE_SUPPORTED_TYPES_H_
diff --git a/chromium/media/base/supported_types_unittest.cc b/chromium/media/base/supported_types_unittest.cc
index e0ad0925416..1d0f12e0bfa 100644
--- a/chromium/media/base/supported_types_unittest.cc
+++ b/chromium/media/base/supported_types_unittest.cc
@@ -249,21 +249,21 @@ TEST(SupportedTypesTest, IsSupportedAudioTypeWithSpatialRenderingBasics) {
is_spatial_rendering}));
}
-TEST(SupportedTypesTest, XHE_AACSupportedOnAndroidOnly) {
- // TODO(dalecurtis): Update this test if we ever have support elsewhere.
+TEST(SupportedTypesTest, XHE_AACSupported) {
+ bool is_supported = false;
+
#if BUILDFLAG(IS_ANDROID)
- const bool is_supported =
- kPropCodecsEnabled &&
- base::android::BuildInfo::GetInstance()->sdk_int() >=
- base::android::SDK_VERSION_P;
+ is_supported = kPropCodecsEnabled &&
+ base::android::BuildInfo::GetInstance()->sdk_int() >=
+ base::android::SDK_VERSION_P;
+#elif BUILDFLAG(IS_MAC) && BUILDFLAG(USE_PROPRIETARY_CODECS)
+ if (__builtin_available(macOS 10.15, *))
+ is_supported = true;
+#endif
EXPECT_EQ(is_supported,
IsSupportedAudioType(
{AudioCodec::kAAC, AudioCodecProfile::kXHE_AAC, false}));
-#else
- EXPECT_FALSE(IsSupportedAudioType(
- {AudioCodec::kAAC, AudioCodecProfile::kXHE_AAC, false}));
-#endif
}
TEST(SupportedTypesTest, IsSupportedVideoTypeWithHdrMetadataBasics) {
diff --git a/chromium/media/base/test_data_util.cc b/chromium/media/base/test_data_util.cc
index 4940d4c4adc..0858b67d0dc 100644
--- a/chromium/media/base/test_data_util.cc
+++ b/chromium/media/base/test_data_util.cc
@@ -8,7 +8,6 @@
#include "base/check_op.h"
#include "base/containers/flat_map.h"
-#include "base/cxx17_backports.h"
#include "base/files/file_util.h"
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
@@ -227,13 +226,13 @@ scoped_refptr<DecoderBuffer> ReadTestDataFile(const std::string& name) {
bool LookupTestKeyVector(const std::vector<uint8_t>& key_id,
bool allow_rotation,
std::vector<uint8_t>* key) {
- std::vector<uint8_t> starting_key_id(kKeyId, kKeyId + base::size(kKeyId));
+ std::vector<uint8_t> starting_key_id(kKeyId, kKeyId + std::size(kKeyId));
size_t rotate_limit = allow_rotation ? starting_key_id.size() : 1;
for (size_t pos = 0; pos < rotate_limit; ++pos) {
std::rotate(starting_key_id.begin(), starting_key_id.begin() + pos,
starting_key_id.end());
if (key_id == starting_key_id) {
- key->assign(kSecretKey, kSecretKey + base::size(kSecretKey));
+ key->assign(kSecretKey, kSecretKey + std::size(kSecretKey));
std::rotate(key->begin(), key->begin() + pos, key->end());
return true;
}
diff --git a/chromium/media/base/text_renderer_unittest.cc b/chromium/media/base/text_renderer_unittest.cc
index 40c14d262f4..68e805b7234 100644
--- a/chromium/media/base/text_renderer_unittest.cc
+++ b/chromium/media/base/text_renderer_unittest.cc
@@ -13,6 +13,7 @@
#include "base/callback_helpers.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
+#include "base/time/time.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/decoder_buffer.h"
#include "media/base/demuxer_stream.h"
diff --git a/chromium/media/base/time_delta_interpolator_unittest.cc b/chromium/media/base/time_delta_interpolator_unittest.cc
index ed8b35c5291..c1c7935ea31 100644
--- a/chromium/media/base/time_delta_interpolator_unittest.cc
+++ b/chromium/media/base/time_delta_interpolator_unittest.cc
@@ -2,8 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/test/simple_test_tick_clock.h"
#include "media/base/time_delta_interpolator.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
diff --git a/chromium/media/base/tuneable.cc b/chromium/media/base/tuneable.cc
index c3b6d4221db..d018fd6eee1 100644
--- a/chromium/media/base/tuneable.cc
+++ b/chromium/media/base/tuneable.cc
@@ -10,6 +10,7 @@
#include "base/hash/hash.h"
#include "base/metrics/field_trial_params.h"
#include "base/strings/string_number_conversions.h"
+#include "base/time/time.h"
#include "media/base/media_switches.h"
namespace {
diff --git a/chromium/media/base/unaligned_shared_memory_unittest.cc b/chromium/media/base/unaligned_shared_memory_unittest.cc
index 1e79bb29179..9d553cbc63f 100644
--- a/chromium/media/base/unaligned_shared_memory_unittest.cc
+++ b/chromium/media/base/unaligned_shared_memory_unittest.cc
@@ -9,7 +9,6 @@
#include <limits>
-#include "base/cxx17_backports.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {
@@ -17,11 +16,11 @@ namespace media {
namespace {
const uint8_t kUnalignedData[] = "XXXhello";
-const size_t kUnalignedDataSize = base::size(kUnalignedData);
+const size_t kUnalignedDataSize = std::size(kUnalignedData);
const off_t kUnalignedOffset = 3;
const uint8_t kData[] = "hello";
-const size_t kDataSize = base::size(kData);
+const size_t kDataSize = std::size(kData);
base::UnsafeSharedMemoryRegion CreateRegion(const uint8_t* data, size_t size) {
auto region = base::UnsafeSharedMemoryRegion::Create(size);
diff --git a/chromium/media/base/video_bitrate_allocation.cc b/chromium/media/base/video_bitrate_allocation.cc
index a988be2f126..cf01aa25da4 100644
--- a/chromium/media/base/video_bitrate_allocation.cc
+++ b/chromium/media/base/video_bitrate_allocation.cc
@@ -11,26 +11,74 @@
#include "base/check_op.h"
#include "base/numerics/checked_math.h"
+#include "media/base/bitrate.h"
+
+namespace {
+
+static media::Bitrate MakeReplacementBitrate(const media::Bitrate& old,
+ uint32_t target_bps,
+ uint32_t peak_bps) {
+ switch (old.mode()) {
+ case media::Bitrate::Mode::kConstant:
+ return media::Bitrate::ConstantBitrate(target_bps);
+ case media::Bitrate::Mode::kVariable:
+ return media::Bitrate::VariableBitrate(target_bps, peak_bps);
+ }
+}
+
+} // namespace
namespace media {
constexpr size_t VideoBitrateAllocation::kMaxSpatialLayers;
constexpr size_t VideoBitrateAllocation::kMaxTemporalLayers;
+VideoBitrateAllocation::VideoBitrateAllocation(Bitrate::Mode mode) {
+ switch (mode) {
+ case Bitrate::Mode::kConstant:
+ sum_bitrate_ = Bitrate::ConstantBitrate(0u);
+ break;
+ case Bitrate::Mode::kVariable:
+ // For variable bitrates, the peak must not be zero as enforced by
+ // Bitrate.
+ sum_bitrate_ = Bitrate::VariableBitrate(0u, 1u);
+ break;
+ }
+}
+
+bool VideoBitrateAllocation::SetPeakBps(uint32_t peak_bps) {
+ if (sum_bitrate_.mode() != Bitrate::Mode::kVariable)
+ return false;
+
+ if (peak_bps == 0u)
+ return false;
+
+ if (sum_bitrate_.target_bps() > peak_bps)
+ return false;
+
+ Bitrate old = sum_bitrate_;
+ sum_bitrate_ = MakeReplacementBitrate(old, old.target_bps(), peak_bps);
+ return true;
+}
+
bool VideoBitrateAllocation::SetBitrate(size_t spatial_index,
size_t temporal_index,
uint32_t bitrate_bps) {
CHECK_LT(spatial_index, kMaxSpatialLayers);
CHECK_LT(temporal_index, kMaxTemporalLayers);
- base::CheckedNumeric<uint32_t> checked_sum = sum_;
- checked_sum -= bitrates_[spatial_index][temporal_index];
+ base::CheckedNumeric<uint32_t> checked_sum = sum_bitrate_.target_bps();
+ uint32_t old_bitrate_bps = bitrates_[spatial_index][temporal_index];
+ checked_sum -= old_bitrate_bps;
checked_sum += bitrate_bps;
if (!checked_sum.IsValid()) {
return false; // Would cause overflow of the sum.
}
- sum_ = checked_sum.ValueOrDie();
+ const uint32_t new_sum_bps = checked_sum.ValueOrDefault(0u);
+ const uint32_t new_peak_bps = std::max(sum_bitrate_.peak_bps(), new_sum_bps);
+ sum_bitrate_ =
+ MakeReplacementBitrate(sum_bitrate_, new_sum_bps, new_peak_bps);
bitrates_[spatial_index][temporal_index] = bitrate_bps;
return true;
}
@@ -43,7 +91,11 @@ uint32_t VideoBitrateAllocation::GetBitrateBps(size_t spatial_index,
}
uint32_t VideoBitrateAllocation::GetSumBps() const {
- return sum_;
+ return sum_bitrate_.target_bps();
+}
+
+const Bitrate VideoBitrateAllocation::GetSumBitrate() const {
+ return sum_bitrate_;
}
std::string VideoBitrateAllocation::ToString() const {
@@ -83,13 +135,21 @@ std::string VideoBitrateAllocation::ToString() const {
}
ss << "}";
}
- ss << "}";
+ ss << "}, mode ";
+ switch (sum_bitrate_.mode()) {
+ case Bitrate::Mode::kConstant:
+ ss << "CBR";
+ break;
+ case Bitrate::Mode::kVariable:
+ ss << "VBR with peak bps " << sum_bitrate_.peak_bps();
+ break;
+ }
return ss.str();
}
bool VideoBitrateAllocation::operator==(
const VideoBitrateAllocation& other) const {
- if (sum_ != other.sum_) {
+ if (sum_bitrate_ != other.sum_bitrate_) {
return false;
}
return memcmp(bitrates_, other.bitrates_, sizeof(bitrates_)) == 0;
diff --git a/chromium/media/base/video_bitrate_allocation.h b/chromium/media/base/video_bitrate_allocation.h
index 5b4e6a29a41..62a3cc49a47 100644
--- a/chromium/media/base/video_bitrate_allocation.h
+++ b/chromium/media/base/video_bitrate_allocation.h
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <string>
+#include "media/base/bitrate.h"
#include "media/base/media_export.h"
namespace media {
@@ -21,14 +22,16 @@ class MEDIA_EXPORT VideoBitrateAllocation {
static constexpr size_t kMaxSpatialLayers = 5;
static constexpr size_t kMaxTemporalLayers = 4;
- VideoBitrateAllocation() = default;
+ explicit VideoBitrateAllocation(
+ Bitrate::Mode mode = Bitrate::Mode::kConstant);
~VideoBitrateAllocation() = default;
- // Returns if this bitrate can't be set (sum exceeds uint32_t max value). Do
- // not use an integer or uint64_t version of this. If you have a signed or
- // 64-bit value you want to use as input, you must explicitly convert to
- // uint32_t before calling. This is intended to prevent implicit and unsafe
- // type conversion.
+ // Returns true iff. the bitrate was set (sum within uint32_t max value). If
+ // a variable bitrate is used and the previous peak bitrate was below the new
+ // sum of bitrates across layers, this will automatically set the new peak to
+ // equal the new sum. If you have a signed or 64-bit value you want to use as
+ // input, you must explicitly convert to uint32_t before calling. This is
+ // intended to prevent implicit and unsafe type conversion.
bool SetBitrate(size_t spatial_index,
size_t temporal_index,
uint32_t bitrate_bps);
@@ -46,12 +49,21 @@ class MEDIA_EXPORT VideoBitrateAllocation {
size_t temporal_index,
uint64_t bitrate_bps) = delete;
+ // True iff. this bitrate allocation can have its peak set to |peak_bps| (the
+ // peak must be greater than the sum of the layers' bitrates, and the bitrate
+ // mode must be variable bitrate).
+ bool SetPeakBps(uint32_t peak_bps);
+
// Returns the bitrate for specified spatial/temporal index, or 0 if not set.
uint32_t GetBitrateBps(size_t spatial_index, size_t temporal_index) const;
// Sum of all bitrates.
uint32_t GetSumBps() const;
+ // Non-layered bitrate allocation. If there are layers, this bitrate's target
+ // bps equals the sum of the layers' bitrates.
+ const Bitrate GetSumBitrate() const;
+
std::string ToString() const;
bool operator==(const VideoBitrateAllocation& other) const;
@@ -60,8 +72,9 @@ class MEDIA_EXPORT VideoBitrateAllocation {
}
private:
- // Cached sum of all elements of |bitrates_|, for performance.
- uint32_t sum_ = 0u;
+ // A bitrate representing a cached sum of the elements of |bitrates_|, for
+ // performance.
+ Bitrate sum_bitrate_;
uint32_t bitrates_[kMaxSpatialLayers][kMaxTemporalLayers] = {};
};
diff --git a/chromium/media/base/video_bitrate_allocation_unittest.cc b/chromium/media/base/video_bitrate_allocation_unittest.cc
index 9794a819054..7ab8fdf07d7 100644
--- a/chromium/media/base/video_bitrate_allocation_unittest.cc
+++ b/chromium/media/base/video_bitrate_allocation_unittest.cc
@@ -9,6 +9,38 @@
namespace media {
+TEST(VideoBitrateAllocationTest, Constructor_DefaultsModeConstant) {
+ VideoBitrateAllocation allocation;
+
+ ASSERT_EQ(allocation.GetSumBitrate().mode(), Bitrate::Mode::kConstant);
+}
+
+TEST(VideoBitrateAllocationTest, Constructor_ConstantBitrate_CorrectMode) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kConstant);
+
+ ASSERT_EQ(allocation.GetSumBitrate().mode(), Bitrate::Mode::kConstant);
+}
+
+TEST(VideoBitrateAllocationTest, Constructor_VariableBitrate_CorrectMode) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+
+ ASSERT_EQ(allocation.GetSumBitrate().mode(), Bitrate::Mode::kVariable);
+}
+
+TEST(VideoBitrateAllocationTest,
+ Constructor_ConstantBitrate_InitializesTargetZero) {
+ VideoBitrateAllocation allocation;
+
+ ASSERT_EQ(allocation.GetSumBitrate().target_bps(), 0u);
+}
+
+TEST(VideoBitrateAllocationTest,
+ Constructor_VariableBitrate_InitializesTargetZero) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+
+ ASSERT_EQ(allocation.GetSumBitrate().target_bps(), 0u);
+}
+
TEST(VideoBitrateAllocationTest, SetAndGet) {
uint32_t sum = 0u;
uint32_t layer_rate = 0u;
@@ -39,6 +71,66 @@ TEST(VideoBitrateAllocationTest, SetAndGet) {
}
}
+TEST(VideoBitrateAllocationTest, SetBitrate_VariableBitrate_CorrectSum) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+ allocation.SetBitrate(0, 0, 1u);
+ allocation.SetBitrate(1, 0, 2u);
+ allocation.SetBitrate(0, 1, 3u);
+ allocation.SetBitrate(2, 2, 4u);
+ allocation.SetBitrate(1, 2, 5u);
+
+ ASSERT_EQ(15u, allocation.GetSumBps());
+}
+
+TEST(VideoBitrateAllocationTest, SetBitrate_PeakTooLow_IncreasesPeak) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+ allocation.SetPeakBps(50u);
+
+ ASSERT_TRUE(allocation.SetBitrate(0, 0, 1000u));
+ ASSERT_EQ(allocation.GetSumBitrate().peak_bps(), 1000u);
+}
+
+TEST(VideoBitrateAllocationTest, SetPeakBps_GreaterThanSum_Succeeds) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+ allocation.SetBitrate(0, 0, 500u);
+ allocation.SetBitrate(0, 1, 500u);
+ allocation.SetBitrate(1, 0, 500u);
+
+ ASSERT_TRUE(allocation.SetPeakBps(2000u));
+ ASSERT_EQ(allocation.GetSumBitrate().peak_bps(), 2000u);
+}
+
+TEST(VideoBitrateAllocationTest, SetPeakBps_EqualToSum_Succeeds) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+ allocation.SetBitrate(0, 0, 400u);
+ allocation.SetBitrate(0, 1, 300u);
+ allocation.SetBitrate(1, 0, 300u);
+
+ EXPECT_EQ(allocation.GetSumBps(), 1000u);
+
+ ASSERT_TRUE(allocation.SetPeakBps(1000u));
+ ASSERT_EQ(allocation.GetSumBitrate().peak_bps(), 1000u);
+}
+
+TEST(VideoBitrateAllocationTest, SetPeakBps_ImplicitConstantBitrate_Fails) {
+ VideoBitrateAllocation allocation;
+
+ ASSERT_FALSE(allocation.SetPeakBps(1u));
+}
+
+TEST(VideoBitrateAllocationTest, SetPeakBps_ConstantBitrate_Fails) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kConstant);
+
+ ASSERT_FALSE(allocation.SetPeakBps(1u));
+}
+
+TEST(VideoBitrateAllocationTest, SetPeakBps_PeakLessThanSum_Fails) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+ allocation.SetBitrate(0, 0, 1000u);
+
+ ASSERT_FALSE(allocation.SetPeakBps(999u));
+}
+
TEST(VideoBitrateAllocationTest, CanSetMaxValue) {
VideoBitrateAllocation allocation;
// Single cell containing max value.
@@ -87,26 +179,27 @@ TEST(VideoBitrateAllocationTest, ToString) {
EXPECT_TRUE(allocation.SetBitrate(0, 1, 456u));
EXPECT_TRUE(allocation.SetBitrate(0, 2, 789u));
EXPECT_EQ(allocation.ToString(),
- "active spatial layers: 1, {SL#0: {123, 456, 789}}");
+ "active spatial layers: 1, {SL#0: {123, 456, 789}}, mode CBR");
// Add spatial layer.
EXPECT_TRUE(allocation.SetBitrate(1, 0, 789u));
EXPECT_TRUE(allocation.SetBitrate(1, 1, 456u));
- EXPECT_EQ(
- allocation.ToString(),
- "active spatial layers: 2, {SL#0: {123, 456, 789}, SL#1: {789, 456}}");
+ EXPECT_EQ(allocation.ToString(),
+ "active spatial layers: 2, {SL#0: {123, 456, 789}, SL#1: {789, "
+ "456}}, mode CBR");
// Reset the bottom spatial layer.
EXPECT_TRUE(allocation.SetBitrate(0, 0, 0u));
EXPECT_TRUE(allocation.SetBitrate(0, 1, 0u));
EXPECT_TRUE(allocation.SetBitrate(0, 2, 0u));
EXPECT_EQ(allocation.ToString(),
- "active spatial layers: 1, {SL#1: {789, 456}}");
+ "active spatial layers: 1, {SL#1: {789, 456}}, mode CBR");
// Add one more spatial layer.
EXPECT_TRUE(allocation.SetBitrate(2, 0, 123u));
- EXPECT_EQ(allocation.ToString(),
- "active spatial layers: 2, {SL#1: {789, 456}, SL#2: {123}}");
+ EXPECT_EQ(
+ allocation.ToString(),
+ "active spatial layers: 2, {SL#1: {789, 456}, SL#2: {123}}, mode CBR");
// Reset all the spatial layers.
EXPECT_TRUE(allocation.SetBitrate(1, 0, 0u));
@@ -115,4 +208,27 @@ TEST(VideoBitrateAllocationTest, ToString) {
EXPECT_EQ(allocation.ToString(), "Empty VideoBitrateAllocation");
}
+TEST(VideoBitrateAllocationTest, ToString_VariableBitrateAndSingleLayer) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+ allocation.SetBitrate(0, 0, 1u);
+
+ EXPECT_EQ(allocation.ToString(),
+ "active spatial layers: 1, {SL#0: {1}}, mode VBR with peak bps 1");
+}
+
+TEST(VideoBitrateAllocationTest, ToString_VariableBitrateAndMultiLayer) {
+ VideoBitrateAllocation allocation(Bitrate::Mode::kVariable);
+ allocation.SetBitrate(0, 0, 1u);
+ allocation.SetBitrate(0, 1, 2u);
+ allocation.SetBitrate(0, 2, 3u);
+ allocation.SetBitrate(1, 0, 4u);
+ allocation.SetBitrate(1, 1, 5u);
+ allocation.SetBitrate(1, 2, 6u);
+ allocation.SetPeakBps(100u);
+
+ EXPECT_EQ(allocation.ToString(),
+ "active spatial layers: 2, {SL#0: {1, 2, 3}, SL#1: {4, 5, 6}}, "
+ "mode VBR with peak bps 100");
+}
+
} // namespace media
diff --git a/chromium/media/base/video_frame.cc b/chromium/media/base/video_frame.cc
index 9a4dab2a266..8e906c86f82 100644
--- a/chromium/media/base/video_frame.cc
+++ b/chromium/media/base/video_frame.cc
@@ -12,7 +12,6 @@
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
#include "base/bits.h"
-#include "base/cxx17_backports.h"
#include "base/logging.h"
#include "base/process/memory.h"
#include "base/strings/string_piece.h"
@@ -128,12 +127,16 @@ gfx::Size VideoFrame::SampleSize(VideoPixelFormat format, size_t plane) {
case PIXEL_FORMAT_YUV444P10:
case PIXEL_FORMAT_YUV444P12:
case PIXEL_FORMAT_Y16:
+ case PIXEL_FORMAT_I444A:
+ case PIXEL_FORMAT_YUV444AP10:
return gfx::Size(1, 1);
case PIXEL_FORMAT_I422:
case PIXEL_FORMAT_YUV422P9:
case PIXEL_FORMAT_YUV422P10:
case PIXEL_FORMAT_YUV422P12:
+ case PIXEL_FORMAT_I422A:
+ case PIXEL_FORMAT_YUV422AP10:
return gfx::Size(2, 1);
case PIXEL_FORMAT_YV12:
@@ -145,6 +148,7 @@ gfx::Size VideoFrame::SampleSize(VideoPixelFormat format, size_t plane) {
case PIXEL_FORMAT_YUV420P10:
case PIXEL_FORMAT_YUV420P12:
case PIXEL_FORMAT_P016LE:
+ case PIXEL_FORMAT_YUV420AP10:
return gfx::Size(2, 2);
case PIXEL_FORMAT_UYVY:
@@ -214,6 +218,11 @@ static bool RequiresEvenSizeAllocation(VideoPixelFormat format) {
case PIXEL_FORMAT_I420A:
case PIXEL_FORMAT_UYVY:
case PIXEL_FORMAT_P016LE:
+ case PIXEL_FORMAT_I422A:
+ case PIXEL_FORMAT_I444A:
+ case PIXEL_FORMAT_YUV420AP10:
+ case PIXEL_FORMAT_YUV422AP10:
+ case PIXEL_FORMAT_YUV444AP10:
return true;
case PIXEL_FORMAT_UNKNOWN:
break;
@@ -268,8 +277,6 @@ static absl::optional<VideoFrameLayout> GetDefaultLayout(
}
default:
- // TODO(miu): This function should support any pixel format.
- // http://crbug.com/555909 .
DLOG(ERROR) << "Unsupported pixel format"
<< VideoPixelFormatToString(format);
return absl::nullopt;
@@ -1060,16 +1067,19 @@ int VideoFrame::BytesPerElement(VideoPixelFormat format, size_t plane) {
case PIXEL_FORMAT_YUV420P12:
case PIXEL_FORMAT_YUV422P12:
case PIXEL_FORMAT_YUV444P12:
+ case PIXEL_FORMAT_YUV420AP10:
+ case PIXEL_FORMAT_YUV422AP10:
+ case PIXEL_FORMAT_YUV444AP10:
return 2;
case PIXEL_FORMAT_NV12:
case PIXEL_FORMAT_NV21: {
static const int bytes_per_element[] = {1, 2};
- DCHECK_LT(plane, base::size(bytes_per_element));
+ DCHECK_LT(plane, std::size(bytes_per_element));
return bytes_per_element[plane];
}
case PIXEL_FORMAT_P016LE: {
static const int bytes_per_element[] = {1, 2};
- DCHECK_LT(plane, base::size(bytes_per_element));
+ DCHECK_LT(plane, std::size(bytes_per_element));
return bytes_per_element[plane] * 2;
}
case PIXEL_FORMAT_YV12:
@@ -1077,6 +1087,8 @@ int VideoFrame::BytesPerElement(VideoPixelFormat format, size_t plane) {
case PIXEL_FORMAT_I422:
case PIXEL_FORMAT_I420A:
case PIXEL_FORMAT_I444:
+ case PIXEL_FORMAT_I422A:
+ case PIXEL_FORMAT_I444A:
return 1;
case PIXEL_FORMAT_MJPEG:
return 0;
@@ -1451,9 +1463,6 @@ bool VideoFrame::IsValidConfigInternal(VideoPixelFormat format,
return false;
}
- // Make sure new formats are properly accounted for in the method.
- static_assert(PIXEL_FORMAT_MAX == 33,
- "Added pixel format, please review AreSizesValid()");
switch (frame_control_type) {
case FrameControlType::kNone:
// Check that software-allocated buffer formats are not empty.
diff --git a/chromium/media/base/video_frame.h b/chromium/media/base/video_frame.h
index 0bc150669e5..edf74296fd3 100644
--- a/chromium/media/base/video_frame.h
+++ b/chromium/media/base/video_frame.h
@@ -22,6 +22,7 @@
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
+#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
@@ -588,9 +589,6 @@ class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
// Returns a dictionary of optional metadata. This contains information
// associated with the frame that downstream clients might use for frame-level
// logging, quality/performance optimizations, signaling, etc.
- //
- // TODO(miu): Move some of the "extra" members of VideoFrame (below) into
- // here as a later clean-up step.
const VideoFrameMetadata& metadata() const { return metadata_; }
VideoFrameMetadata& metadata() { return metadata_; }
void set_metadata(const VideoFrameMetadata& metadata) {
diff --git a/chromium/media/base/video_frame_layout.cc b/chromium/media/base/video_frame_layout.cc
index 3eef408656d..b3d666289e4 100644
--- a/chromium/media/base/video_frame_layout.cc
+++ b/chromium/media/base/video_frame_layout.cc
@@ -76,6 +76,11 @@ size_t VideoFrameLayout::NumPlanes(VideoPixelFormat format) {
case PIXEL_FORMAT_YUV444P12:
return 3;
case PIXEL_FORMAT_I420A:
+ case PIXEL_FORMAT_I422A:
+ case PIXEL_FORMAT_I444A:
+ case PIXEL_FORMAT_YUV420AP10:
+ case PIXEL_FORMAT_YUV422AP10:
+ case PIXEL_FORMAT_YUV444AP10:
return 4;
case PIXEL_FORMAT_UNKNOWN:
// Note: PIXEL_FORMAT_UNKNOWN is used for end-of-stream frame.
diff --git a/chromium/media/base/video_frame_metadata.cc b/chromium/media/base/video_frame_metadata.cc
index 47d0cd1166a..3a95860569e 100644
--- a/chromium/media/base/video_frame_metadata.cc
+++ b/chromium/media/base/video_frame_metadata.cc
@@ -50,6 +50,7 @@ void VideoFrameMetadata::MergeMetadataFrom(
MERGE_VALUE_FIELD(dcomp_surface, metadata_source);
MERGE_VALUE_FIELD(protected_video, metadata_source);
MERGE_VALUE_FIELD(hw_protected, metadata_source);
+ MERGE_VALUE_FIELD(is_webgpu_compatible, metadata_source);
#if BUILDFLAG(USE_VAAPI)
MERGE_OPTIONAL_FIELD(hw_va_protected_session_id, metadata_source);
#endif
diff --git a/chromium/media/base/video_frame_metadata.h b/chromium/media/base/video_frame_metadata.h
index e74c575399b..0f7560a4855 100644
--- a/chromium/media/base/video_frame_metadata.h
+++ b/chromium/media/base/video_frame_metadata.h
@@ -148,6 +148,10 @@ struct MEDIA_EXPORT VideoFrameMetadata {
// PROTECTED_VIDEO is also set to true.
bool hw_protected = false;
+ // This video frame's shared image backing can support zero-copy WebGPU
+ // import.
+ bool is_webgpu_compatible = false;
+
#if BUILDFLAG(USE_VAAPI)
// The ID of the VA-API protected session used to decode this frame, if
// applicable. The proper type is VAProtectedSessionID. However, in order to
diff --git a/chromium/media/base/video_frame_pool.cc b/chromium/media/base/video_frame_pool.cc
index e5aa15c28f8..8f6a0489fde 100644
--- a/chromium/media/base/video_frame_pool.cc
+++ b/chromium/media/base/video_frame_pool.cc
@@ -12,6 +12,7 @@
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/time/default_tick_clock.h"
+#include "base/time/time.h"
namespace media {
diff --git a/chromium/media/base/video_frame_unittest.cc b/chromium/media/base/video_frame_unittest.cc
index bf5ba94cddd..5db228c01b1 100644
--- a/chromium/media/base/video_frame_unittest.cc
+++ b/chromium/media/base/video_frame_unittest.cc
@@ -6,11 +6,11 @@
#include <stddef.h>
#include <stdint.h>
+
#include <memory>
#include "base/bind.h"
#include "base/callback_helpers.h"
-#include "base/cxx17_backports.h"
#include "base/format_macros.h"
#include "base/memory/aligned_memory.h"
#include "base/memory/unsafe_shared_memory_region.h"
@@ -340,15 +340,15 @@ TEST(VideoFrame, CreateBlackFrame) {
// Test frames themselves.
uint8_t* y_plane = frame->data(VideoFrame::kYPlane);
for (int y = 0; y < frame->coded_size().height(); ++y) {
- EXPECT_EQ(0, memcmp(kExpectedYRow, y_plane, base::size(kExpectedYRow)));
+ EXPECT_EQ(0, memcmp(kExpectedYRow, y_plane, std::size(kExpectedYRow)));
y_plane += frame->stride(VideoFrame::kYPlane);
}
uint8_t* u_plane = frame->data(VideoFrame::kUPlane);
uint8_t* v_plane = frame->data(VideoFrame::kVPlane);
for (int y = 0; y < frame->coded_size().height() / 2; ++y) {
- EXPECT_EQ(0, memcmp(kExpectedUVRow, u_plane, base::size(kExpectedUVRow)));
- EXPECT_EQ(0, memcmp(kExpectedUVRow, v_plane, base::size(kExpectedUVRow)));
+ EXPECT_EQ(0, memcmp(kExpectedUVRow, u_plane, std::size(kExpectedUVRow)));
+ EXPECT_EQ(0, memcmp(kExpectedUVRow, v_plane, std::size(kExpectedUVRow)));
u_plane += frame->stride(VideoFrame::kUPlane);
v_plane += frame->stride(VideoFrame::kVPlane);
}
@@ -703,12 +703,14 @@ TEST(VideoFrame, AllocationSize_OddSize) {
case PIXEL_FORMAT_YUV444P9:
case PIXEL_FORMAT_YUV444P10:
case PIXEL_FORMAT_YUV444P12:
+ case PIXEL_FORMAT_YUV422AP10:
EXPECT_EQ(144u, VideoFrame::AllocationSize(format, size))
<< VideoPixelFormatToString(format);
break;
case PIXEL_FORMAT_YUV422P9:
case PIXEL_FORMAT_YUV422P10:
case PIXEL_FORMAT_YUV422P12:
+ case PIXEL_FORMAT_I444A:
EXPECT_EQ(96u, VideoFrame::AllocationSize(format, size))
<< VideoPixelFormatToString(format);
break;
@@ -717,6 +719,7 @@ TEST(VideoFrame, AllocationSize_OddSize) {
case PIXEL_FORMAT_YUV420P10:
case PIXEL_FORMAT_YUV420P12:
case PIXEL_FORMAT_P016LE:
+ case PIXEL_FORMAT_I422A:
EXPECT_EQ(72u, VideoFrame::AllocationSize(format, size))
<< VideoPixelFormatToString(format);
break;
@@ -753,9 +756,14 @@ TEST(VideoFrame, AllocationSize_OddSize) {
<< VideoPixelFormatToString(format);
break;
case PIXEL_FORMAT_RGBAF16:
+ case PIXEL_FORMAT_YUV420AP10:
EXPECT_EQ(120u, VideoFrame::AllocationSize(format, size))
<< VideoPixelFormatToString(format);
break;
+ case PIXEL_FORMAT_YUV444AP10:
+ EXPECT_EQ(192u, VideoFrame::AllocationSize(format, size))
+ << VideoPixelFormatToString(format);
+ break;
case PIXEL_FORMAT_MJPEG:
case PIXEL_FORMAT_UNKNOWN:
continue;
diff --git a/chromium/media/base/video_transformation.cc b/chromium/media/base/video_transformation.cc
index 043ae2d0397..a293bb2ed09 100644
--- a/chromium/media/base/video_transformation.cc
+++ b/chromium/media/base/video_transformation.cc
@@ -14,8 +14,9 @@
namespace media {
namespace {
+template <size_t decimal_bits>
double FixedToFloatingPoint(int32_t i) {
- return static_cast<double>(i >> 16);
+ return i / static_cast<double>(1 << decimal_bits);
}
} // namespace
@@ -58,7 +59,6 @@ VideoTransformation::VideoTransformation(int32_t matrix[4]) {
// [ sin(Θ), cos(Θ)]
// A vertical flip is represented by the cosine's having opposite signs
// and a horizontal flip is represented by the sine's having the same sign.
-
// Check the matrix for validity
if (abs(matrix[0]) != abs(matrix[3]) || abs(matrix[1]) != abs(matrix[2])) {
rotation = VIDEO_ROTATION_0;
@@ -66,7 +66,19 @@ VideoTransformation::VideoTransformation(int32_t matrix[4]) {
return;
}
- double angle = acos(FixedToFloatingPoint(matrix[0])) * 180 / base::kPiDouble;
+ double angle =
+ acos(FixedToFloatingPoint<16>(matrix[0])) * 180 / base::kPiDouble;
+ double check_angle =
+ asin(FixedToFloatingPoint<16>(matrix[1])) * 180 / base::kPiDouble;
+ double offset = abs(abs(angle) - abs(check_angle));
+ while (offset >= 180.0)
+ offset -= 180.0;
+
+ if (offset > 1e-3) {
+ rotation = VIDEO_ROTATION_0;
+ mirrored = false;
+ return;
+ }
// Calculate angle offsets for rotation - rotating about the X axis
// can be expressed as a 180 degree rotation and a Y axis rotation
@@ -98,8 +110,7 @@ VideoTransformation::VideoTransformation(int32_t matrix[4]) {
} else if (abs(angle - 180) < 1e-4) {
rotation = VIDEO_ROTATION_180;
} else if (abs(angle - 90) < 1e-4) {
- bool quadrant = asin(FixedToFloatingPoint(matrix[2])) < 0;
- rotation = quadrant ? VIDEO_ROTATION_90 : VIDEO_ROTATION_270;
+ rotation = (check_angle > 0) ? VIDEO_ROTATION_90 : VIDEO_ROTATION_270;
} else {
rotation = VIDEO_ROTATION_0;
mirrored = false;
diff --git a/chromium/media/base/video_transformation_unittest.cc b/chromium/media/base/video_transformation_unittest.cc
new file mode 100644
index 00000000000..d0435e72f70
--- /dev/null
+++ b/chromium/media/base/video_transformation_unittest.cc
@@ -0,0 +1,92 @@
+// Copyright 2022 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_transformation.h"
+#include <math.h>
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+namespace {
+
+enum class Flip { kNone, kVertical, kHorizontal, kBoth };
+
+// Rotation by angle Θ is represented in the matrix as:
+// [ cos(Θ), -sin(Θ)]
+// [ sin(Θ), cos(Θ)]
+// a vertical flip is represented by the cosine's having opposite signs
+// and a horizontal flip is represented by the sine's having the same sign.
+constexpr void FromAngle(double angle_degrees, int32_t* matrix, Flip flip) {
+ double f_matrix[4] = {0, 0, 0, 0};
+ f_matrix[0] = f_matrix[3] = cos(angle_degrees * 3.1415926535 / 180.0);
+ f_matrix[1] = f_matrix[2] = sin(angle_degrees * 3.1415926535 / 180.0);
+ if (flip == Flip::kVertical || flip == Flip::kBoth)
+ f_matrix[3] *= -1;
+ if (flip == Flip::kVertical || flip == Flip::kNone)
+ f_matrix[2] *= -1;
+
+ matrix[0] = static_cast<int32_t>(round(f_matrix[0] * (1 << 16)));
+ matrix[1] = static_cast<int32_t>(round(f_matrix[1] * (1 << 16)));
+ matrix[3] = static_cast<int32_t>(round(f_matrix[2] * (1 << 16)));
+ matrix[4] = static_cast<int32_t>(round(f_matrix[3] * (1 << 16)));
+}
+
+} // namespace
+
+class VideoTransformationTest : public testing::Test {
+ public:
+ VideoTransformationTest() = default;
+ VideoTransformationTest(const VideoTransformationTest&) = delete;
+ VideoTransformationTest& operator=(const VideoTransformationTest&) = delete;
+ ~VideoTransformationTest() override = default;
+};
+
+TEST_F(VideoTransformationTest, ComputeRotationAngles) {
+ int32_t matrix[9];
+
+ // Standard 90 degree increments with no rotation all end up rotated normally
+ FromAngle(0.0, matrix, Flip::kNone);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_0, false));
+
+ FromAngle(90.0, matrix, Flip::kNone);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_90, false));
+
+ FromAngle(180.0, matrix, Flip::kNone);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_180, false));
+
+ FromAngle(270.0, matrix, Flip::kNone);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_270, false));
+
+ // Non-right-angle rotations all get set to 0, since we can't render those
+ // properly anyway.
+ FromAngle(60.0, matrix, Flip::kNone);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_0, false));
+
+ FromAngle(45.0, matrix, Flip::kNone);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_0, false));
+
+ // Flips can cause weird things - ie a vertical flip + 180 rotation
+ // is the same thing as a horizontal flip + no rotation!
+ FromAngle(180.0, matrix, Flip::kVertical);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_0, true));
+
+ // Vertical and horizontal flipping is the same as a 180 degree rotation
+ FromAngle(0.0, matrix, Flip::kBoth);
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_180, true));
+
+ // An invalid matrix is always going to give no rotation or mirroring.
+ for (int i = 0; i < 9; i++)
+ matrix[i] = 78123;
+ ASSERT_EQ(VideoTransformation::FromFFmpegDisplayMatrix(matrix),
+ VideoTransformation(VIDEO_ROTATION_0, false));
+}
+
+} // namespace media
diff --git a/chromium/media/base/video_types.cc b/chromium/media/base/video_types.cc
index 00b263dd050..d909bf5a2a5 100644
--- a/chromium/media/base/video_types.cc
+++ b/chromium/media/base/video_types.cc
@@ -75,6 +75,16 @@ std::string VideoPixelFormatToString(VideoPixelFormat format) {
return "PIXEL_FORMAT_BGRA";
case PIXEL_FORMAT_RGBAF16:
return "PIXEL_FORMAT_RGBAF16";
+ case PIXEL_FORMAT_I422A:
+ return "PIXEL_FORMAT_I422A";
+ case PIXEL_FORMAT_I444A:
+ return "PIXEL_FORMAT_I444A";
+ case PIXEL_FORMAT_YUV420AP10:
+ return "PIXEL_FORMAT_YUV420AP10";
+ case PIXEL_FORMAT_YUV422AP10:
+ return "PIXEL_FORMAT_YUV422AP10";
+ case PIXEL_FORMAT_YUV444AP10:
+ return "PIXEL_FORMAT_YUV444AP10";
}
NOTREACHED() << "Invalid VideoPixelFormat provided: " << format;
return "";
@@ -115,6 +125,11 @@ bool IsYuvPlanar(VideoPixelFormat format) {
case PIXEL_FORMAT_YUV422P12:
case PIXEL_FORMAT_YUV444P12:
case PIXEL_FORMAT_P016LE:
+ case PIXEL_FORMAT_I422A:
+ case PIXEL_FORMAT_I444A:
+ case PIXEL_FORMAT_YUV420AP10:
+ case PIXEL_FORMAT_YUV422AP10:
+ case PIXEL_FORMAT_YUV444AP10:
return true;
case PIXEL_FORMAT_UNKNOWN:
@@ -170,6 +185,11 @@ bool IsOpaque(VideoPixelFormat format) {
case PIXEL_FORMAT_ABGR:
case PIXEL_FORMAT_BGRA:
case PIXEL_FORMAT_RGBAF16:
+ case PIXEL_FORMAT_I422A:
+ case PIXEL_FORMAT_I444A:
+ case PIXEL_FORMAT_YUV420AP10:
+ case PIXEL_FORMAT_YUV422AP10:
+ case PIXEL_FORMAT_YUV444AP10:
break;
}
return false;
@@ -196,6 +216,8 @@ size_t BitDepth(VideoPixelFormat format) {
case PIXEL_FORMAT_ABGR:
case PIXEL_FORMAT_XBGR:
case PIXEL_FORMAT_BGRA:
+ case PIXEL_FORMAT_I422A:
+ case PIXEL_FORMAT_I444A:
return 8;
case PIXEL_FORMAT_YUV420P9:
case PIXEL_FORMAT_YUV422P9:
@@ -206,6 +228,9 @@ size_t BitDepth(VideoPixelFormat format) {
case PIXEL_FORMAT_YUV444P10:
case PIXEL_FORMAT_XR30:
case PIXEL_FORMAT_XB30:
+ case PIXEL_FORMAT_YUV420AP10:
+ case PIXEL_FORMAT_YUV422AP10:
+ case PIXEL_FORMAT_YUV444AP10:
return 10;
case PIXEL_FORMAT_YUV420P12:
case PIXEL_FORMAT_YUV422P12:
diff --git a/chromium/media/base/video_types.h b/chromium/media/base/video_types.h
index b0ce5ceeebf..dca783b768f 100644
--- a/chromium/media/base/video_types.h
+++ b/chromium/media/base/video_types.h
@@ -79,9 +79,18 @@ enum VideoPixelFormat {
PIXEL_FORMAT_RGBAF16 = 33, // Half float RGBA, 1 plane.
+ PIXEL_FORMAT_I422A = 34, // 24bpp YUVA planar 1x1 Y, 2x1 UV, 1x1 A samples.
+
+ PIXEL_FORMAT_I444A = 35, // 32bpp YUVA planar, no subsampling.
+
+ // YUVA planar, 10 bits per pixel component.
+ PIXEL_FORMAT_YUV420AP10 = 36,
+ PIXEL_FORMAT_YUV422AP10 = 37,
+ PIXEL_FORMAT_YUV444AP10 = 38,
+
// Please update UMA histogram enumeration when adding new formats here.
PIXEL_FORMAT_MAX =
- PIXEL_FORMAT_RGBAF16, // Must always be equal to largest entry logged.
+ PIXEL_FORMAT_YUV444AP10, // Must always be equal to largest entry logged.
};
// Returns the name of a Format as a string.
diff --git a/chromium/media/base/video_util.cc b/chromium/media/base/video_util.cc
index 0e4cb7fa468..a786d60496a 100644
--- a/chromium/media/base/video_util.cc
+++ b/chromium/media/base/video_util.cc
@@ -17,9 +17,12 @@
#include "base/time/time.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/raster_interface.h"
+#include "media/base/limits.h"
#include "media/base/video_frame.h"
#include "media/base/video_frame_pool.h"
+#include "media/base/video_types.h"
#include "third_party/libyuv/include/libyuv.h"
+#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -61,7 +64,7 @@ void FillRegionOutsideVisibleRect(uint8_t* data,
}
}
-VideoPixelFormat ReadbackFormat(const media::VideoFrame& frame) {
+VideoPixelFormat ReadbackFormat(const VideoFrame& frame) {
switch (frame.format()) {
case PIXEL_FORMAT_I420:
case PIXEL_FORMAT_I420A:
@@ -94,8 +97,8 @@ SkColorType SkColorTypeForPlane(VideoPixelFormat format, size_t plane) {
// kGray_8_SkColorType would make more sense but doesn't work on Windows.
return kAlpha_8_SkColorType;
case PIXEL_FORMAT_NV12:
- return plane == media::VideoFrame::kYPlane ? kAlpha_8_SkColorType
- : kR8G8_unorm_SkColorType;
+ return plane == VideoFrame::kYPlane ? kAlpha_8_SkColorType
+ : kR8G8_unorm_SkColorType;
case PIXEL_FORMAT_XBGR:
case PIXEL_FORMAT_ABGR:
return kRGBA_8888_SkColorType;
@@ -212,8 +215,8 @@ bool ReadbackTexturePlaneToMemorySyncOOP(const VideoFrame& src_frame,
sk_color_type, sk_alpha_type);
ri->ReadbackImagePixels(holder.mailbox, info, dest_stride, src_rect.x(),
src_rect.y(), dest_pixels);
- DCHECK_EQ(ri->GetError(), static_cast<GLenum>(GL_NO_ERROR));
- return true;
+ return ri->GetGraphicsResetStatusKHR() == GL_NO_ERROR &&
+ ri->GetError() == GL_NO_ERROR;
}
void LetterboxPlane(const gfx::Rect& view_area_in_bytes,
@@ -541,6 +544,23 @@ gfx::Rect ComputeLetterboxRegionForI420(const gfx::Rect& bounds,
return result;
}
+gfx::Rect MinimallyShrinkRectForI420(const gfx::Rect& rect) {
+ constexpr int kMinDimension = -1 * limits::kMaxDimension;
+ DCHECK(gfx::Rect(kMinDimension, kMinDimension, limits::kMaxDimension * 2,
+ limits::kMaxDimension * 2)
+ .Contains(rect));
+
+ const auto positive_mod = [](int a, int b) { return (a % b + b) % b; };
+
+ const int left = rect.x() + positive_mod(rect.x(), 2);
+ const int top = rect.y() + positive_mod(rect.y(), 2);
+ const int right = rect.right() - (rect.right() % 2);
+ const int bottom = rect.bottom() - (rect.bottom() % 2);
+
+ return gfx::Rect(left, top, std::max(0, right - left),
+ std::max(0, bottom - top));
+}
+
gfx::Size ScaleSizeToFitWithinTarget(const gfx::Size& size,
const gfx::Size& target) {
return ScaleSizeToTarget(size, target, true);
@@ -828,14 +848,13 @@ EncoderStatus ConvertAndScaleFrame(const VideoFrame& src_frame,
(src_frame.format() == PIXEL_FORMAT_I420 ||
src_frame.format() == PIXEL_FORMAT_I420A)) {
if (dst_frame.format() == PIXEL_FORMAT_I420A) {
- libyuv::ScalePlane(src_frame.visible_data(media::VideoFrame::kAPlane),
- src_frame.stride(media::VideoFrame::kAPlane),
- src_frame.visible_rect().width(),
- src_frame.visible_rect().height(),
- dst_frame.data(media::VideoFrame::kAPlane),
- dst_frame.stride(media::VideoFrame::kAPlane),
- dst_frame.coded_size().width(),
- dst_frame.coded_size().height(), kDefaultFiltering);
+ libyuv::ScalePlane(
+ src_frame.visible_data(VideoFrame::kAPlane),
+ src_frame.stride(VideoFrame::kAPlane),
+ src_frame.visible_rect().width(), src_frame.visible_rect().height(),
+ dst_frame.data(VideoFrame::kAPlane),
+ dst_frame.stride(VideoFrame::kAPlane), dst_frame.coded_size().width(),
+ dst_frame.coded_size().height(), kDefaultFiltering);
}
int error = libyuv::I420Scale(
src_frame.visible_data(VideoFrame::kYPlane),
@@ -879,7 +898,7 @@ EncoderStatus ConvertAndScaleFrame(const VideoFrame& src_frame,
if (dst_frame.format() == PIXEL_FORMAT_I420 &&
src_frame.format() == PIXEL_FORMAT_NV12) {
- if (src_frame.visible_rect() == dst_frame.visible_rect()) {
+ if (src_frame.visible_rect().size() == dst_frame.visible_rect().size()) {
// Both frames have the same size, only NV12-to-I420 conversion is
// required.
int error = libyuv::NV12ToI420(
@@ -940,7 +959,7 @@ EncoderStatus ConvertAndScaleFrame(const VideoFrame& src_frame,
if (dst_frame.format() == PIXEL_FORMAT_NV12 &&
src_frame.format() == PIXEL_FORMAT_I420) {
- if (src_frame.visible_rect() == dst_frame.visible_rect()) {
+ if (src_frame.visible_rect().size() == dst_frame.visible_rect().size()) {
// Both frames have the same size, only I420-to-NV12 conversion is
// required.
int error = libyuv::I420ToNV12(
@@ -1005,12 +1024,12 @@ 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;
+ return is_opaque ? PIXEL_FORMAT_XBGR : PIXEL_FORMAT_ABGR;
case kBGRA_8888_SkColorType:
- return is_opaque ? media::PIXEL_FORMAT_XRGB : media::PIXEL_FORMAT_ARGB;
+ return is_opaque ? PIXEL_FORMAT_XRGB : PIXEL_FORMAT_ARGB;
default:
// TODO(crbug.com/1073995): Add F16 support.
- return media::PIXEL_FORMAT_UNKNOWN;
+ return PIXEL_FORMAT_UNKNOWN;
}
}
diff --git a/chromium/media/base/video_util.h b/chromium/media/base/video_util.h
index c778f5ef916..5e09b2c0e1e 100644
--- a/chromium/media/base/video_util.h
+++ b/chromium/media/base/video_util.h
@@ -87,6 +87,11 @@ MEDIA_EXPORT gfx::Rect ComputeLetterboxRegion(const gfx::Rect& bounds,
MEDIA_EXPORT gfx::Rect ComputeLetterboxRegionForI420(const gfx::Rect& bounds,
const gfx::Size& content);
+// Shrinks the given |rect| by the minimum amount necessary to align its corners
+// to even-numbered coordinates. |rect| is assumed to have bounded limit values,
+// and may have negative bounds.
+MEDIA_EXPORT gfx::Rect MinimallyShrinkRectForI420(const gfx::Rect& rect);
+
// Return a scaled |size| whose area is less than or equal to |target|, where
// one of its dimensions is equal to |target|'s. The aspect ratio of |size| is
// preserved as closely as possible. If |size| is empty, the result will be
diff --git a/chromium/media/base/video_util_unittest.cc b/chromium/media/base/video_util_unittest.cc
index e82e3caccbd..01eaf7626e6 100644
--- a/chromium/media/base/video_util_unittest.cc
+++ b/chromium/media/base/video_util_unittest.cc
@@ -9,8 +9,10 @@
#include <cmath>
#include <memory>
+#include "media/base/limits.h"
#include "media/base/video_frame.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/rect.h"
namespace {
@@ -410,6 +412,58 @@ TEST_F(VideoUtilTest, ComputeLetterboxRegionForI420) {
.IsEmpty());
}
+// Tests the MinimallyShrinkRectForI420 function.
+TEST_F(VideoUtilTest, MinimallyShrinkRectForI420) {
+ // A few no-ops:
+ EXPECT_EQ(gfx::Rect(2, 2, 100, 100),
+ MinimallyShrinkRectForI420(gfx::Rect(2, 2, 100, 100)));
+ EXPECT_EQ(gfx::Rect(2, -2, 100, 100),
+ MinimallyShrinkRectForI420(gfx::Rect(2, -2, 100, 100)));
+ EXPECT_EQ(gfx::Rect(-2, 2, 100, 100),
+ MinimallyShrinkRectForI420(gfx::Rect(-2, 2, 100, 100)));
+
+ // Origin has odd coordinates:
+ EXPECT_EQ(gfx::Rect(2, 2, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(1, 1, 100, 100)));
+ EXPECT_EQ(gfx::Rect(0, 2, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(-1, 1, 100, 100)));
+ EXPECT_EQ(gfx::Rect(2, 0, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(1, -1, 100, 100)));
+
+ // Size is odd:
+ EXPECT_EQ(gfx::Rect(2, 2, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(2, 2, 99, 99)));
+ EXPECT_EQ(gfx::Rect(-2, 2, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(-2, 2, 99, 99)));
+ EXPECT_EQ(gfx::Rect(2, -2, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(2, -2, 99, 99)));
+
+ // Both are odd:
+ EXPECT_EQ(gfx::Rect(2, 2, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(1, 1, 99, 99)));
+ EXPECT_EQ(gfx::Rect(0, 2, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(-1, 1, 99, 99)));
+ EXPECT_EQ(gfx::Rect(2, 0, 98, 98),
+ MinimallyShrinkRectForI420(gfx::Rect(1, -1, 99, 99)));
+
+ // Check the biggest rectangle that the function will accept:
+ constexpr int kMinDimension = -1 * limits::kMaxDimension;
+ if (limits::kMaxDimension % 2 == 0) {
+ EXPECT_EQ(gfx::Rect(kMinDimension, kMinDimension, 2 * limits::kMaxDimension,
+ 2 * limits::kMaxDimension),
+ MinimallyShrinkRectForI420(gfx::Rect(kMinDimension, kMinDimension,
+ 2 * limits::kMaxDimension,
+ 2 * limits::kMaxDimension)));
+ } else {
+ EXPECT_EQ(
+ gfx::Rect(kMinDimension + 1, kMinDimension + 1,
+ 2 * limits::kMaxDimension - 2, 2 * limits::kMaxDimension - 2),
+ MinimallyShrinkRectForI420(gfx::Rect(kMinDimension, kMinDimension,
+ 2 * limits::kMaxDimension,
+ 2 * limits::kMaxDimension)));
+ }
+}
+
TEST_F(VideoUtilTest, ScaleSizeToEncompassTarget) {
EXPECT_EQ(gfx::Size(1000, 750),
ScaleSizeToEncompassTarget(gfx::Size(640, 480),
diff --git a/chromium/media/base/wall_clock_time_source_unittest.cc b/chromium/media/base/wall_clock_time_source_unittest.cc
index 05c7718f63d..20b701a336a 100644
--- a/chromium/media/base/wall_clock_time_source_unittest.cc
+++ b/chromium/media/base/wall_clock_time_source_unittest.cc
@@ -5,6 +5,7 @@
#include <memory>
#include "base/test/simple_test_tick_clock.h"
+#include "base/time/time.h"
#include "media/base/wall_clock_time_source.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/media/base/win/dcomp_texture_wrapper.h b/chromium/media/base/win/dcomp_texture_wrapper.h
index 93eee07749a..2974ea75cb2 100644
--- a/chromium/media/base/win/dcomp_texture_wrapper.h
+++ b/chromium/media/base/win/dcomp_texture_wrapper.h
@@ -45,11 +45,9 @@ class DCOMPTextureWrapper {
CreateVideoFrameCB create_video_frame_cb) = 0;
using CreateDXVideoFrameCB =
- base::OnceCallback<void(scoped_refptr<VideoFrame>,
- const base::UnguessableToken& token)>;
+ base::OnceCallback<void(scoped_refptr<VideoFrame>)>;
virtual void CreateVideoFrame(const gfx::Size& natural_size,
gfx::GpuMemoryBufferHandle dx_handle,
- const base::UnguessableToken& token,
CreateDXVideoFrameCB create_video_frame_cb) = 0;
};
diff --git a/chromium/media/base/win/hresult_status_helper.cc b/chromium/media/base/win/hresult_status_helper.cc
deleted file mode 100644
index b8218fa94a4..00000000000
--- a/chromium/media/base/win/hresult_status_helper.cc
+++ /dev/null
@@ -1,27 +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/win/hresult_status_helper.h"
-
-#include "base/logging.h"
-#include "base/strings/string_util.h"
-
-namespace media {
-
-D3D11Status HresultToStatus(HRESULT hresult,
- D3D11Status::Codes code,
- const char* message,
- const base::Location& location) {
- if (SUCCEEDED(hresult))
- return D3D11Status::Codes::kOk;
-
- std::string sys_err = logging::SystemErrorCodeToString(hresult);
- if (!base::IsStringUTF8AllowingNoncharacters(sys_err))
- sys_err = "System error string is invalid";
-
- return D3D11Status(code, message == nullptr ? "HRESULT" : message, location)
- .WithData("value", sys_err);
-}
-
-} // namespace media
diff --git a/chromium/media/base/win/media_foundation_cdm_proxy.h b/chromium/media/base/win/media_foundation_cdm_proxy.h
index 8ba852ad61d..36831e9a331 100644
--- a/chromium/media/base/win/media_foundation_cdm_proxy.h
+++ b/chromium/media/base/win/media_foundation_cdm_proxy.h
@@ -60,6 +60,12 @@ class MediaFoundationCdmProxy
// because they are in bad state.
virtual void OnHardwareContextReset() = 0;
+ // Notify the CDM that significant playback (e.g. >1 minutes) has happened.
+ virtual void OnSignificantPlayback() = 0;
+
+ // Notify the CDM that playback error happened.
+ virtual void OnPlaybackError() = 0;
+
protected:
friend base::RefCountedThreadSafe<MediaFoundationCdmProxy>;
virtual ~MediaFoundationCdmProxy() = default;