summaryrefslogtreecommitdiff
path: root/chromium/third_party/webrtc/test
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/webrtc/test
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/webrtc/test')
-rw-r--r--chromium/third_party/webrtc/test/BUILD.gn85
-rw-r--r--chromium/third_party/webrtc/test/DEPS3
-rw-r--r--chromium/third_party/webrtc/test/benchmark_main.cc17
-rw-r--r--chromium/third_party/webrtc/test/explicit_key_value_config.cc57
-rw-r--r--chromium/third_party/webrtc/test/explicit_key_value_config.h35
-rw-r--r--chromium/third_party/webrtc/test/fake_encoder.cc6
-rw-r--r--chromium/third_party/webrtc/test/fake_encoder.h25
-rw-r--r--chromium/third_party/webrtc/test/frame_forwarder.cc10
-rw-r--r--chromium/third_party/webrtc/test/frame_forwarder.h18
-rw-r--r--chromium/third_party/webrtc/test/frame_generator_capturer_unittest.cc4
-rw-r--r--chromium/third_party/webrtc/test/fuzzers/BUILD.gn35
-rw-r--r--chromium/third_party/webrtc/test/logging/BUILD.gn2
-rw-r--r--chromium/third_party/webrtc/test/mock_audio_decoder.h22
-rw-r--r--chromium/third_party/webrtc/test/mock_audio_decoder_factory.h18
-rw-r--r--chromium/third_party/webrtc/test/mock_audio_encoder.h65
-rw-r--r--chromium/third_party/webrtc/test/mock_audio_encoder_factory.h24
-rw-r--r--chromium/third_party/webrtc/test/mock_transport.h2
-rw-r--r--chromium/third_party/webrtc/test/network/BUILD.gn6
-rw-r--r--chromium/third_party/webrtc/test/network/cross_traffic.cc13
-rw-r--r--chromium/third_party/webrtc/test/network/network_emulation_unittest.cc2
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/BUILD.gn1069
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.cc126
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h22
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc675
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h308
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc388
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc18
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h34
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue.h99
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue_test.cc103
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc19
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h9
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc21
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h9
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc81
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h7
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector_unittest.cc74
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc48
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h32
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc112
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h23
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/echo/echo_emulation.cc10
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/media/media_helper.cc2
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.cc52
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.h10
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/peer_configurer.h17
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc129
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.cc28
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.h4
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test_params.h4
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/stats_poller.cc9
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/stats_poller.h6
-rw-r--r--chromium/third_party/webrtc/test/pc/e2e/test_peer_factory.cc18
-rw-r--r--chromium/third_party/webrtc/test/peer_scenario/BUILD.gn2
-rw-r--r--chromium/third_party/webrtc/test/run_loop_unittest.cc1
-rw-r--r--chromium/third_party/webrtc/test/scenario/BUILD.gn2
-rw-r--r--chromium/third_party/webrtc/test/scenario/call_client.cc13
-rw-r--r--chromium/third_party/webrtc/test/scenario/call_client.h2
-rw-r--r--chromium/third_party/webrtc/test/scenario/scenario_unittest.cc3
-rw-r--r--chromium/third_party/webrtc/test/test_main.cc7
-rw-r--r--chromium/third_party/webrtc/test/test_main_lib.cc66
-rw-r--r--chromium/third_party/webrtc/test/testsupport/mock/mock_frame_reader.h10
-rw-r--r--chromium/third_party/webrtc/test/testsupport/perf_test.h1
-rw-r--r--chromium/third_party/webrtc/test/testsupport/resources_dir_flag.cc2
-rw-r--r--chromium/third_party/webrtc/test/testsupport/resources_dir_flag.h2
-rw-r--r--chromium/third_party/webrtc/test/testsupport/test_artifacts_unittest.cc1
-rw-r--r--chromium/third_party/webrtc/test/time_controller/BUILD.gn2
-rw-r--r--chromium/third_party/webrtc/test/time_controller/simulated_time_controller.cc8
-rw-r--r--chromium/third_party/webrtc/test/time_controller/simulated_time_controller.h22
69 files changed, 2898 insertions, 1261 deletions
diff --git a/chromium/third_party/webrtc/test/BUILD.gn b/chromium/third_party/webrtc/test/BUILD.gn
index 34da8894f74..9215b679cea 100644
--- a/chromium/third_party/webrtc/test/BUILD.gn
+++ b/chromium/third_party/webrtc/test/BUILD.gn
@@ -22,13 +22,13 @@ group("test") {
":test_renderer",
":test_support",
":video_test_common",
- "pc/e2e",
]
if (rtc_include_tests) {
deps += [
":test_main",
":test_support_unittests",
+ "pc/e2e",
]
}
}
@@ -70,8 +70,8 @@ rtc_library("frame_generator_impl") {
"../rtc_base/synchronization:sequence_checker",
"../rtc_base/system:file_wrapper",
"../system_wrappers",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("frame_utils") {
@@ -127,8 +127,8 @@ rtc_library("video_test_common") {
"../rtc_base:timeutils",
"../rtc_base/task_utils:repeating_task",
"../system_wrappers",
- "//third_party/abseil-cpp/absl/strings",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
}
if (!build_with_chromium) {
@@ -160,10 +160,8 @@ if (!build_with_chromium) {
"platform_video_capturer.cc",
"platform_video_capturer.h",
]
- deps = [
- ":video_test_common",
- "//third_party/abseil-cpp/absl/memory",
- ]
+ deps = [ ":video_test_common" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
if (is_mac || is_ios) {
deps += [ ":video_test_mac" ]
} else {
@@ -218,6 +216,20 @@ rtc_library("field_trial") {
deps = [ "../system_wrappers:field_trial" ]
}
+rtc_library("explicit_key_value_config") {
+ sources = [
+ "explicit_key_value_config.cc",
+ "explicit_key_value_config.h",
+ ]
+
+ deps = [
+ "../api/transport:webrtc_key_value_config",
+ "../rtc_base:checks",
+ "../system_wrappers:field_trial",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings:strings" ]
+}
+
rtc_library("perf_test") {
visibility = [ "*" ]
testonly = true
@@ -235,9 +247,8 @@ rtc_library("perf_test") {
"../rtc_base:criticalsection",
"../rtc_base:logging",
"../rtc_base:rtc_numerics",
- "//third_party/abseil-cpp/absl/flags:flag",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
if (rtc_enable_protobuf) {
sources += [ "testsupport/perf_test_histogram_writer.cc" ]
deps += [
@@ -262,8 +273,8 @@ if (is_ios) {
deps = [
":perf_test",
"../sdk:helpers_objc",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
configs += [ ":test_support_objc_config" ]
}
@@ -359,8 +370,8 @@ rtc_library("video_test_support") {
"../rtc_base:rtc_event",
"../rtc_base/synchronization:sequence_checker",
"../rtc_base/system:file_wrapper",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
if (!is_ios) {
deps += [ "//third_party:jpeg" ]
@@ -375,6 +386,16 @@ rtc_library("video_test_support") {
}
if (rtc_include_tests) {
+ rtc_library("resources_dir_flag") {
+ testonly = true
+ visibility = [ "*" ]
+ sources = [
+ "testsupport/resources_dir_flag.cc",
+ "testsupport/resources_dir_flag.h",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/flags:flag" ]
+ }
+
rtc_library("test_main_lib") {
visibility = [ "*" ]
testonly = true
@@ -394,9 +415,12 @@ if (rtc_include_tests) {
"../rtc_base:rtc_base_approved",
"../system_wrappers:field_trial",
"../system_wrappers:metrics",
+ ]
+ absl_deps = [
"//third_party/abseil-cpp/absl/flags:flag",
"//third_party/abseil-cpp/absl/flags:parse",
"//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings:strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
@@ -406,13 +430,20 @@ if (rtc_include_tests) {
testonly = true
sources = [ "test_main.cc" ]
- deps = [
- ":test_main_lib",
+ deps = [ ":test_main_lib" ]
+ absl_deps = [
"//third_party/abseil-cpp/absl/debugging:failure_signal_handler",
"//third_party/abseil-cpp/absl/debugging:symbolize",
]
}
+ rtc_library("benchmark_main") {
+ testonly = true
+ sources = [ "benchmark_main.cc" ]
+
+ deps = [ "//third_party/google_benchmark" ]
+ }
+
rtc_library("test_support_test_artifacts") {
testonly = true
sources = [
@@ -423,6 +454,8 @@ if (rtc_include_tests) {
":fileutils",
"../rtc_base:logging",
"../rtc_base/system:file_wrapper",
+ ]
+ absl_deps = [
"//third_party/abseil-cpp/absl/flags:flag",
"//third_party/abseil-cpp/absl/flags:parse",
]
@@ -586,8 +619,8 @@ rtc_library("fileutils") {
":fileutils_override_impl",
"../rtc_base:checks",
"../rtc_base:stringutils",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
if (is_ios) {
deps += [ ":fileutils_ios_objc" ]
}
@@ -599,16 +632,6 @@ rtc_library("fileutils") {
}
}
-rtc_library("resources_dir_flag") {
- testonly = true
- visibility = [ "*" ]
- sources = [
- "testsupport/resources_dir_flag.cc",
- "testsupport/resources_dir_flag.h",
- ]
- deps = [ "//third_party/abseil-cpp/absl/flags:flag" ]
-}
-
# We separate header into own target to make it possible for downstream
# projects to override implementation.
rtc_source_set("fileutils_override_api") {
@@ -625,8 +648,8 @@ rtc_library("fileutils_override_impl") {
"../rtc_base:checks",
"../rtc_base:macromagic",
"../rtc_base:stringutils",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
if (is_ios) {
deps += [ ":fileutils_ios_objc" ]
}
@@ -676,8 +699,8 @@ rtc_library("fileutils_unittests") {
":fileutils",
":test_support",
"../rtc_base:checks",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("direct_transport") {
@@ -699,8 +722,8 @@ rtc_library("direct_transport") {
"../rtc_base:timeutils",
"../rtc_base/synchronization:sequence_checker",
"../rtc_base/task_utils:repeating_task",
- "//third_party/abseil-cpp/absl/memory",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
public_deps = # no-presubmit-check TODO(webrtc:8603)
[ "../call:fake_network" ]
}
@@ -742,8 +765,8 @@ rtc_library("fake_video_codecs") {
"../rtc_base:timeutils",
"../rtc_base/synchronization:sequence_checker",
"../system_wrappers",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("null_transport") {
@@ -839,8 +862,8 @@ rtc_library("test_common") {
"../rtc_base/task_utils:to_queued_task",
"../system_wrappers",
"../system_wrappers:field_trial",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
if (!is_android && !build_with_chromium) {
deps += [ "../modules/video_capture:video_capture_internal_impl" ]
}
@@ -986,8 +1009,8 @@ rtc_library("audio_codec_mocks") {
"../api/audio_codecs:builtin_audio_decoder_factory",
"../rtc_base:checks",
"../rtc_base:refcount",
- "//third_party/abseil-cpp/absl/memory",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
}
rtc_library("copy_to_file_audio_capturer") {
@@ -1001,8 +1024,8 @@ rtc_library("copy_to_file_audio_capturer") {
"../common_audio",
"../modules/audio_device:audio_device_impl",
"../rtc_base:rtc_base_approved",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("copy_to_file_audio_capturer_unittest") {
diff --git a/chromium/third_party/webrtc/test/DEPS b/chromium/third_party/webrtc/test/DEPS
index 62fd6d3ff77..170c4086d74 100644
--- a/chromium/third_party/webrtc/test/DEPS
+++ b/chromium/third_party/webrtc/test/DEPS
@@ -72,5 +72,8 @@ specific_include_rules = {
],
".*test_video_capturer_video_track_source.h": [
"+pc",
+ ],
+ "benchmark_main\.cc": [
+ "+benchmark",
]
}
diff --git a/chromium/third_party/webrtc/test/benchmark_main.cc b/chromium/third_party/webrtc/test/benchmark_main.cc
new file mode 100644
index 00000000000..1a79c249133
--- /dev/null
+++ b/chromium/third_party/webrtc/test/benchmark_main.cc
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "benchmark/benchmark.h"
+
+int main(int argc, char* argv[]) {
+ benchmark::Initialize(&argc, argv);
+ benchmark::RunSpecifiedBenchmarks();
+ return 0;
+}
diff --git a/chromium/third_party/webrtc/test/explicit_key_value_config.cc b/chromium/third_party/webrtc/test/explicit_key_value_config.cc
new file mode 100644
index 00000000000..69f725a9e24
--- /dev/null
+++ b/chromium/third_party/webrtc/test/explicit_key_value_config.cc
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "test/explicit_key_value_config.h"
+
+#include "api/transport/webrtc_key_value_config.h"
+#include "rtc_base/checks.h"
+#include "system_wrappers/include/field_trial.h"
+
+namespace webrtc {
+namespace test {
+
+ExplicitKeyValueConfig::ExplicitKeyValueConfig(const std::string& s) {
+ std::string::size_type field_start = 0;
+ while (field_start < s.size()) {
+ std::string::size_type separator_pos = s.find('/', field_start);
+ RTC_CHECK_NE(separator_pos, std::string::npos)
+ << "Missing separator '/' after field trial key.";
+ RTC_CHECK_GT(separator_pos, field_start)
+ << "Field trial key cannot be empty.";
+ std::string key = s.substr(field_start, separator_pos - field_start);
+ field_start = separator_pos + 1;
+
+ RTC_CHECK_LT(field_start, s.size())
+ << "Missing value after field trial key. String ended.";
+ separator_pos = s.find('/', field_start);
+ RTC_CHECK_NE(separator_pos, std::string::npos)
+ << "Missing terminating '/' in field trial string.";
+ RTC_CHECK_GT(separator_pos, field_start)
+ << "Field trial value cannot be empty.";
+ std::string value = s.substr(field_start, separator_pos - field_start);
+ field_start = separator_pos + 1;
+
+ key_value_map_[key] = value;
+ }
+ // This check is technically redundant due to earlier checks.
+ // We nevertheless keep the check to make it clear that the entire
+ // string has been processed, and without indexing past the end.
+ RTC_CHECK_EQ(field_start, s.size());
+}
+
+std::string ExplicitKeyValueConfig::Lookup(absl::string_view key) const {
+ auto it = key_value_map_.find(std::string(key));
+ if (it != key_value_map_.end())
+ return it->second;
+ return "";
+}
+
+} // namespace test
+} // namespace webrtc
diff --git a/chromium/third_party/webrtc/test/explicit_key_value_config.h b/chromium/third_party/webrtc/test/explicit_key_value_config.h
new file mode 100644
index 00000000000..9a3bc84f606
--- /dev/null
+++ b/chromium/third_party/webrtc/test/explicit_key_value_config.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef TEST_EXPLICIT_KEY_VALUE_CONFIG_H_
+#define TEST_EXPLICIT_KEY_VALUE_CONFIG_H_
+
+#include <map>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "api/transport/webrtc_key_value_config.h"
+
+namespace webrtc {
+namespace test {
+
+class ExplicitKeyValueConfig : public WebRtcKeyValueConfig {
+ public:
+ explicit ExplicitKeyValueConfig(const std::string& s);
+ std::string Lookup(absl::string_view key) const override;
+
+ private:
+ std::map<std::string, std::string> key_value_map_;
+};
+
+} // namespace test
+} // namespace webrtc
+
+#endif // TEST_EXPLICIT_KEY_VALUE_CONFIG_H_
diff --git a/chromium/third_party/webrtc/test/fake_encoder.cc b/chromium/third_party/webrtc/test/fake_encoder.cc
index 64b4a4e9ff8..2959559910e 100644
--- a/chromium/third_party/webrtc/test/fake_encoder.cc
+++ b/chromium/third_party/webrtc/test/fake_encoder.cc
@@ -69,7 +69,7 @@ void FakeEncoder::SetMaxBitrate(int max_kbps) {
RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it.
rtc::CritScope cs(&crit_sect_);
max_target_bitrate_kbps_ = max_kbps;
- SetRates(current_rate_settings_);
+ SetRatesLocked(current_rate_settings_);
}
void FakeEncoder::SetQp(int qp) {
@@ -243,6 +243,10 @@ int32_t FakeEncoder::Release() {
void FakeEncoder::SetRates(const RateControlParameters& parameters) {
rtc::CritScope cs(&crit_sect_);
+ SetRatesLocked(parameters);
+}
+
+void FakeEncoder::SetRatesLocked(const RateControlParameters& parameters) {
current_rate_settings_ = parameters;
int allocated_bitrate_kbps = parameters.bitrate.get_sum_kbps();
diff --git a/chromium/third_party/webrtc/test/fake_encoder.h b/chromium/third_party/webrtc/test/fake_encoder.h
index 39838d16f14..ade0e35560c 100644
--- a/chromium/third_party/webrtc/test/fake_encoder.h
+++ b/chromium/third_party/webrtc/test/fake_encoder.h
@@ -40,21 +40,23 @@ class FakeEncoder : public VideoEncoder {
virtual ~FakeEncoder() = default;
// Sets max bitrate. Not thread-safe, call before registering the encoder.
- void SetMaxBitrate(int max_kbps);
- void SetQp(int qp);
+ void SetMaxBitrate(int max_kbps) RTC_LOCKS_EXCLUDED(crit_sect_);
+ void SetQp(int qp) RTC_LOCKS_EXCLUDED(crit_sect_);
void SetFecControllerOverride(
FecControllerOverride* fec_controller_override) override;
- int32_t InitEncode(const VideoCodec* config,
- const Settings& settings) override;
+ int32_t InitEncode(const VideoCodec* config, const Settings& settings)
+ RTC_LOCKS_EXCLUDED(crit_sect_) override;
int32_t Encode(const VideoFrame& input_image,
- const std::vector<VideoFrameType>* frame_types) override;
- int32_t RegisterEncodeCompleteCallback(
- EncodedImageCallback* callback) override;
+ const std::vector<VideoFrameType>* frame_types)
+ RTC_LOCKS_EXCLUDED(crit_sect_) override;
+ int32_t RegisterEncodeCompleteCallback(EncodedImageCallback* callback)
+ RTC_LOCKS_EXCLUDED(crit_sect_) override;
int32_t Release() override;
- void SetRates(const RateControlParameters& parameters) override;
- int GetConfiguredInputFramerate() const;
+ void SetRates(const RateControlParameters& parameters)
+ RTC_LOCKS_EXCLUDED(crit_sect_) override;
+ int GetConfiguredInputFramerate() const RTC_LOCKS_EXCLUDED(crit_sect_);
EncoderInfo GetEncoderInfo() const override;
static const char* kImplementationName;
@@ -79,7 +81,7 @@ class FakeEncoder : public VideoEncoder {
uint8_t num_simulcast_streams,
const VideoBitrateAllocation& target_bitrate,
SimulcastStream simulcast_streams[kMaxSimulcastStreams],
- int framerate);
+ int framerate) RTC_LOCKS_EXCLUDED(crit_sect_);
// Called before the frame is passed to callback_->OnEncodedImage, to let
// subclasses fill out codec_specific, possibly modify encodedImage.
@@ -88,6 +90,9 @@ class FakeEncoder : public VideoEncoder {
EncodedImage* encoded_image,
CodecSpecificInfo* codec_specific);
+ void SetRatesLocked(const RateControlParameters& parameters)
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
+
FrameInfo last_frame_info_ RTC_GUARDED_BY(crit_sect_);
Clock* const clock_;
diff --git a/chromium/third_party/webrtc/test/frame_forwarder.cc b/chromium/third_party/webrtc/test/frame_forwarder.cc
index d1a2ddb1c29..d8ec4b5060e 100644
--- a/chromium/third_party/webrtc/test/frame_forwarder.cc
+++ b/chromium/third_party/webrtc/test/frame_forwarder.cc
@@ -26,6 +26,12 @@ void FrameForwarder::IncomingCapturedFrame(const VideoFrame& video_frame) {
void FrameForwarder::AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
const rtc::VideoSinkWants& wants) {
rtc::CritScope lock(&crit_);
+ AddOrUpdateSinkLocked(sink, wants);
+}
+
+void FrameForwarder::AddOrUpdateSinkLocked(
+ rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants) {
RTC_DCHECK(!sink_ || sink_ == sink);
sink_ = sink;
sink_wants_ = wants;
@@ -42,6 +48,10 @@ rtc::VideoSinkWants FrameForwarder::sink_wants() const {
return sink_wants_;
}
+rtc::VideoSinkWants FrameForwarder::sink_wants_locked() const {
+ return sink_wants_;
+}
+
bool FrameForwarder::has_sinks() const {
rtc::CritScope lock(&crit_);
return sink_ != nullptr;
diff --git a/chromium/third_party/webrtc/test/frame_forwarder.h b/chromium/third_party/webrtc/test/frame_forwarder.h
index cf29f5f0743..d391160fab0 100644
--- a/chromium/third_party/webrtc/test/frame_forwarder.h
+++ b/chromium/third_party/webrtc/test/frame_forwarder.h
@@ -26,14 +26,22 @@ class FrameForwarder : public rtc::VideoSourceInterface<VideoFrame> {
FrameForwarder();
~FrameForwarder() override;
// Forwards |video_frame| to the registered |sink_|.
- virtual void IncomingCapturedFrame(const VideoFrame& video_frame);
- rtc::VideoSinkWants sink_wants() const;
- bool has_sinks() const;
+ virtual void IncomingCapturedFrame(const VideoFrame& video_frame)
+ RTC_LOCKS_EXCLUDED(crit_);
+ rtc::VideoSinkWants sink_wants() const RTC_LOCKS_EXCLUDED(crit_);
+ bool has_sinks() const RTC_LOCKS_EXCLUDED(crit_);
protected:
+ rtc::VideoSinkWants sink_wants_locked() const
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
- const rtc::VideoSinkWants& wants) override;
- void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override;
+ const rtc::VideoSinkWants& wants)
+ RTC_LOCKS_EXCLUDED(crit_) override;
+ void AddOrUpdateSinkLocked(rtc::VideoSinkInterface<VideoFrame>* sink,
+ const rtc::VideoSinkWants& wants)
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
+ void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink)
+ RTC_LOCKS_EXCLUDED(crit_) override;
rtc::CriticalSection crit_;
rtc::VideoSinkInterface<VideoFrame>* sink_ RTC_GUARDED_BY(crit_);
diff --git a/chromium/third_party/webrtc/test/frame_generator_capturer_unittest.cc b/chromium/third_party/webrtc/test/frame_generator_capturer_unittest.cc
index 7400bbb79bd..a76cb95d443 100644
--- a/chromium/third_party/webrtc/test/frame_generator_capturer_unittest.cc
+++ b/chromium/third_party/webrtc/test/frame_generator_capturer_unittest.cc
@@ -22,8 +22,8 @@ using ::testing::Property;
class MockVideoSinkInterfaceVideoFrame
: public rtc::VideoSinkInterface<VideoFrame> {
public:
- MOCK_METHOD1(OnFrame, void(const VideoFrame& frame));
- MOCK_METHOD0(OnDiscardedFrame, void());
+ MOCK_METHOD(void, OnFrame, (const VideoFrame& frame), (override));
+ MOCK_METHOD(void, OnDiscardedFrame, (), (override));
};
} // namespace
TEST(FrameGeneratorCapturerTest, CreateFromConfig) {
diff --git a/chromium/third_party/webrtc/test/fuzzers/BUILD.gn b/chromium/third_party/webrtc/test/fuzzers/BUILD.gn
index 96376a2e839..203490f417c 100644
--- a/chromium/third_party/webrtc/test/fuzzers/BUILD.gn
+++ b/chromium/third_party/webrtc/test/fuzzers/BUILD.gn
@@ -40,6 +40,10 @@ rtc_library("fuzz_data_helper") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
}
+set_defaults("webrtc_fuzzer_test") {
+ absl_deps = []
+}
+
template("webrtc_fuzzer_test") {
fuzzer_test(target_name) {
forward_variables_from(invoker, "*")
@@ -47,6 +51,21 @@ template("webrtc_fuzzer_test") {
":fuzz_data_helper",
":webrtc_fuzzer_main",
]
+
+ # If absl_deps is [], no action is needed. If not [], then it needs to be
+ # converted to //third_party/abseil-cpp:absl when build_with_chromium=true
+ # otherwise it just needs to be added to deps.
+ if (absl_deps != []) {
+ if (!defined(deps)) {
+ deps = []
+ }
+ if (build_with_chromium) {
+ deps += [ "//third_party/abseil-cpp:absl" ]
+ } else {
+ deps += absl_deps
+ }
+ }
+
if (!build_with_chromium && is_clang) {
suppressed_configs = [ "//build/config/clang:find_bad_constructs" ]
}
@@ -194,10 +213,8 @@ webrtc_fuzzer_test("rtcp_receiver_fuzzer") {
webrtc_fuzzer_test("rtp_packet_fuzzer") {
sources = [ "rtp_packet_fuzzer.cc" ]
- deps = [
- "../../modules/rtp_rtcp:rtp_rtcp_format",
- "//third_party/abseil-cpp/absl/types:optional",
- ]
+ deps = [ "../../modules/rtp_rtcp:rtp_rtcp_format" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
seed_corpus = "corpora/rtp-corpus"
}
@@ -240,8 +257,8 @@ rtc_library("audio_decoder_fuzzer") {
"../../modules/rtp_rtcp:rtp_rtcp_format",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
webrtc_fuzzer_test("audio_decoder_ilbc_fuzzer") {
@@ -318,7 +335,7 @@ webrtc_fuzzer_test("audio_encoder_opus_fuzzer") {
}
webrtc_fuzzer_test("audio_encoder_isac_fixed_fuzzer") {
- sources = [ "audio_encoder_isax_fixed_fuzzer.cc" ]
+ sources = [ "audio_encoder_isac_fixed_fuzzer.cc" ]
deps = [
":audio_encoder_fuzzer",
"../../api/audio_codecs/isac:audio_encoder_isac_fix",
@@ -327,7 +344,7 @@ webrtc_fuzzer_test("audio_encoder_isac_fixed_fuzzer") {
}
webrtc_fuzzer_test("audio_encoder_isac_float_fuzzer") {
- sources = [ "audio_encoder_isax_float_fuzzer.cc" ]
+ sources = [ "audio_encoder_isac_float_fuzzer.cc" ]
deps = [
":audio_encoder_fuzzer",
"../../api/audio_codecs/isac:audio_encoder_isac_float",
@@ -439,8 +456,8 @@ rtc_library("audio_processing_fuzzer_helper") {
"../../modules/audio_processing:audio_frame_proxies",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
webrtc_fuzzer_test("audio_processing_fuzzer") {
@@ -461,8 +478,8 @@ webrtc_fuzzer_test("audio_processing_fuzzer") {
"../../rtc_base:rtc_task_queue",
"../../rtc_base:safe_minmax",
"../../system_wrappers:field_trial",
- "//third_party/abseil-cpp/absl/memory",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
seed_corpus = "corpora/audio_processing-corpus"
}
diff --git a/chromium/third_party/webrtc/test/logging/BUILD.gn b/chromium/third_party/webrtc/test/logging/BUILD.gn
index db2a5447ac9..1af2ecfdac2 100644
--- a/chromium/third_party/webrtc/test/logging/BUILD.gn
+++ b/chromium/third_party/webrtc/test/logging/BUILD.gn
@@ -27,6 +27,6 @@ rtc_library("log_writer") {
"../../rtc_base:rtc_base_tests_utils",
"../../rtc_base:stringutils",
"../../test:fileutils",
- "//third_party/abseil-cpp/absl/types:optional",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
diff --git a/chromium/third_party/webrtc/test/mock_audio_decoder.h b/chromium/third_party/webrtc/test/mock_audio_decoder.h
index 7c6db5acc22..8f44bf891d5 100644
--- a/chromium/third_party/webrtc/test/mock_audio_decoder.h
+++ b/chromium/third_party/webrtc/test/mock_audio_decoder.h
@@ -20,16 +20,18 @@ class MockAudioDecoder : public AudioDecoder {
public:
MockAudioDecoder();
~MockAudioDecoder();
- MOCK_METHOD0(Die, void());
- MOCK_METHOD5(DecodeInternal,
- int(const uint8_t*, size_t, int, int16_t*, SpeechType*));
- MOCK_CONST_METHOD0(HasDecodePlc, bool());
- MOCK_METHOD2(DecodePlc, size_t(size_t, int16_t*));
- MOCK_METHOD0(Reset, void());
- MOCK_METHOD0(ErrorCode, int());
- MOCK_CONST_METHOD2(PacketDuration, int(const uint8_t*, size_t));
- MOCK_CONST_METHOD0(Channels, size_t());
- MOCK_CONST_METHOD0(SampleRateHz, int());
+ MOCK_METHOD(void, Die, ());
+ MOCK_METHOD(int,
+ DecodeInternal,
+ (const uint8_t*, size_t, int, int16_t*, SpeechType*),
+ (override));
+ MOCK_METHOD(bool, HasDecodePlc, (), (const, override));
+ MOCK_METHOD(size_t, DecodePlc, (size_t, int16_t*), (override));
+ MOCK_METHOD(void, Reset, (), (override));
+ MOCK_METHOD(int, ErrorCode, (), (override));
+ MOCK_METHOD(int, PacketDuration, (const uint8_t*, size_t), (const, override));
+ MOCK_METHOD(size_t, Channels, (), (const, override));
+ MOCK_METHOD(int, SampleRateHz, (), (const, override));
};
} // namespace webrtc
diff --git a/chromium/third_party/webrtc/test/mock_audio_decoder_factory.h b/chromium/third_party/webrtc/test/mock_audio_decoder_factory.h
index cdf29195433..cdb03d3f380 100644
--- a/chromium/third_party/webrtc/test/mock_audio_decoder_factory.h
+++ b/chromium/third_party/webrtc/test/mock_audio_decoder_factory.h
@@ -24,19 +24,23 @@ namespace webrtc {
class MockAudioDecoderFactory : public AudioDecoderFactory {
public:
- MOCK_METHOD0(GetSupportedDecoders, std::vector<AudioCodecSpec>());
- MOCK_METHOD1(IsSupportedDecoder, bool(const SdpAudioFormat&));
+ MOCK_METHOD(std::vector<AudioCodecSpec>,
+ GetSupportedDecoders,
+ (),
+ (override));
+ MOCK_METHOD(bool, IsSupportedDecoder, (const SdpAudioFormat&), (override));
std::unique_ptr<AudioDecoder> MakeAudioDecoder(
const SdpAudioFormat& format,
- absl::optional<AudioCodecPairId> codec_pair_id) {
+ absl::optional<AudioCodecPairId> codec_pair_id) override {
std::unique_ptr<AudioDecoder> return_value;
MakeAudioDecoderMock(format, codec_pair_id, &return_value);
return return_value;
}
- MOCK_METHOD3(MakeAudioDecoderMock,
- void(const SdpAudioFormat& format,
- absl::optional<AudioCodecPairId> codec_pair_id,
- std::unique_ptr<AudioDecoder>* return_value));
+ MOCK_METHOD(void,
+ MakeAudioDecoderMock,
+ (const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id,
+ std::unique_ptr<AudioDecoder>*));
// Creates a MockAudioDecoderFactory with no formats and that may not be
// invoked to create a codec - useful for initializing a voice engine, for
diff --git a/chromium/third_party/webrtc/test/mock_audio_encoder.h b/chromium/third_party/webrtc/test/mock_audio_encoder.h
index 2dfd15ca981..9d9db0d66cd 100644
--- a/chromium/third_party/webrtc/test/mock_audio_encoder.h
+++ b/chromium/third_party/webrtc/test/mock_audio_encoder.h
@@ -27,37 +27,44 @@ class MockAudioEncoder : public AudioEncoder {
// http://crbug.com/428099.
MockAudioEncoder();
~MockAudioEncoder();
- MOCK_METHOD1(Mark, void(std::string desc));
- MOCK_CONST_METHOD0(SampleRateHz, int());
- MOCK_CONST_METHOD0(NumChannels, size_t());
- MOCK_CONST_METHOD0(RtpTimestampRateHz, int());
- MOCK_CONST_METHOD0(Num10MsFramesInNextPacket, size_t());
- MOCK_CONST_METHOD0(Max10MsFramesInAPacket, size_t());
- MOCK_CONST_METHOD0(GetTargetBitrate, int());
- MOCK_CONST_METHOD0(GetFrameLengthRange,
- absl::optional<std::pair<TimeDelta, TimeDelta>>());
-
- MOCK_METHOD0(Reset, void());
- MOCK_METHOD1(SetFec, bool(bool enable));
- MOCK_METHOD1(SetDtx, bool(bool enable));
- MOCK_METHOD1(SetApplication, bool(Application application));
- MOCK_METHOD1(SetMaxPlaybackRate, void(int frequency_hz));
- MOCK_METHOD1(SetMaxBitrate, void(int max_bps));
- MOCK_METHOD1(SetMaxPayloadSize, void(int max_payload_size_bytes));
- MOCK_METHOD2(OnReceivedUplinkBandwidth,
- void(int target_audio_bitrate_bps,
- absl::optional<int64_t> probing_interval_ms));
- MOCK_METHOD1(OnReceivedUplinkPacketLossFraction,
- void(float uplink_packet_loss_fraction));
-
- MOCK_METHOD2(EnableAudioNetworkAdaptor,
- bool(const std::string& config_string, RtcEventLog* event_log));
+ MOCK_METHOD(int, SampleRateHz, (), (const, override));
+ MOCK_METHOD(size_t, NumChannels, (), (const, override));
+ MOCK_METHOD(int, RtpTimestampRateHz, (), (const, override));
+ MOCK_METHOD(size_t, Num10MsFramesInNextPacket, (), (const, override));
+ MOCK_METHOD(size_t, Max10MsFramesInAPacket, (), (const, override));
+ MOCK_METHOD(int, GetTargetBitrate, (), (const, override));
+ MOCK_METHOD((absl::optional<std::pair<TimeDelta, TimeDelta>>),
+ GetFrameLengthRange,
+ (),
+ (const, override));
+
+ MOCK_METHOD(void, Reset, (), (override));
+ MOCK_METHOD(bool, SetFec, (bool enable), (override));
+ MOCK_METHOD(bool, SetDtx, (bool enable), (override));
+ MOCK_METHOD(bool, SetApplication, (Application application), (override));
+ MOCK_METHOD(void, SetMaxPlaybackRate, (int frequency_hz), (override));
+ MOCK_METHOD(void,
+ OnReceivedUplinkBandwidth,
+ (int target_audio_bitrate_bps,
+ absl::optional<int64_t> probing_interval_ms),
+ (override));
+ MOCK_METHOD(void,
+ OnReceivedUplinkPacketLossFraction,
+ (float uplink_packet_loss_fraction),
+ (override));
+
+ MOCK_METHOD(bool,
+ EnableAudioNetworkAdaptor,
+ (const std::string& config_string, RtcEventLog*),
+ (override));
// Note, we explicitly chose not to create a mock for the Encode method.
- MOCK_METHOD3(EncodeImpl,
- EncodedInfo(uint32_t timestamp,
- rtc::ArrayView<const int16_t> audio,
- rtc::Buffer* encoded));
+ MOCK_METHOD(EncodedInfo,
+ EncodeImpl,
+ (uint32_t timestamp,
+ rtc::ArrayView<const int16_t> audio,
+ rtc::Buffer*),
+ (override));
class FakeEncoding {
public:
diff --git a/chromium/third_party/webrtc/test/mock_audio_encoder_factory.h b/chromium/third_party/webrtc/test/mock_audio_encoder_factory.h
index 3e774a39e9d..392a4c11e2e 100644
--- a/chromium/third_party/webrtc/test/mock_audio_encoder_factory.h
+++ b/chromium/third_party/webrtc/test/mock_audio_encoder_factory.h
@@ -24,23 +24,29 @@ namespace webrtc {
class MockAudioEncoderFactory
: public ::testing::NiceMock<AudioEncoderFactory> {
public:
- MOCK_METHOD0(GetSupportedEncoders, std::vector<AudioCodecSpec>());
- MOCK_METHOD1(QueryAudioEncoder,
- absl::optional<AudioCodecInfo>(const SdpAudioFormat& format));
+ MOCK_METHOD(std::vector<AudioCodecSpec>,
+ GetSupportedEncoders,
+ (),
+ (override));
+ MOCK_METHOD(absl::optional<AudioCodecInfo>,
+ QueryAudioEncoder,
+ (const SdpAudioFormat& format),
+ (override));
std::unique_ptr<AudioEncoder> MakeAudioEncoder(
int payload_type,
const SdpAudioFormat& format,
- absl::optional<AudioCodecPairId> codec_pair_id) {
+ absl::optional<AudioCodecPairId> codec_pair_id) override {
std::unique_ptr<AudioEncoder> return_value;
MakeAudioEncoderMock(payload_type, format, codec_pair_id, &return_value);
return return_value;
}
- MOCK_METHOD4(MakeAudioEncoderMock,
- void(int payload_type,
- const SdpAudioFormat& format,
- absl::optional<AudioCodecPairId> codec_pair_id,
- std::unique_ptr<AudioEncoder>* return_value));
+ MOCK_METHOD(void,
+ MakeAudioEncoderMock,
+ (int payload_type,
+ const SdpAudioFormat& format,
+ absl::optional<AudioCodecPairId> codec_pair_id,
+ std::unique_ptr<AudioEncoder>*));
// Creates a MockAudioEncoderFactory with no formats and that may not be
// invoked to create a codec - useful for initializing a voice engine, for
diff --git a/chromium/third_party/webrtc/test/mock_transport.h b/chromium/third_party/webrtc/test/mock_transport.h
index 5ffc10425b6..9c4dc4bf8dc 100644
--- a/chromium/third_party/webrtc/test/mock_transport.h
+++ b/chromium/third_party/webrtc/test/mock_transport.h
@@ -25,7 +25,7 @@ class MockTransport : public Transport {
SendRtp,
(const uint8_t*, size_t, const PacketOptions&),
(override));
- MOCK_METHOD(bool, SendRtcp, (const uint8_t* data, size_t len), (override));
+ MOCK_METHOD(bool, SendRtcp, (const uint8_t*, size_t len), (override));
};
} // namespace webrtc
diff --git a/chromium/third_party/webrtc/test/network/BUILD.gn b/chromium/third_party/webrtc/test/network/BUILD.gn
index 4b01479c9b6..9e810bfc530 100644
--- a/chromium/third_party/webrtc/test/network/BUILD.gn
+++ b/chromium/third_party/webrtc/test/network/BUILD.gn
@@ -54,6 +54,8 @@ rtc_library("emulated_network") {
"../../system_wrappers",
"../scenario:column_printer",
"../time_controller",
+ ]
+ absl_deps = [
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:optional",
@@ -114,8 +116,8 @@ rtc_library("cross_traffic_unittest") {
"../../rtc_base:logging",
"../../rtc_base:rtc_event",
"//test/time_controller:time_controller",
- "//third_party/abseil-cpp/absl/memory",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
}
rtc_library("feedback_generator") {
@@ -130,8 +132,8 @@ rtc_library("feedback_generator") {
"../../call:simulated_network",
"../../rtc_base:checks",
"../time_controller",
- "//third_party/abseil-cpp/absl/memory",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
}
rtc_library("feedback_generator_unittest") {
diff --git a/chromium/third_party/webrtc/test/network/cross_traffic.cc b/chromium/third_party/webrtc/test/network/cross_traffic.cc
index be0c3d32863..56e7635142e 100644
--- a/chromium/third_party/webrtc/test/network/cross_traffic.cc
+++ b/chromium/third_party/webrtc/test/network/cross_traffic.cc
@@ -144,15 +144,16 @@ void TcpMessageRouteImpl::SendMessage(size_t size,
cwnd_ = 10;
ssthresh_ = INFINITY;
}
- size_t data_left = size;
- size_t kMaxPacketSize = 1200;
- size_t kMinPacketSize = 4;
+ int64_t data_left = static_cast<int64_t>(size);
+ int64_t kMaxPacketSize = 1200;
+ int64_t kMinPacketSize = 4;
Message message{std::move(handler)};
while (data_left > 0) {
- size_t packet_size =
- std::max(kMinPacketSize, std::min(data_left, kMaxPacketSize));
+ int64_t packet_size = std::min(data_left, kMaxPacketSize);
int fragment_id = next_fragment_id_++;
- pending_.push_back(MessageFragment{fragment_id, packet_size});
+ pending_.push_back(MessageFragment{
+ fragment_id,
+ static_cast<size_t>(std::max(kMinPacketSize, packet_size))});
message.pending_fragment_ids.insert(fragment_id);
data_left -= packet_size;
}
diff --git a/chromium/third_party/webrtc/test/network/network_emulation_unittest.cc b/chromium/third_party/webrtc/test/network/network_emulation_unittest.cc
index 58346abb93c..9e630de9cb9 100644
--- a/chromium/third_party/webrtc/test/network/network_emulation_unittest.cc
+++ b/chromium/third_party/webrtc/test/network/network_emulation_unittest.cc
@@ -70,7 +70,7 @@ class SocketReader : public sigslot::has_slots<> {
class MockReceiver : public EmulatedNetworkReceiverInterface {
public:
- MOCK_METHOD1(OnPacketReceived, void(EmulatedIpPacket packet));
+ MOCK_METHOD(void, OnPacketReceived, (EmulatedIpPacket packet), (override));
};
class NetworkEmulationManagerThreeNodesRoutingTest : public ::testing::Test {
diff --git a/chromium/third_party/webrtc/test/pc/e2e/BUILD.gn b/chromium/third_party/webrtc/test/pc/e2e/BUILD.gn
index d340f1a00cc..fea59bcb87e 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/BUILD.gn
+++ b/chromium/third_party/webrtc/test/pc/e2e/BUILD.gn
@@ -8,632 +8,681 @@
import("../../../webrtc.gni")
-group("e2e") {
- testonly = true
-
- deps = [
- ":default_encoded_image_data_injector",
- ":encoded_image_data_injector_api",
- ":example_video_quality_analyzer",
- ":id_generator",
- ":quality_analyzing_video_decoder",
- ":quality_analyzing_video_encoder",
- ":single_process_encoded_image_data_injector",
- ]
- if (rtc_include_tests) {
- deps += [
- ":peerconnection_quality_test",
- ":test_peer",
- ":video_quality_analyzer_injection_helper",
- ]
- }
-}
-
-if (rtc_include_tests) {
- group("e2e_unittests") {
+if (!build_with_chromium) {
+ group("e2e") {
testonly = true
deps = [
- ":default_encoded_image_data_injector_unittest",
- ":default_video_quality_analyzer_test",
- ":peer_connection_e2e_smoke_test",
- ":single_process_encoded_image_data_injector_unittest",
+ ":default_encoded_image_data_injector",
+ ":encoded_image_data_injector_api",
+ ":example_video_quality_analyzer",
+ ":id_generator",
+ ":quality_analyzing_video_decoder",
+ ":quality_analyzing_video_encoder",
+ ":single_process_encoded_image_data_injector",
]
+ if (rtc_include_tests) {
+ deps += [
+ ":peerconnection_quality_test",
+ ":test_peer",
+ ":video_quality_analyzer_injection_helper",
+ ]
+ }
}
-}
-
-rtc_library("peer_connection_quality_test_params") {
- visibility = [ "*" ]
- testonly = true
- sources = [ "peer_connection_quality_test_params.h" ]
-
- deps = [
- "../../../api:callfactory_api",
- "../../../api:fec_controller_api",
- "../../../api:libjingle_peerconnection_api",
- "../../../api:packet_socket_factory",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../api/rtc_event_log",
- "../../../api/task_queue",
- "../../../api/transport:network_control",
- "../../../api/transport/media:media_transport_interface",
- "../../../api/video_codecs:video_codecs_api",
- "../../../rtc_base",
- ]
-}
-
-rtc_library("encoded_image_data_injector_api") {
- visibility = [ "*" ]
- testonly = true
- sources = [ "analyzer/video/encoded_image_data_injector.h" ]
-
- deps = [ "../../../api/video:encoded_image" ]
-}
-rtc_library("default_encoded_image_data_injector") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/video/default_encoded_image_data_injector.cc",
- "analyzer/video/default_encoded_image_data_injector.h",
- ]
-
- deps = [
- ":encoded_image_data_injector_api",
- "../../../api/video:encoded_image",
- "../../../rtc_base:checks",
- "../../../rtc_base:criticalsection",
- "//third_party/abseil-cpp/absl/memory",
- ]
-}
+ if (rtc_include_tests) {
+ group("e2e_unittests") {
+ testonly = true
-rtc_library("single_process_encoded_image_data_injector") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/video/single_process_encoded_image_data_injector.cc",
- "analyzer/video/single_process_encoded_image_data_injector.h",
- ]
-
- deps = [
- ":encoded_image_data_injector_api",
- "../../../api/video:encoded_image",
- "../../../rtc_base:checks",
- "../../../rtc_base:criticalsection",
- "//third_party/abseil-cpp/absl/memory",
- ]
-}
+ deps = [
+ ":default_encoded_image_data_injector_unittest",
+ ":default_video_quality_analyzer_test",
+ ":multi_head_queue_test",
+ ":peer_connection_e2e_smoke_test",
+ ":single_process_encoded_image_data_injector_unittest",
+ ]
+ }
+ }
-rtc_library("id_generator") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/video/id_generator.cc",
- "analyzer/video/id_generator.h",
- ]
- deps = []
-}
+ rtc_library("peer_connection_quality_test_params") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "peer_connection_quality_test_params.h" ]
-rtc_library("simulcast_dummy_buffer_helper") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/video/simulcast_dummy_buffer_helper.cc",
- "analyzer/video/simulcast_dummy_buffer_helper.h",
- ]
- deps = [
- "../../../api/video:video_frame",
- "../../../api/video:video_frame_i420",
- ]
-}
+ deps = [
+ "../../../api:callfactory_api",
+ "../../../api:fec_controller_api",
+ "../../../api:libjingle_peerconnection_api",
+ "../../../api:packet_socket_factory",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api/rtc_event_log",
+ "../../../api/task_queue",
+ "../../../api/transport:network_control",
+ "../../../api/video_codecs:video_codecs_api",
+ "../../../rtc_base",
+ ]
+ }
-rtc_library("quality_analyzing_video_decoder") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/video/quality_analyzing_video_decoder.cc",
- "analyzer/video/quality_analyzing_video_decoder.h",
- ]
- deps = [
- ":encoded_image_data_injector_api",
- ":id_generator",
- ":simulcast_dummy_buffer_helper",
- "../../../api:video_quality_analyzer_api",
- "../../../api/video:encoded_image",
- "../../../api/video:video_frame",
- "../../../api/video:video_frame_i420",
- "../../../api/video:video_rtp_headers",
- "../../../api/video_codecs:video_codecs_api",
- "../../../modules/video_coding:video_codec_interface",
- "../../../rtc_base:criticalsection",
- "../../../rtc_base:logging",
- "//third_party/abseil-cpp/absl/types:optional",
- ]
-}
+ rtc_library("encoded_image_data_injector_api") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [ "analyzer/video/encoded_image_data_injector.h" ]
-rtc_library("quality_analyzing_video_encoder") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/video/quality_analyzing_video_encoder.cc",
- "analyzer/video/quality_analyzing_video_encoder.h",
- ]
- deps = [
- ":encoded_image_data_injector_api",
- ":id_generator",
- "../../../api:video_quality_analyzer_api",
- "../../../api/video:encoded_image",
- "../../../api/video:video_frame",
- "../../../api/video:video_rtp_headers",
- "../../../api/video_codecs:video_codecs_api",
- "../../../modules/video_coding:video_codec_interface",
- "../../../rtc_base:criticalsection",
- "../../../rtc_base:logging",
- ]
-}
+ deps = [ "../../../api/video:encoded_image" ]
+ }
-if (rtc_include_tests) {
- rtc_library("video_quality_analyzer_injection_helper") {
+ rtc_library("default_encoded_image_data_injector") {
visibility = [ "*" ]
testonly = true
sources = [
- "analyzer/video/video_quality_analyzer_injection_helper.cc",
- "analyzer/video/video_quality_analyzer_injection_helper.h",
+ "analyzer/video/default_encoded_image_data_injector.cc",
+ "analyzer/video/default_encoded_image_data_injector.h",
]
+
deps = [
":encoded_image_data_injector_api",
- ":id_generator",
- ":quality_analyzing_video_decoder",
- ":quality_analyzing_video_encoder",
- ":simulcast_dummy_buffer_helper",
- "../..:test_renderer",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../api:stats_observer_interface",
- "../../../api:video_quality_analyzer_api",
- "../../../api/video:video_frame",
- "../../../api/video:video_rtp_headers",
- "../../../api/video_codecs:video_codecs_api",
+ "../../../api/video:encoded_image",
+ "../../../rtc_base:checks",
"../../../rtc_base:criticalsection",
- "../../../test:video_test_common",
- "../../../test:video_test_support",
- "//third_party/abseil-cpp/absl/memory",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
}
- rtc_library("echo_emulation") {
+ rtc_library("single_process_encoded_image_data_injector") {
visibility = [ "*" ]
testonly = true
sources = [
- "echo/echo_emulation.cc",
- "echo/echo_emulation.h",
+ "analyzer/video/single_process_encoded_image_data_injector.cc",
+ "analyzer/video/single_process_encoded_image_data_injector.h",
]
+
deps = [
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../modules/audio_device:audio_device_impl",
- "../../../rtc_base:rtc_base_approved",
+ ":encoded_image_data_injector_api",
+ "../../../api/video:encoded_image",
+ "../../../rtc_base:checks",
+ "../../../rtc_base:criticalsection",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/memory" ]
}
- rtc_library("test_peer") {
+ rtc_library("id_generator") {
visibility = [ "*" ]
testonly = true
sources = [
- "test_peer.cc",
- "test_peer.h",
+ "analyzer/video/id_generator.cc",
+ "analyzer/video/id_generator.h",
+ ]
+ deps = []
+ }
+
+ rtc_library("simulcast_dummy_buffer_helper") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "analyzer/video/simulcast_dummy_buffer_helper.cc",
+ "analyzer/video/simulcast_dummy_buffer_helper.h",
]
deps = [
- ":peer_configurer",
- ":peer_connection_quality_test_params",
- "../../../api:frame_generator_api",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../api:scoped_refptr",
- "../../../modules/audio_processing:api",
- "../../../pc:peerconnection_wrapper",
- "//third_party/abseil-cpp/absl/memory",
- "//third_party/abseil-cpp/absl/types:variant",
+ "../../../api/video:video_frame",
+ "../../../api/video:video_frame_i420",
]
}
- rtc_library("test_peer_factory") {
+ rtc_library("quality_analyzing_video_decoder") {
visibility = [ "*" ]
testonly = true
sources = [
- "test_peer_factory.cc",
- "test_peer_factory.h",
+ "analyzer/video/quality_analyzing_video_decoder.cc",
+ "analyzer/video/quality_analyzing_video_decoder.h",
]
deps = [
- ":echo_emulation",
- ":peer_configurer",
- ":peer_connection_quality_test_params",
- ":quality_analyzing_video_encoder",
- ":test_peer",
- ":video_quality_analyzer_injection_helper",
- "../..:copy_to_file_audio_capturer",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../api/rtc_event_log:rtc_event_log_factory",
- "../../../api/task_queue:default_task_queue_factory",
- "../../../api/video_codecs:builtin_video_decoder_factory",
- "../../../api/video_codecs:builtin_video_encoder_factory",
- "../../../media:rtc_audio_video",
- "../../../media:rtc_media_engine_defaults",
- "../../../modules/audio_device:audio_device_impl",
- "../../../modules/audio_processing/aec_dump",
- "../../../p2p:rtc_p2p",
- "../../../rtc_base:rtc_task_queue",
- "//third_party/abseil-cpp/absl/memory",
+ ":encoded_image_data_injector_api",
+ ":id_generator",
+ ":simulcast_dummy_buffer_helper",
+ "../../../api:video_quality_analyzer_api",
+ "../../../api/video:encoded_image",
+ "../../../api/video:video_frame",
+ "../../../api/video:video_frame_i420",
+ "../../../api/video:video_rtp_headers",
+ "../../../api/video_codecs:video_codecs_api",
+ "../../../modules/video_coding:video_codec_interface",
+ "../../../rtc_base:criticalsection",
+ "../../../rtc_base:logging",
+ ]
+ absl_deps = [
"//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/types:optional",
]
}
- rtc_library("media_helper") {
+ rtc_library("quality_analyzing_video_encoder") {
visibility = [ "*" ]
testonly = true
sources = [
- "media/media_helper.cc",
- "media/media_helper.h",
- "media/test_video_capturer_video_track_source.h",
+ "analyzer/video/quality_analyzing_video_encoder.cc",
+ "analyzer/video/quality_analyzing_video_encoder.h",
]
deps = [
- ":peer_configurer",
- ":test_peer",
- ":video_quality_analyzer_injection_helper",
- "../..:fileutils",
- "../..:platform_video_capturer",
- "../..:video_test_common",
- "../../../api:create_frame_generator",
- "../../../api:frame_generator_api",
- "../../../api:media_stream_interface",
- "../../../api:peer_connection_quality_test_fixture_api",
+ ":encoded_image_data_injector_api",
+ ":id_generator",
+ "../../../api:video_quality_analyzer_api",
+ "../../../api/video:encoded_image",
"../../../api/video:video_frame",
- "../../../pc:peerconnection",
- "//third_party/abseil-cpp/absl/types:variant",
+ "../../../api/video:video_rtp_headers",
+ "../../../api/video_codecs:video_codecs_api",
+ "../../../modules/video_coding:video_codec_interface",
+ "../../../rtc_base:criticalsection",
+ "../../../rtc_base:logging",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+ }
+
+ if (rtc_include_tests) {
+ rtc_library("video_quality_analyzer_injection_helper") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "analyzer/video/video_quality_analyzer_injection_helper.cc",
+ "analyzer/video/video_quality_analyzer_injection_helper.h",
+ ]
+ deps = [
+ ":encoded_image_data_injector_api",
+ ":id_generator",
+ ":quality_analyzing_video_decoder",
+ ":quality_analyzing_video_encoder",
+ ":simulcast_dummy_buffer_helper",
+ "../..:test_renderer",
+ "../../../api:array_view",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api:stats_observer_interface",
+ "../../../api:video_quality_analyzer_api",
+ "../../../api/video:video_frame",
+ "../../../api/video:video_rtp_headers",
+ "../../../api/video_codecs:video_codecs_api",
+ "../../../rtc_base:criticalsection",
+ "../../../test:video_test_common",
+ "../../../test:video_test_support",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+ }
+
+ rtc_library("echo_emulation") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "echo/echo_emulation.cc",
+ "echo/echo_emulation.h",
+ ]
+ deps = [
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../modules/audio_device:audio_device_impl",
+ "../../../rtc_base:rtc_base_approved",
+ ]
+ }
+
+ rtc_library("test_peer") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test_peer.cc",
+ "test_peer.h",
+ ]
+ deps = [
+ ":peer_configurer",
+ ":peer_connection_quality_test_params",
+ "../../../api:frame_generator_api",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api:scoped_refptr",
+ "../../../modules/audio_processing:api",
+ "../../../pc:peerconnection_wrapper",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/types:variant",
+ ]
+ }
+
+ rtc_library("test_peer_factory") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test_peer_factory.cc",
+ "test_peer_factory.h",
+ ]
+ deps = [
+ ":echo_emulation",
+ ":peer_configurer",
+ ":peer_connection_quality_test_params",
+ ":quality_analyzing_video_encoder",
+ ":test_peer",
+ ":video_quality_analyzer_injection_helper",
+ "../..:copy_to_file_audio_capturer",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api/rtc_event_log:rtc_event_log_factory",
+ "../../../api/task_queue:default_task_queue_factory",
+ "../../../api/video_codecs:builtin_video_decoder_factory",
+ "../../../api/video_codecs:builtin_video_encoder_factory",
+ "../../../media:rtc_audio_video",
+ "../../../media:rtc_media_engine_defaults",
+ "../../../modules/audio_device:audio_device_impl",
+ "../../../modules/audio_processing/aec_dump",
+ "../../../p2p:rtc_p2p",
+ "../../../rtc_base:rtc_task_queue",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+ }
+
+ rtc_library("media_helper") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "media/media_helper.cc",
+ "media/media_helper.h",
+ "media/test_video_capturer_video_track_source.h",
+ ]
+ deps = [
+ ":peer_configurer",
+ ":test_peer",
+ ":video_quality_analyzer_injection_helper",
+ "../..:fileutils",
+ "../..:platform_video_capturer",
+ "../..:video_test_common",
+ "../../../api:create_frame_generator",
+ "../../../api:frame_generator_api",
+ "../../../api:media_stream_interface",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api/video:video_frame",
+ "../../../pc:peerconnection",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:variant" ]
+ }
+
+ rtc_library("peer_configurer") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "peer_configurer.cc",
+ "peer_configurer.h",
+ ]
+ deps = [
+ ":peer_connection_quality_test_params",
+ "../..:fileutils",
+ "../../../api:callfactory_api",
+ "../../../api:create_peer_connection_quality_test_frame_generator",
+ "../../../api:fec_controller_api",
+ "../../../api:packet_socket_factory",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api/rtc_event_log",
+ "../../../api/task_queue",
+ "../../../api/transport:network_control",
+ "../../../api/video_codecs:video_codecs_api",
+ "../../../rtc_base",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+ }
+
+ rtc_library("test_activities_executor") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "test_activities_executor.cc",
+ "test_activities_executor.h",
+ ]
+ deps = [
+ "../../../api/units:time_delta",
+ "../../../api/units:timestamp",
+ "../../../rtc_base:checks",
+ "../../../rtc_base:criticalsection",
+ "../../../rtc_base:logging",
+ "../../../rtc_base:rtc_base_approved",
+ "../../../rtc_base:task_queue_for_test",
+ "../../../rtc_base/task_utils:repeating_task",
+ "../../../system_wrappers",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/types:optional",
+ ]
+ }
+
+ rtc_library("peerconnection_quality_test") {
+ visibility = [ "*" ]
+ testonly = true
+
+ sources = [
+ "peer_connection_quality_test.cc",
+ "peer_connection_quality_test.h",
+ ]
+ deps = [
+ ":analyzer_helper",
+ ":default_audio_quality_analyzer",
+ ":default_video_quality_analyzer",
+ ":media_helper",
+ ":peer_configurer",
+ ":peer_connection_quality_test_params",
+ ":sdp_changer",
+ ":single_process_encoded_image_data_injector",
+ ":stats_poller",
+ ":test_activities_executor",
+ ":test_peer",
+ ":test_peer_factory",
+ ":video_quality_analyzer_injection_helper",
+ ":video_quality_metrics_reporter",
+ "../..:field_trial",
+ "../..:fileutils",
+ "../..:perf_test",
+ "../../../api:audio_quality_analyzer_api",
+ "../../../api:libjingle_peerconnection_api",
+ "../../../api:media_stream_interface",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api:rtc_event_log_output_file",
+ "../../../api:scoped_refptr",
+ "../../../api:video_quality_analyzer_api",
+ "../../../api/rtc_event_log",
+ "../../../api/task_queue",
+ "../../../api/task_queue:default_task_queue_factory",
+ "../../../api/units:time_delta",
+ "../../../api/units:timestamp",
+ "../../../pc:pc_test_utils",
+ "../../../pc:peerconnection",
+ "../../../rtc_base",
+ "../../../rtc_base:gunit_helpers",
+ "../../../rtc_base:macromagic",
+ "../../../rtc_base:rtc_base_approved",
+ "../../../rtc_base:safe_conversions",
+ "../../../rtc_base:task_queue_for_test",
+ "../../../system_wrappers",
+ "../../../system_wrappers:field_trial",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
+ }
+
+ rtc_library("single_process_encoded_image_data_injector_unittest") {
+ testonly = true
+ sources = [
+ "analyzer/video/single_process_encoded_image_data_injector_unittest.cc",
+ ]
+ deps = [
+ ":single_process_encoded_image_data_injector",
+ "../../../api/video:encoded_image",
+ "../../../rtc_base:rtc_base_approved",
+ "../../../test:test_support",
+ ]
+ }
+
+ rtc_library("default_encoded_image_data_injector_unittest") {
+ testonly = true
+ sources =
+ [ "analyzer/video/default_encoded_image_data_injector_unittest.cc" ]
+ deps = [
+ ":default_encoded_image_data_injector",
+ "../../../api/video:encoded_image",
+ "../../../rtc_base:rtc_base_approved",
+ "../../../test:test_support",
+ ]
+ }
+
+ peer_connection_e2e_smoke_test_resources = [
+ "../../../resources/pc_quality_smoke_test_alice_source.wav",
+ "../../../resources/pc_quality_smoke_test_bob_source.wav",
]
+ if (is_ios) {
+ bundle_data("peer_connection_e2e_smoke_test_resources_bundle_data") {
+ testonly = true
+ sources = peer_connection_e2e_smoke_test_resources
+ outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
+ }
+ }
+
+ rtc_library("peer_connection_e2e_smoke_test") {
+ testonly = true
+
+ sources = [ "peer_connection_e2e_smoke_test.cc" ]
+ deps = [
+ ":default_audio_quality_analyzer",
+ ":default_video_quality_analyzer",
+ ":network_quality_metrics_reporter",
+ "../../../api:callfactory_api",
+ "../../../api:create_network_emulation_manager",
+ "../../../api:create_peer_connection_quality_test_frame_generator",
+ "../../../api:create_peerconnection_quality_test_fixture",
+ "../../../api:libjingle_peerconnection_api",
+ "../../../api:media_stream_interface",
+ "../../../api:network_emulation_manager_api",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api:scoped_refptr",
+ "../../../api:simulated_network_api",
+ "../../../api/audio_codecs:builtin_audio_decoder_factory",
+ "../../../api/audio_codecs:builtin_audio_encoder_factory",
+ "../../../api/video_codecs:builtin_video_decoder_factory",
+ "../../../api/video_codecs:builtin_video_encoder_factory",
+ "../../../call:simulated_network",
+ "../../../media:rtc_audio_video",
+ "../../../modules/audio_device:audio_device_impl",
+ "../../../p2p:rtc_p2p",
+ "../../../pc:pc_test_utils",
+ "../../../pc:peerconnection_wrapper",
+ "../../../rtc_base",
+ "../../../rtc_base:gunit_helpers",
+ "../../../rtc_base:logging",
+ "../../../rtc_base:rtc_event",
+ "../../../system_wrappers:field_trial",
+ "../../../test:field_trial",
+ "../../../test:fileutils",
+ "../../../test:test_support",
+ ]
+ data = peer_connection_e2e_smoke_test_resources
+ if (is_ios) {
+ deps += [ ":peer_connection_e2e_smoke_test_resources_bundle_data" ]
+ }
+ }
+
+ rtc_library("stats_poller") {
+ visibility = [ "*" ]
+ testonly = true
+ sources = [
+ "stats_poller.cc",
+ "stats_poller.h",
+ ]
+ deps = [
+ ":test_peer",
+ "../../../api:libjingle_peerconnection_api",
+ "../../../api:rtc_stats_api",
+ "../../../api:stats_observer_interface",
+ "../../../rtc_base:logging",
+ ]
+ }
+
+ rtc_library("default_video_quality_analyzer_test") {
+ testonly = true
+ sources = [ "analyzer/video/default_video_quality_analyzer_test.cc" ]
+ deps = [
+ ":default_video_quality_analyzer",
+ "../..:test_support",
+ "../../../api:create_frame_generator",
+ "../../../api:rtp_packet_info",
+ "../../../api/video:encoded_image",
+ "../../../api/video:video_frame",
+ "../../../api/video:video_frame_i420",
+ "../../../modules/rtp_rtcp:rtp_rtcp_format",
+ "../../../rtc_base:stringutils",
+ "../../../system_wrappers",
+ ]
+ }
+
+ rtc_library("multi_head_queue_test") {
+ testonly = true
+ sources = [ "analyzer/video/multi_head_queue_test.cc" ]
+ deps = [
+ ":multi_head_queue",
+ "../../../test:test_support",
+ ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
+ }
}
- rtc_library("peer_configurer") {
+ rtc_library("analyzer_helper") {
visibility = [ "*" ]
- testonly = true
sources = [
- "peer_configurer.cc",
- "peer_configurer.h",
+ "analyzer_helper.cc",
+ "analyzer_helper.h",
]
deps = [
- ":peer_connection_quality_test_params",
- "../..:fileutils",
- "../../../api:callfactory_api",
- "../../../api:create_peer_connection_quality_test_frame_generator",
- "../../../api:fec_controller_api",
- "../../../api:packet_socket_factory",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../api/rtc_event_log",
- "../../../api/task_queue",
- "../../../api/transport:network_control",
- "../../../api/transport/media:media_transport_interface",
- "../../../api/video_codecs:video_codecs_api",
- "../../../rtc_base",
- "//third_party/abseil-cpp/absl/strings",
+ "../../../api:track_id_stream_label_map",
+ "../../../rtc_base:macromagic",
+ "../../../rtc_base/synchronization:sequence_checker",
]
}
- rtc_library("test_activities_executor") {
+ rtc_library("default_audio_quality_analyzer") {
visibility = [ "*" ]
testonly = true
sources = [
- "test_activities_executor.cc",
- "test_activities_executor.h",
+ "analyzer/audio/default_audio_quality_analyzer.cc",
+ "analyzer/audio/default_audio_quality_analyzer.h",
]
+
deps = [
+ "../..:perf_test",
+ "../../../api:audio_quality_analyzer_api",
+ "../../../api:rtc_stats_api",
+ "../../../api:stats_observer_interface",
+ "../../../api:track_id_stream_label_map",
"../../../api/units:time_delta",
"../../../api/units:timestamp",
- "../../../rtc_base:checks",
"../../../rtc_base:criticalsection",
"../../../rtc_base:logging",
- "../../../rtc_base:rtc_base_approved",
- "../../../rtc_base:task_queue_for_test",
- "../../../rtc_base/task_utils:repeating_task",
- "../../../system_wrappers",
- "//third_party/abseil-cpp/absl/memory",
- "//third_party/abseil-cpp/absl/types:optional",
+ "../../../rtc_base:rtc_numerics",
]
}
- rtc_library("peerconnection_quality_test") {
+ rtc_library("example_video_quality_analyzer") {
visibility = [ "*" ]
testonly = true
-
sources = [
- "peer_connection_quality_test.cc",
- "peer_connection_quality_test.h",
+ "analyzer/video/example_video_quality_analyzer.cc",
+ "analyzer/video/example_video_quality_analyzer.h",
]
+
deps = [
- ":analyzer_helper",
- ":default_audio_quality_analyzer",
- ":default_video_quality_analyzer",
- ":media_helper",
- ":peer_configurer",
- ":peer_connection_quality_test_params",
- ":sdp_changer",
- ":single_process_encoded_image_data_injector",
- ":stats_poller",
- ":test_activities_executor",
- ":test_peer",
- ":test_peer_factory",
- ":video_quality_analyzer_injection_helper",
- ":video_quality_metrics_reporter",
- "../..:field_trial",
- "../..:fileutils",
- "../..:perf_test",
- "../../../api:audio_quality_analyzer_api",
- "../../../api:libjingle_peerconnection_api",
- "../../../api:media_stream_interface",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../api:rtc_event_log_output_file",
- "../../../api:scoped_refptr",
+ "../../../api:array_view",
"../../../api:video_quality_analyzer_api",
- "../../../api/rtc_event_log",
- "../../../api/task_queue",
- "../../../api/task_queue:default_task_queue_factory",
- "../../../api/units:time_delta",
- "../../../api/units:timestamp",
- "../../../pc:pc_test_utils",
- "../../../pc:peerconnection",
- "../../../rtc_base",
- "../../../rtc_base:gunit_helpers",
- "../../../rtc_base:macromagic",
- "../../../rtc_base:rtc_base_approved",
- "../../../rtc_base:safe_conversions",
- "../../../rtc_base:task_queue_for_test",
- "../../../system_wrappers",
- "../../../system_wrappers:field_trial",
+ "../../../api/video:encoded_image",
+ "../../../api/video:video_frame",
+ "../../../api/video:video_rtp_headers",
+ "../../../rtc_base:criticalsection",
+ "../../../rtc_base:logging",
]
}
- rtc_library("single_process_encoded_image_data_injector_unittest") {
+ rtc_library("video_quality_metrics_reporter") {
+ visibility = [ "*" ]
+
testonly = true
sources = [
- "analyzer/video/single_process_encoded_image_data_injector_unittest.cc",
+ "analyzer/video/video_quality_metrics_reporter.cc",
+ "analyzer/video/video_quality_metrics_reporter.h",
]
deps = [
- ":single_process_encoded_image_data_injector",
- "../../../api/video:encoded_image",
- "../../../rtc_base:rtc_base_approved",
- "../../../test:test_support",
+ "../..:perf_test",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api:rtc_stats_api",
+ "../../../api/units:data_rate",
+ "../../../api/units:data_size",
+ "../../../api/units:time_delta",
+ "../../../api/units:timestamp",
+ "../../../rtc_base:criticalsection",
+ "../../../rtc_base:rtc_numerics",
]
}
- rtc_library("default_encoded_image_data_injector_unittest") {
+ rtc_library("default_video_quality_analyzer") {
+ visibility = [ "*" ]
+
testonly = true
- sources =
- [ "analyzer/video/default_encoded_image_data_injector_unittest.cc" ]
+ sources = [
+ "analyzer/video/default_video_quality_analyzer.cc",
+ "analyzer/video/default_video_quality_analyzer.h",
+ ]
+
deps = [
- ":default_encoded_image_data_injector",
+ ":multi_head_queue",
+ "../..:perf_test",
+ "../../../api:array_view",
+ "../../../api:video_quality_analyzer_api",
+ "../../../api/units:time_delta",
+ "../../../api/units:timestamp",
"../../../api/video:encoded_image",
+ "../../../api/video:video_frame",
+ "../../../api/video:video_frame_i420",
+ "../../../api/video:video_rtp_headers",
+ "../../../common_video",
+ "../../../rtc_base:criticalsection",
+ "../../../rtc_base:logging",
"../../../rtc_base:rtc_base_approved",
- "../../../test:test_support",
+ "../../../rtc_base:rtc_base_tests_utils",
+ "../../../rtc_base:rtc_event",
+ "../../../rtc_base:rtc_numerics",
+ "../../../rtc_base:timeutils",
+ "../../../system_wrappers",
]
}
- peer_connection_e2e_smoke_test_resources = [
- "../../../resources/pc_quality_smoke_test_alice_source.wav",
- "../../../resources/pc_quality_smoke_test_bob_source.wav",
- ]
- if (is_ios) {
- bundle_data("peer_connection_e2e_smoke_test_resources_bundle_data") {
- testonly = true
- sources = peer_connection_e2e_smoke_test_resources
- outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
- }
- }
-
- rtc_library("peer_connection_e2e_smoke_test") {
+ rtc_library("network_quality_metrics_reporter") {
+ visibility = [ "*" ]
testonly = true
-
- sources = [ "peer_connection_e2e_smoke_test.cc" ]
+ sources = [
+ "network_quality_metrics_reporter.cc",
+ "network_quality_metrics_reporter.h",
+ ]
deps = [
- ":default_audio_quality_analyzer",
- ":default_video_quality_analyzer",
- ":network_quality_metrics_reporter",
- "../../../api:callfactory_api",
- "../../../api:create_network_emulation_manager",
- "../../../api:create_peer_connection_quality_test_frame_generator",
- "../../../api:create_peerconnection_quality_test_fixture",
- "../../../api:libjingle_peerconnection_api",
- "../../../api:media_stream_interface",
+ "../..:perf_test",
"../../../api:network_emulation_manager_api",
"../../../api:peer_connection_quality_test_fixture_api",
- "../../../api:scoped_refptr",
- "../../../api:simulated_network_api",
- "../../../api/audio_codecs:builtin_audio_decoder_factory",
- "../../../api/audio_codecs:builtin_audio_encoder_factory",
- "../../../api/video_codecs:builtin_video_decoder_factory",
- "../../../api/video_codecs:builtin_video_encoder_factory",
- "../../../call:simulated_network",
- "../../../media:rtc_audio_video",
- "../../../modules/audio_device:audio_device_impl",
- "../../../p2p:rtc_p2p",
- "../../../pc:pc_test_utils",
- "../../../pc:peerconnection_wrapper",
- "../../../rtc_base",
- "../../../rtc_base:gunit_helpers",
- "../../../rtc_base:logging",
+ "../../../api:rtc_stats_api",
+ "../../../api/units:data_size",
+ "../../../rtc_base:criticalsection",
"../../../rtc_base:rtc_event",
"../../../system_wrappers:field_trial",
- "../../../test:field_trial",
- "../../../test:fileutils",
- "../../../test:test_support",
]
- data = peer_connection_e2e_smoke_test_resources
- if (is_ios) {
- deps += [ ":peer_connection_e2e_smoke_test_resources_bundle_data" ]
- }
}
- rtc_library("stats_poller") {
+ rtc_library("sdp_changer") {
visibility = [ "*" ]
testonly = true
sources = [
- "stats_poller.cc",
- "stats_poller.h",
+ "sdp/sdp_changer.cc",
+ "sdp/sdp_changer.h",
]
deps = [
- ":test_peer",
+ "../../../api:array_view",
"../../../api:libjingle_peerconnection_api",
- "../../../api:stats_observer_interface",
- "../../../rtc_base:logging",
+ "../../../api:peer_connection_quality_test_fixture_api",
+ "../../../api:rtp_parameters",
+ "../../../media:rtc_media_base",
+ "../../../p2p:rtc_p2p",
+ "../../../pc:peerconnection",
+ "../../../pc:rtc_pc_base",
+ "../../../rtc_base:stringutils",
+ ]
+ absl_deps = [
+ "//third_party/abseil-cpp/absl/memory",
+ "//third_party/abseil-cpp/absl/strings:strings",
+ "//third_party/abseil-cpp/absl/types:optional",
]
}
- rtc_library("default_video_quality_analyzer_test") {
+ rtc_library("multi_head_queue") {
+ visibility = [ "*" ]
testonly = true
- sources = [ "analyzer/video/default_video_quality_analyzer_test.cc" ]
- deps = [
- ":default_video_quality_analyzer",
- "../..:test_support",
- "../../../api:create_frame_generator",
- "../../../api:rtp_packet_info",
- "../../../api/video:encoded_image",
- "../../../api/video:video_frame",
- "../../../api/video:video_frame_i420",
- "../../../modules/rtp_rtcp:rtp_rtcp_format",
- "../../../system_wrappers",
- ]
+ sources = [ "analyzer/video/multi_head_queue.h" ]
+ deps = [ "../../../rtc_base:checks" ]
+ absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
}
-
-rtc_library("analyzer_helper") {
- visibility = [ "*" ]
- sources = [
- "analyzer_helper.cc",
- "analyzer_helper.h",
- ]
- deps = [
- "../../../api:track_id_stream_label_map",
- "../../../rtc_base:macromagic",
- "../../../rtc_base/synchronization:sequence_checker",
- ]
-}
-
-rtc_library("default_audio_quality_analyzer") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/audio/default_audio_quality_analyzer.cc",
- "analyzer/audio/default_audio_quality_analyzer.h",
- ]
-
- deps = [
- "../..:perf_test",
- "../../../api:audio_quality_analyzer_api",
- "../../../api:libjingle_peerconnection_api",
- "../../../api:stats_observer_interface",
- "../../../api:track_id_stream_label_map",
- "../../../rtc_base:criticalsection",
- "../../../rtc_base:logging",
- "../../../rtc_base:rtc_numerics",
- ]
-}
-
-rtc_library("example_video_quality_analyzer") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "analyzer/video/example_video_quality_analyzer.cc",
- "analyzer/video/example_video_quality_analyzer.h",
- ]
-
- deps = [
- "../../../api:video_quality_analyzer_api",
- "../../../api/video:encoded_image",
- "../../../api/video:video_frame",
- "../../../api/video:video_rtp_headers",
- "../../../rtc_base:criticalsection",
- "../../../rtc_base:logging",
- ]
-}
-
-rtc_library("video_quality_metrics_reporter") {
- visibility = [ "*" ]
-
- testonly = true
- sources = [
- "analyzer/video/video_quality_metrics_reporter.cc",
- "analyzer/video/video_quality_metrics_reporter.h",
- ]
- deps = [
- "../..:perf_test",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../rtc_base:criticalsection",
- "../../../rtc_base:rtc_numerics",
- ]
-}
-
-rtc_library("default_video_quality_analyzer") {
- visibility = [ "*" ]
-
- testonly = true
- sources = [
- "analyzer/video/default_video_quality_analyzer.cc",
- "analyzer/video/default_video_quality_analyzer.h",
- ]
-
- deps = [
- "../..:perf_test",
- "../../../api:video_quality_analyzer_api",
- "../../../api/units:time_delta",
- "../../../api/units:timestamp",
- "../../../api/video:encoded_image",
- "../../../api/video:video_frame",
- "../../../api/video:video_frame_i420",
- "../../../api/video:video_rtp_headers",
- "../../../common_video",
- "../../../rtc_base:criticalsection",
- "../../../rtc_base:logging",
- "../../../rtc_base:rtc_base_approved",
- "../../../rtc_base:rtc_base_tests_utils",
- "../../../rtc_base:rtc_event",
- "../../../rtc_base:rtc_numerics",
- "../../../rtc_base:timeutils",
- "../../../system_wrappers",
- ]
-}
-
-rtc_library("network_quality_metrics_reporter") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "network_quality_metrics_reporter.cc",
- "network_quality_metrics_reporter.h",
- ]
- deps = [
- "../..:perf_test",
- "../../../api:libjingle_peerconnection_api",
- "../../../api:network_emulation_manager_api",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../rtc_base:criticalsection",
- "../../../rtc_base:rtc_event",
- "../../../system_wrappers:field_trial",
- ]
-}
-
-rtc_library("sdp_changer") {
- visibility = [ "*" ]
- testonly = true
- sources = [
- "sdp/sdp_changer.cc",
- "sdp/sdp_changer.h",
- ]
- deps = [
- "../../../api:array_view",
- "../../../api:libjingle_peerconnection_api",
- "../../../api:peer_connection_quality_test_fixture_api",
- "../../../api:rtp_parameters",
- "../../../media:rtc_media_base",
- "../../../p2p:rtc_p2p",
- "../../../pc:peerconnection",
- "../../../pc:rtc_pc_base",
- "../../../rtc_base:stringutils",
- "//third_party/abseil-cpp/absl/memory",
- "//third_party/abseil-cpp/absl/strings:strings",
- "//third_party/abseil-cpp/absl/types:optional",
- ]
-}
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.cc
index b8f1740e46d..b8902335213 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.cc
@@ -10,16 +10,12 @@
#include "test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h"
-#include "api/stats_types.h"
+#include "api/stats/rtc_stats.h"
+#include "api/stats/rtcstats_objects.h"
#include "rtc_base/logging.h"
namespace webrtc {
namespace webrtc_pc_e2e {
-namespace {
-
-static const char kStatsAudioMediaType[] = "audio";
-
-} // namespace
void DefaultAudioQualityAnalyzer::Start(
std::string test_case_name,
@@ -29,68 +25,82 @@ void DefaultAudioQualityAnalyzer::Start(
}
void DefaultAudioQualityAnalyzer::OnStatsReports(
- const std::string& pc_label,
- const StatsReports& stats_reports) {
- for (const StatsReport* stats_report : stats_reports) {
- // NetEq stats are only present in kStatsReportTypeSsrc reports, so all
- // other reports are just ignored.
- if (stats_report->type() != StatsReport::StatsType::kStatsReportTypeSsrc) {
- continue;
- }
- // Ignoring stats reports of "video" SSRC.
- const webrtc::StatsReport::Value* media_type = stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameMediaType);
- RTC_CHECK(media_type);
- if (strcmp(media_type->static_string_val(), kStatsAudioMediaType) != 0) {
- continue;
- }
- if (stats_report->FindValue(
- webrtc::StatsReport::kStatsValueNameBytesSent)) {
- // If kStatsValueNameBytesSent is present, it means it's a send stream,
- // but we need audio metrics for receive stream, so skip it.
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) {
+ // TODO(https://crbug.com/webrtc/11683): use "inbound-rtp" instead of "track"
+ // stats when required audio metrics moved there
+ auto stats = report->GetStatsOfType<RTCMediaStreamTrackStats>();
+
+ for (auto& stat : stats) {
+ if (!stat->kind.is_defined() ||
+ !(*stat->kind == RTCMediaStreamTrackKind::kAudio) ||
+ !*stat->remote_source) {
continue;
}
- const webrtc::StatsReport::Value* expand_rate = stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameExpandRate);
- const webrtc::StatsReport::Value* accelerate_rate = stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameAccelerateRate);
- const webrtc::StatsReport::Value* preemptive_rate = stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNamePreemptiveExpandRate);
- const webrtc::StatsReport::Value* speech_expand_rate =
- stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameSpeechExpandRate);
- const webrtc::StatsReport::Value* preferred_buffer_size_ms =
- stats_report->FindValue(StatsReport::StatsValueName::
- kStatsValueNamePreferredJitterBufferMs);
- RTC_CHECK(expand_rate);
- RTC_CHECK(accelerate_rate);
- RTC_CHECK(preemptive_rate);
- RTC_CHECK(speech_expand_rate);
- RTC_CHECK(preferred_buffer_size_ms);
+ StatsSample sample;
+ sample.total_samples_received =
+ stat->total_samples_received.ValueOrDefault(0ul);
+ sample.concealed_samples = stat->concealed_samples.ValueOrDefault(0ul);
+ sample.removed_samples_for_acceleration =
+ stat->removed_samples_for_acceleration.ValueOrDefault(0ul);
+ sample.inserted_samples_for_deceleration =
+ stat->inserted_samples_for_deceleration.ValueOrDefault(0ul);
+ sample.silent_concealed_samples =
+ stat->silent_concealed_samples.ValueOrDefault(0ul);
+ sample.jitter_buffer_target_delay =
+ TimeDelta::Seconds(stat->jitter_buffer_target_delay.ValueOrDefault(0.));
+ sample.jitter_buffer_emitted_count =
+ stat->jitter_buffer_emitted_count.ValueOrDefault(0ul);
const std::string& stream_label =
- GetStreamLabelFromStatsReport(stats_report);
+ analyzer_helper_->GetStreamLabelFromTrackId(*stat->track_identifier);
rtc::CritScope crit(&lock_);
+ StatsSample prev_sample = last_stats_sample_[stream_label];
+ RTC_CHECK_GE(sample.total_samples_received,
+ prev_sample.total_samples_received);
+ double total_samples_diff = static_cast<double>(
+ sample.total_samples_received - prev_sample.total_samples_received);
+ if (total_samples_diff == 0) {
+ return;
+ }
+
AudioStreamStats& audio_stream_stats = streams_stats_[stream_label];
- audio_stream_stats.expand_rate.AddSample(expand_rate->float_val());
- audio_stream_stats.accelerate_rate.AddSample(accelerate_rate->float_val());
- audio_stream_stats.preemptive_rate.AddSample(preemptive_rate->float_val());
+ audio_stream_stats.expand_rate.AddSample(
+ (sample.concealed_samples - prev_sample.concealed_samples) /
+ total_samples_diff);
+ audio_stream_stats.accelerate_rate.AddSample(
+ (sample.removed_samples_for_acceleration -
+ prev_sample.removed_samples_for_acceleration) /
+ total_samples_diff);
+ audio_stream_stats.preemptive_rate.AddSample(
+ (sample.inserted_samples_for_deceleration -
+ prev_sample.inserted_samples_for_deceleration) /
+ total_samples_diff);
+
+ int64_t speech_concealed_samples =
+ sample.concealed_samples - sample.silent_concealed_samples;
+ int64_t prev_speech_concealed_samples =
+ prev_sample.concealed_samples - prev_sample.silent_concealed_samples;
audio_stream_stats.speech_expand_rate.AddSample(
- speech_expand_rate->float_val());
- audio_stream_stats.preferred_buffer_size_ms.AddSample(
- preferred_buffer_size_ms->int_val());
- }
-}
+ (speech_concealed_samples - prev_speech_concealed_samples) /
+ total_samples_diff);
+
+ int64_t jitter_buffer_emitted_count_diff =
+ sample.jitter_buffer_emitted_count -
+ prev_sample.jitter_buffer_emitted_count;
+ if (jitter_buffer_emitted_count_diff > 0) {
+ TimeDelta jitter_buffer_target_delay_diff =
+ sample.jitter_buffer_target_delay -
+ prev_sample.jitter_buffer_target_delay;
+ audio_stream_stats.preferred_buffer_size_ms.AddSample(
+ jitter_buffer_target_delay_diff.ms<double>() /
+ jitter_buffer_emitted_count_diff);
+ }
-const std::string& DefaultAudioQualityAnalyzer::GetStreamLabelFromStatsReport(
- const StatsReport* stats_report) const {
- const webrtc::StatsReport::Value* report_track_id = stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameTrackId);
- RTC_CHECK(report_track_id);
- return analyzer_helper_->GetStreamLabelFromTrackId(
- report_track_id->string_val());
+ last_stats_sample_[stream_label] = sample;
+ }
}
std::string DefaultAudioQualityAnalyzer::GetTestCaseName(
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h
index 33aaefd4c3f..c990e4f357f 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h
@@ -14,9 +14,9 @@
#include <map>
#include <string>
-#include "api/stats_types.h"
#include "api/test/audio_quality_analyzer_interface.h"
#include "api/test/track_id_stream_label_map.h"
+#include "api/units/time_delta.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/numerics/samples_stats_counter.h"
#include "test/testsupport/perf_test.h"
@@ -32,22 +32,29 @@ struct AudioStreamStats {
SamplesStatsCounter preferred_buffer_size_ms;
};
-// TODO(bugs.webrtc.org/10430): Migrate to the new GetStats as soon as
-// bugs.webrtc.org/10428 is fixed.
class DefaultAudioQualityAnalyzer : public AudioQualityAnalyzerInterface {
public:
void Start(std::string test_case_name,
TrackIdStreamLabelMap* analyzer_helper) override;
- void OnStatsReports(const std::string& pc_label,
- const StatsReports& stats_reports) override;
+ void OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override;
void Stop() override;
// Returns audio quality stats per stream label.
std::map<std::string, AudioStreamStats> GetAudioStreamsStats() const;
private:
- const std::string& GetStreamLabelFromStatsReport(
- const StatsReport* stats_report) const;
+ struct StatsSample {
+ uint64_t total_samples_received = 0;
+ uint64_t concealed_samples = 0;
+ uint64_t removed_samples_for_acceleration = 0;
+ uint64_t inserted_samples_for_deceleration = 0;
+ uint64_t silent_concealed_samples = 0;
+ TimeDelta jitter_buffer_target_delay = TimeDelta::Zero();
+ uint64_t jitter_buffer_emitted_count = 0;
+ };
+
std::string GetTestCaseName(const std::string& stream_label) const;
void ReportResult(const std::string& metric_name,
const std::string& stream_label,
@@ -60,6 +67,7 @@ class DefaultAudioQualityAnalyzer : public AudioQualityAnalyzerInterface {
rtc::CriticalSection lock_;
std::map<std::string, AudioStreamStats> streams_stats_ RTC_GUARDED_BY(lock_);
+ std::map<std::string, StatsSample> last_stats_sample_ RTC_GUARDED_BY(lock_);
};
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
index 786509ddb7e..851238f1e74 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
@@ -14,11 +14,13 @@
#include <memory>
#include <utility>
+#include "api/array_view.h"
#include "api/units/time_delta.h"
#include "api/video/i420_buffer.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "rtc_base/cpu_time.h"
#include "rtc_base/logging.h"
+#include "rtc_base/strings/string_builder.h"
#include "rtc_base/time_utils.h"
namespace webrtc {
@@ -35,6 +37,7 @@ void LogFrameCounters(const std::string& name, const FrameCounters& counters) {
RTC_LOG(INFO) << "[" << name << "] Pre encoded : " << counters.pre_encoded;
RTC_LOG(INFO) << "[" << name << "] Encoded : " << counters.encoded;
RTC_LOG(INFO) << "[" << name << "] Received : " << counters.received;
+ RTC_LOG(INFO) << "[" << name << "] Decoded : " << counters.decoded;
RTC_LOG(INFO) << "[" << name << "] Rendered : " << counters.rendered;
RTC_LOG(INFO) << "[" << name << "] Dropped : " << counters.dropped;
}
@@ -46,6 +49,15 @@ void LogStreamInternalStats(const std::string& name, const StreamStats& stats) {
<< stats.dropped_before_encoder;
}
+template <typename T>
+absl::optional<T> MaybeGetValue(const std::map<size_t, T>& map, size_t key) {
+ auto it = map.find(key);
+ if (it == map.end()) {
+ return absl::nullopt;
+ }
+ return it->second;
+}
+
} // namespace
void RateCounter::AddEvent(Timestamp event_time) {
@@ -65,9 +77,52 @@ double RateCounter::GetEventsPerSecond() const {
(event_last_time_ - event_first_time_).us() * kMicrosPerSecond;
}
+std::string StatsKey::ToString() const {
+ rtc::StringBuilder out;
+ out << stream_label << "_" << sender << "_" << receiver;
+ return out.str();
+}
+
+bool operator<(const StatsKey& a, const StatsKey& b) {
+ if (a.stream_label != b.stream_label) {
+ return a.stream_label < b.stream_label;
+ }
+ if (a.sender != b.sender) {
+ return a.sender < b.sender;
+ }
+ return a.receiver < b.receiver;
+}
+
+bool operator==(const StatsKey& a, const StatsKey& b) {
+ return a.stream_label == b.stream_label && a.sender == b.sender &&
+ a.receiver == b.receiver;
+}
+
+std::string InternalStatsKey::ToString() const {
+ rtc::StringBuilder out;
+ out << "stream=" << stream << "_sender=" << sender
+ << "_receiver=" << receiver;
+ return out.str();
+}
+
+bool operator<(const InternalStatsKey& a, const InternalStatsKey& b) {
+ if (a.stream != b.stream) {
+ return a.stream < b.stream;
+ }
+ if (a.sender != b.sender) {
+ return a.sender < b.sender;
+ }
+ return a.receiver < b.receiver;
+}
+
+bool operator==(const InternalStatsKey& a, const InternalStatsKey& b) {
+ return a.stream == b.stream && a.sender == b.sender &&
+ a.receiver == b.receiver;
+}
+
DefaultVideoQualityAnalyzer::DefaultVideoQualityAnalyzer(
bool heavy_metrics_computation_enabled,
- int max_frames_in_flight_per_stream_count)
+ size_t max_frames_in_flight_per_stream_count)
: heavy_metrics_computation_enabled_(heavy_metrics_computation_enabled),
max_frames_in_flight_per_stream_count_(
max_frames_in_flight_per_stream_count),
@@ -76,9 +131,12 @@ DefaultVideoQualityAnalyzer::~DefaultVideoQualityAnalyzer() {
Stop();
}
-void DefaultVideoQualityAnalyzer::Start(std::string test_case_name,
- int max_threads_count) {
+void DefaultVideoQualityAnalyzer::Start(
+ std::string test_case_name,
+ rtc::ArrayView<const std::string> peer_names,
+ int max_threads_count) {
test_label_ = std::move(test_case_name);
+ peers_ = std::make_unique<NamesCollection>(peer_names);
for (int i = 0; i < max_threads_count; i++) {
auto thread = std::make_unique<rtc::PlatformThread>(
&DefaultVideoQualityAnalyzer::ProcessComparisonsThread, this,
@@ -98,73 +156,115 @@ void DefaultVideoQualityAnalyzer::Start(std::string test_case_name,
}
uint16_t DefaultVideoQualityAnalyzer::OnFrameCaptured(
+ absl::string_view peer_name,
const std::string& stream_label,
const webrtc::VideoFrame& frame) {
// |next_frame_id| is atomic, so we needn't lock here.
uint16_t frame_id = next_frame_id_++;
Timestamp start_time = Timestamp::MinusInfinity();
+ size_t peer_index = peers_->index(peer_name);
+ size_t stream_index;
{
rtc::CritScope crit(&lock_);
- // Create a local copy of start_time_ to access it under |comparison_lock_|
- // without holding a |lock_|
+ // Create a local copy of start_time_ to access it under
+ // |comparison_lock_| without holding a |lock_|
start_time = start_time_;
+ stream_index = streams_.AddIfAbsent(stream_label);
}
{
// Ensure stats for this stream exists.
rtc::CritScope crit(&comparison_lock_);
- if (stream_stats_.find(stream_label) == stream_stats_.end()) {
- stream_stats_.insert({stream_label, StreamStats()});
- // Assume that the first freeze was before first stream frame captured.
- // This way time before the first freeze would be counted as time between
- // freezes.
- stream_last_freeze_end_time_.insert({stream_label, start_time});
+ for (size_t i = 0; i < peers_->size(); ++i) {
+ if (i == peer_index) {
+ continue;
+ }
+ InternalStatsKey stats_key(stream_index, peer_index, i);
+ if (stream_stats_.find(stats_key) == stream_stats_.end()) {
+ stream_stats_.insert({stats_key, StreamStats()});
+ // Assume that the first freeze was before first stream frame captured.
+ // This way time before the first freeze would be counted as time
+ // between freezes.
+ stream_last_freeze_end_time_.insert({stats_key, start_time});
+ } else {
+ // When we see some |stream_label| for the first time we need to create
+ // stream stats object for it and set up some states, but we need to do
+ // it only once and for all receivers, so on the next frame on the same
+ // |stream_label| we can be sure, that it's already done and we needn't
+ // to scan though all peers again.
+ break;
+ }
}
}
{
rtc::CritScope crit(&lock_);
+ stream_to_sender_[stream_index] = peer_index;
frame_counters_.captured++;
- stream_frame_counters_[stream_label].captured++;
+ for (size_t i = 0; i < peers_->size(); ++i) {
+ if (i != peer_index) {
+ InternalStatsKey key(stream_index, peer_index, i);
+ stream_frame_counters_[key].captured++;
+ }
+ }
- StreamState* state = &stream_states_[stream_label];
+ auto state_it = stream_states_.find(stream_index);
+ if (state_it == stream_states_.end()) {
+ stream_states_.emplace(stream_index,
+ StreamState(peer_index, peers_->size()));
+ }
+ StreamState* state = &stream_states_.at(stream_index);
state->PushBack(frame_id);
// Update frames in flight info.
auto it = captured_frames_in_flight_.find(frame_id);
if (it != captured_frames_in_flight_.end()) {
- // We overflow uint16_t and hit previous frame id and this frame is still
- // in flight. It means that this stream wasn't rendered for long time and
- // we need to process existing frame as dropped.
- auto stats_it = frame_stats_.find(frame_id);
- RTC_DCHECK(stats_it != frame_stats_.end());
-
- uint16_t oldest_frame_id = state->PopFront();
- RTC_DCHECK_EQ(frame_id, oldest_frame_id);
- frame_counters_.dropped++;
- stream_frame_counters_[stream_label].dropped++;
- AddComparison(it->second, absl::nullopt, true, stats_it->second);
+ // If we overflow uint16_t and hit previous frame id and this frame is
+ // still in flight, it means that this stream wasn't rendered for long
+ // time and we need to process existing frame as dropped.
+ for (size_t i = 0; i < peers_->size(); ++i) {
+ if (i == peer_index) {
+ continue;
+ }
+
+ uint16_t oldest_frame_id = state->PopFront(i);
+ RTC_DCHECK_EQ(frame_id, oldest_frame_id);
+ frame_counters_.dropped++;
+ InternalStatsKey key(stream_index, peer_index, i);
+ stream_frame_counters_.at(key).dropped++;
+
+ rtc::CritScope crit1(&comparison_lock_);
+ analyzer_stats_.frames_in_flight_left_count.AddSample(
+ captured_frames_in_flight_.size());
+ AddComparison(InternalStatsKey(stream_index, peer_index, i),
+ it->second.frame(), absl::nullopt, true,
+ it->second.GetStatsForPeer(i));
+ }
captured_frames_in_flight_.erase(it);
- frame_stats_.erase(stats_it);
}
- captured_frames_in_flight_.insert(
- std::pair<uint16_t, VideoFrame>(frame_id, frame));
+ captured_frames_in_flight_.emplace(
+ frame_id,
+ FrameInFlight(stream_index, frame,
+ /*captured_time=*/Now(), peer_index, peers_->size()));
// Set frame id on local copy of the frame
- captured_frames_in_flight_.at(frame_id).set_id(frame_id);
- frame_stats_.insert(std::pair<uint16_t, FrameStats>(
- frame_id, FrameStats(stream_label, /*captured_time=*/Now())));
+ captured_frames_in_flight_.at(frame_id).SetFrameId(frame_id);
// Update history stream<->frame mapping
for (auto it = stream_to_frame_id_history_.begin();
it != stream_to_frame_id_history_.end(); ++it) {
it->second.erase(frame_id);
}
- stream_to_frame_id_history_[stream_label].insert(frame_id);
+ stream_to_frame_id_history_[stream_index].insert(frame_id);
// If state has too many frames that are in flight => remove the oldest
// queued frame in order to avoid to use too much memory.
if (state->GetAliveFramesCount() > max_frames_in_flight_per_stream_count_) {
uint16_t frame_id_to_remove = state->MarkNextAliveFrameAsDead();
- auto removed_count = captured_frames_in_flight_.erase(frame_id_to_remove);
- RTC_DCHECK_EQ(removed_count, 1)
+ auto it = captured_frames_in_flight_.find(frame_id_to_remove);
+ RTC_CHECK(it != captured_frames_in_flight_.end())
+ << "Frame with ID " << frame_id_to_remove
+ << " is expected to be in flight, but hasn't been found in "
+ << "|captured_frames_in_flight_|";
+ bool is_removed = it->second.RemoveFrame();
+ RTC_DCHECK(is_removed)
<< "Invalid stream state: alive frame is removed already";
}
}
@@ -172,52 +272,76 @@ uint16_t DefaultVideoQualityAnalyzer::OnFrameCaptured(
}
void DefaultVideoQualityAnalyzer::OnFramePreEncode(
+ absl::string_view peer_name,
const webrtc::VideoFrame& frame) {
rtc::CritScope crit(&lock_);
- auto it = frame_stats_.find(frame.id());
- RTC_DCHECK(it != frame_stats_.end())
+ auto it = captured_frames_in_flight_.find(frame.id());
+ RTC_DCHECK(it != captured_frames_in_flight_.end())
<< "Frame id=" << frame.id() << " not found";
frame_counters_.pre_encoded++;
- stream_frame_counters_[it->second.stream_label].pre_encoded++;
- it->second.pre_encode_time = Now();
+ size_t peer_index = peers_->index(peer_name);
+ for (size_t i = 0; i < peers_->size(); ++i) {
+ if (i != peer_index) {
+ InternalStatsKey key(it->second.stream(), peer_index, i);
+ stream_frame_counters_.at(key).pre_encoded++;
+ }
+ }
+ it->second.SetPreEncodeTime(Now());
}
void DefaultVideoQualityAnalyzer::OnFrameEncoded(
+ absl::string_view peer_name,
uint16_t frame_id,
const webrtc::EncodedImage& encoded_image,
const EncoderStats& stats) {
rtc::CritScope crit(&lock_);
- auto it = frame_stats_.find(frame_id);
- RTC_DCHECK(it != frame_stats_.end());
+ auto it = captured_frames_in_flight_.find(frame_id);
+ RTC_DCHECK(it != captured_frames_in_flight_.end());
// For SVC we can receive multiple encoded images for one frame, so to cover
// all cases we have to pick the last encode time.
- if (it->second.encoded_time.IsInfinite()) {
+ if (!it->second.HasEncodedTime()) {
// Increase counters only when we meet this frame first time.
frame_counters_.encoded++;
- stream_frame_counters_[it->second.stream_label].encoded++;
+ size_t peer_index = peers_->index(peer_name);
+ for (size_t i = 0; i < peers_->size(); ++i) {
+ if (i != peer_index) {
+ InternalStatsKey key(it->second.stream(), peer_index, i);
+ stream_frame_counters_.at(key).encoded++;
+ }
+ }
}
- it->second.encoded_time = Now();
- it->second.encoded_image_size = encoded_image.size();
- it->second.target_encode_bitrate += stats.target_encode_bitrate;
+ it->second.OnFrameEncoded(Now(), encoded_image.size(),
+ stats.target_encode_bitrate);
}
void DefaultVideoQualityAnalyzer::OnFrameDropped(
+ absl::string_view peer_name,
webrtc::EncodedImageCallback::DropReason reason) {
// Here we do nothing, because we will see this drop on renderer side.
}
void DefaultVideoQualityAnalyzer::OnFramePreDecode(
+ absl::string_view peer_name,
uint16_t frame_id,
const webrtc::EncodedImage& input_image) {
rtc::CritScope crit(&lock_);
- auto it = frame_stats_.find(frame_id);
- RTC_DCHECK(it != frame_stats_.end());
- RTC_DCHECK(it->second.received_time.IsInfinite())
- << "Received multiple spatial layers for stream_label="
- << it->second.stream_label;
+ size_t peer_index = peers_->index(peer_name);
+
+ auto it = captured_frames_in_flight_.find(frame_id);
+ if (it == captured_frames_in_flight_.end() ||
+ it->second.HasReceivedTime(peer_index)) {
+ // It means this frame was predecoded before, so we can skip it. It may
+ // happen when we have multiple simulcast streams in one track and received
+ // the same picture from two different streams because SFU can't reliably
+ // correlate two simulcast streams and started relaying the second stream
+ // from the same frame it has relayed right before for the first stream.
+ return;
+ }
+
frame_counters_.received++;
- stream_frame_counters_[it->second.stream_label].received++;
- it->second.decode_start_time = Now();
+ InternalStatsKey key(it->second.stream(),
+ stream_to_sender_.at(it->second.stream()), peer_index);
+ stream_frame_counters_.at(key).received++;
// Determine the time of the last received packet of this video frame.
RTC_DCHECK(!input_image.PacketInfos().empty());
int64_t last_receive_time =
@@ -227,112 +351,145 @@ void DefaultVideoQualityAnalyzer::OnFramePreDecode(
return a.receive_time_ms() < b.receive_time_ms();
})
->receive_time_ms();
- it->second.received_time = Timestamp::Millis(last_receive_time);
+ it->second.OnFramePreDecode(
+ peer_index,
+ /*received_time=*/Timestamp::Millis(last_receive_time),
+ /*decode_start_time=*/Now());
}
void DefaultVideoQualityAnalyzer::OnFrameDecoded(
+ absl::string_view peer_name,
const webrtc::VideoFrame& frame,
const DecoderStats& stats) {
rtc::CritScope crit(&lock_);
- auto it = frame_stats_.find(frame.id());
- RTC_DCHECK(it != frame_stats_.end());
+ size_t peer_index = peers_->index(peer_name);
+
+ auto it = captured_frames_in_flight_.find(frame.id());
+ if (it == captured_frames_in_flight_.end() ||
+ it->second.HasDecodeEndTime(peer_index)) {
+ // It means this frame was decoded before, so we can skip it. It may happen
+ // when we have multiple simulcast streams in one track and received
+ // the same picture from two different streams because SFU can't reliably
+ // correlate two simulcast streams and started relaying the second stream
+ // from the same frame it has relayed right before for the first stream.
+ return;
+ }
frame_counters_.decoded++;
- stream_frame_counters_[it->second.stream_label].decoded++;
- it->second.decode_end_time = Now();
+ InternalStatsKey key(it->second.stream(),
+ stream_to_sender_.at(it->second.stream()), peer_index);
+ stream_frame_counters_.at(key).decoded++;
+ it->second.SetDecodeEndTime(peer_index, Now());
}
void DefaultVideoQualityAnalyzer::OnFrameRendered(
+ absl::string_view peer_name,
const webrtc::VideoFrame& raw_frame) {
+ rtc::CritScope crit(&lock_);
+ size_t peer_index = peers_->index(peer_name);
+
+ auto frame_it = captured_frames_in_flight_.find(raw_frame.id());
+ if (frame_it == captured_frames_in_flight_.end() ||
+ frame_it->second.HasRenderedTime(peer_index)) {
+ // It means this frame was rendered before, so we can skip it. It may happen
+ // when we have multiple simulcast streams in one track and received
+ // the same picture from two different streams because SFU can't reliably
+ // correlate two simulcast streams and started relaying the second stream
+ // from the same frame it has relayed right before for the first stream.
+ return;
+ }
+
// Copy entire video frame including video buffer to ensure that analyzer
// won't hold any WebRTC internal buffers.
VideoFrame frame = raw_frame;
frame.set_video_frame_buffer(
I420Buffer::Copy(*raw_frame.video_frame_buffer()->ToI420()));
- rtc::CritScope crit(&lock_);
- auto stats_it = frame_stats_.find(frame.id());
- RTC_DCHECK(stats_it != frame_stats_.end());
- FrameStats* frame_stats = &stats_it->second;
+ // Find corresponding captured frame.
+ FrameInFlight* frame_in_flight = &frame_it->second;
+ absl::optional<VideoFrame> captured_frame = frame_in_flight->frame();
+
+ const size_t stream_index = frame_in_flight->stream();
+ StreamState* state = &stream_states_.at(stream_index);
+ const InternalStatsKey stats_key(stream_index, state->owner(), peer_index);
+
// Update frames counters.
frame_counters_.rendered++;
- stream_frame_counters_[frame_stats->stream_label].rendered++;
+ stream_frame_counters_.at(stats_key).rendered++;
// Update current frame stats.
- frame_stats->rendered_time = Now();
- frame_stats->rendered_frame_width = frame.width();
- frame_stats->rendered_frame_height = frame.height();
-
- // Find corresponding captured frame.
- auto frame_it = captured_frames_in_flight_.find(frame.id());
- absl::optional<VideoFrame> captured_frame =
- frame_it != captured_frames_in_flight_.end()
- ? absl::optional<VideoFrame>(frame_it->second)
- : absl::nullopt;
+ frame_in_flight->OnFrameRendered(peer_index, Now(), frame.width(),
+ frame.height());
// After we received frame here we need to check if there are any dropped
// frames between this one and last one, that was rendered for this video
// stream.
-
- const std::string& stream_label = frame_stats->stream_label;
- StreamState* state = &stream_states_[stream_label];
int dropped_count = 0;
- while (!state->Empty() && state->Front() != frame.id()) {
+ while (!state->IsEmpty(peer_index) &&
+ state->Front(peer_index) != frame.id()) {
dropped_count++;
- uint16_t dropped_frame_id = state->PopFront();
+ uint16_t dropped_frame_id = state->PopFront(peer_index);
// Frame with id |dropped_frame_id| was dropped. We need:
// 1. Update global and stream frame counters
// 2. Extract corresponding frame from |captured_frames_in_flight_|
- // 3. Extract corresponding frame stats from |frame_stats_|
- // 4. Send extracted frame to comparison with dropped=true
- // 5. Cleanup dropped frame
+ // 3. Send extracted frame to comparison with dropped=true
+ // 4. Cleanup dropped frame
frame_counters_.dropped++;
- stream_frame_counters_[stream_label].dropped++;
+ stream_frame_counters_.at(stats_key).dropped++;
- auto dropped_frame_stats_it = frame_stats_.find(dropped_frame_id);
- RTC_DCHECK(dropped_frame_stats_it != frame_stats_.end());
auto dropped_frame_it = captured_frames_in_flight_.find(dropped_frame_id);
- absl::optional<VideoFrame> dropped_frame =
- dropped_frame_it != captured_frames_in_flight_.end()
- ? absl::optional<VideoFrame>(dropped_frame_it->second)
- : absl::nullopt;
+ RTC_DCHECK(dropped_frame_it != captured_frames_in_flight_.end());
+ absl::optional<VideoFrame> dropped_frame = dropped_frame_it->second.frame();
+ dropped_frame_it->second.MarkDropped(peer_index);
- AddComparison(dropped_frame, absl::nullopt, true,
- dropped_frame_stats_it->second);
+ {
+ rtc::CritScope crit1(&comparison_lock_);
+ analyzer_stats_.frames_in_flight_left_count.AddSample(
+ captured_frames_in_flight_.size());
+ AddComparison(stats_key, dropped_frame, absl::nullopt, true,
+ dropped_frame_it->second.GetStatsForPeer(peer_index));
+ }
- frame_stats_.erase(dropped_frame_stats_it);
- if (dropped_frame_it != captured_frames_in_flight_.end()) {
+ if (dropped_frame_it->second.HaveAllPeersReceived()) {
captured_frames_in_flight_.erase(dropped_frame_it);
}
}
- RTC_DCHECK(!state->Empty());
- state->PopFront();
+ RTC_DCHECK(!state->IsEmpty(peer_index));
+ state->PopFront(peer_index);
- if (state->last_rendered_frame_time()) {
- frame_stats->prev_frame_rendered_time =
- state->last_rendered_frame_time().value();
+ if (state->last_rendered_frame_time(peer_index)) {
+ frame_in_flight->SetPrevFrameRenderedTime(
+ peer_index, state->last_rendered_frame_time(peer_index).value());
}
- state->set_last_rendered_frame_time(frame_stats->rendered_time);
+ state->SetLastRenderedFrameTime(peer_index,
+ frame_in_flight->rendered_time(peer_index));
{
rtc::CritScope cr(&comparison_lock_);
- stream_stats_[stream_label].skipped_between_rendered.AddSample(
- dropped_count);
+ stream_stats_[stats_key].skipped_between_rendered.AddSample(dropped_count);
}
- AddComparison(captured_frame, frame, false, *frame_stats);
- if (frame_it != captured_frames_in_flight_.end()) {
+ {
+ rtc::CritScope crit(&comparison_lock_);
+ analyzer_stats_.frames_in_flight_left_count.AddSample(
+ captured_frames_in_flight_.size());
+ AddComparison(stats_key, captured_frame, frame, false,
+ frame_in_flight->GetStatsForPeer(peer_index));
+ }
+
+ if (frame_it->second.HaveAllPeersReceived()) {
captured_frames_in_flight_.erase(frame_it);
}
- frame_stats_.erase(stats_it);
}
void DefaultVideoQualityAnalyzer::OnEncoderError(
+ absl::string_view peer_name,
const webrtc::VideoFrame& frame,
int32_t error_code) {
RTC_LOG(LS_ERROR) << "Encoder error for frame.id=" << frame.id()
<< ", code=" << error_code;
}
-void DefaultVideoQualityAnalyzer::OnDecoderError(uint16_t frame_id,
+void DefaultVideoQualityAnalyzer::OnDecoderError(absl::string_view peer_name,
+ uint16_t frame_id,
int32_t error_code) {
RTC_LOG(LS_ERROR) << "Decoder error for frame_id=" << frame_id
<< ", code=" << error_code;
@@ -362,46 +519,58 @@ void DefaultVideoQualityAnalyzer::Stop() {
// between freezes.
rtc::CritScope crit1(&lock_);
rtc::CritScope crit2(&comparison_lock_);
- for (auto& item : stream_stats_) {
- const StreamState& state = stream_states_[item.first];
- // If there are no freezes in the call we have to report
- // time_between_freezes_ms as call duration and in such case
- // |stream_last_freeze_end_time_| for this stream will be |start_time_|.
- // If there is freeze, then we need add time from last rendered frame
- // to last freeze end as time between freezes.
- if (state.last_rendered_frame_time()) {
- item.second.time_between_freezes_ms.AddSample(
- (state.last_rendered_frame_time().value() -
- stream_last_freeze_end_time_.at(item.first))
- .ms());
+ for (auto& state_entry : stream_states_) {
+ const size_t stream_index = state_entry.first;
+ const StreamState& stream_state = state_entry.second;
+ for (size_t i = 0; i < peers_->size(); ++i) {
+ if (i == static_cast<size_t>(stream_state.owner())) {
+ continue;
+ }
+
+ InternalStatsKey stats_key(stream_index, stream_state.owner(), i);
+
+ // If there are no freezes in the call we have to report
+ // time_between_freezes_ms as call duration and in such case
+ // |stream_last_freeze_end_time_| for this stream will be |start_time_|.
+ // If there is freeze, then we need add time from last rendered frame
+ // to last freeze end as time between freezes.
+ if (stream_state.last_rendered_frame_time(i)) {
+ stream_stats_[stats_key].time_between_freezes_ms.AddSample(
+ stream_state.last_rendered_frame_time(i).value().ms() -
+ stream_last_freeze_end_time_.at(stats_key).ms());
+ }
}
}
+ analyzer_stats_.frames_in_flight_left_count.AddSample(
+ captured_frames_in_flight_.size());
}
ReportResults();
}
std::string DefaultVideoQualityAnalyzer::GetStreamLabel(uint16_t frame_id) {
rtc::CritScope crit1(&lock_);
- auto it = frame_stats_.find(frame_id);
- if (it != frame_stats_.end()) {
- return it->second.stream_label;
+ auto it = captured_frames_in_flight_.find(frame_id);
+ if (it != captured_frames_in_flight_.end()) {
+ return streams_.name(it->second.stream());
}
for (auto hist_it = stream_to_frame_id_history_.begin();
hist_it != stream_to_frame_id_history_.end(); ++hist_it) {
auto hist_set_it = hist_it->second.find(frame_id);
if (hist_set_it != hist_it->second.end()) {
- return hist_it->first;
+ return streams_.name(hist_it->first);
}
}
RTC_CHECK(false) << "Unknown frame_id=" << frame_id;
}
-std::set<std::string> DefaultVideoQualityAnalyzer::GetKnownVideoStreams()
- const {
+std::set<StatsKey> DefaultVideoQualityAnalyzer::GetKnownVideoStreams() const {
+ rtc::CritScope crit1(&lock_);
rtc::CritScope crit2(&comparison_lock_);
- std::set<std::string> out;
+ std::set<StatsKey> out;
for (auto& item : stream_stats_) {
- out.insert(item.first);
+ RTC_LOG(INFO) << item.first.ToString() << " ==> "
+ << ToStatsKey(item.first).ToString();
+ out.insert(ToStatsKey(item.first));
}
return out;
}
@@ -411,16 +580,24 @@ const FrameCounters& DefaultVideoQualityAnalyzer::GetGlobalCounters() const {
return frame_counters_;
}
-const std::map<std::string, FrameCounters>&
+std::map<StatsKey, FrameCounters>
DefaultVideoQualityAnalyzer::GetPerStreamCounters() const {
rtc::CritScope crit(&lock_);
- return stream_frame_counters_;
+ std::map<StatsKey, FrameCounters> out;
+ for (auto& item : stream_frame_counters_) {
+ out.emplace(ToStatsKey(item.first), item.second);
+ }
+ return out;
}
-std::map<std::string, StreamStats> DefaultVideoQualityAnalyzer::GetStats()
- const {
- rtc::CritScope cri(&comparison_lock_);
- return stream_stats_;
+std::map<StatsKey, StreamStats> DefaultVideoQualityAnalyzer::GetStats() const {
+ rtc::CritScope crit1(&lock_);
+ rtc::CritScope crit2(&comparison_lock_);
+ std::map<StatsKey, StreamStats> out;
+ for (auto& item : stream_stats_) {
+ out.emplace(ToStatsKey(item.first), item.second);
+ }
+ return out;
}
AnalyzerStats DefaultVideoQualityAnalyzer::GetAnalyzerStats() const {
@@ -429,25 +606,27 @@ AnalyzerStats DefaultVideoQualityAnalyzer::GetAnalyzerStats() const {
}
void DefaultVideoQualityAnalyzer::AddComparison(
+ InternalStatsKey stats_key,
absl::optional<VideoFrame> captured,
absl::optional<VideoFrame> rendered,
bool dropped,
FrameStats frame_stats) {
StartExcludingCpuThreadTime();
- rtc::CritScope crit(&comparison_lock_);
analyzer_stats_.comparisons_queue_size.AddSample(comparisons_.size());
// If there too many computations waiting in the queue, we won't provide
// frames itself to make future computations lighter.
if (comparisons_.size() >= kMaxActiveComparisons) {
- comparisons_.emplace_back(absl::nullopt, absl::nullopt, dropped,
- frame_stats, OverloadReason::kCpu);
+ comparisons_.emplace_back(std::move(stats_key), absl::nullopt,
+ absl::nullopt, dropped, std::move(frame_stats),
+ OverloadReason::kCpu);
} else {
OverloadReason overload_reason = OverloadReason::kNone;
if (!captured && !dropped) {
overload_reason = OverloadReason::kMemory;
}
- comparisons_.emplace_back(std::move(captured), std::move(rendered), dropped,
- frame_stats, overload_reason);
+ comparisons_.emplace_back(std::move(stats_key), std::move(captured),
+ std::move(rendered), dropped,
+ std::move(frame_stats), overload_reason);
}
comparison_available_event_.Set();
StopExcludingCpuThreadTime();
@@ -507,8 +686,8 @@ void DefaultVideoQualityAnalyzer::ProcessComparison(
const FrameStats& frame_stats = comparison.frame_stats;
rtc::CritScope crit(&comparison_lock_);
- auto stats_it = stream_stats_.find(frame_stats.stream_label);
- RTC_CHECK(stats_it != stream_stats_.end());
+ auto stats_it = stream_stats_.find(comparison.stats_key);
+ RTC_CHECK(stats_it != stream_stats_.end()) << comparison.stats_key.ToString();
StreamStats* stats = &stats_it->second;
analyzer_stats_.comparisons_done++;
if (comparison.overload_reason == OverloadReason::kCpu) {
@@ -561,7 +740,7 @@ void DefaultVideoQualityAnalyzer::ProcessComparison(
3 * average_time_between_rendered_frames_ms)) {
stats->freeze_time_ms.AddSample(time_between_rendered_frames.ms());
auto freeze_end_it =
- stream_last_freeze_end_time_.find(frame_stats.stream_label);
+ stream_last_freeze_end_time_.find(comparison.stats_key);
RTC_DCHECK(freeze_end_it != stream_last_freeze_end_time_.end());
stats->time_between_freezes_ms.AddSample(
(frame_stats.prev_frame_rendered_time - freeze_end_it->second)
@@ -578,15 +757,16 @@ void DefaultVideoQualityAnalyzer::ReportResults() {
rtc::CritScope crit1(&lock_);
rtc::CritScope crit2(&comparison_lock_);
for (auto& item : stream_stats_) {
- ReportResults(GetTestCaseName(item.first), item.second,
- stream_frame_counters_.at(item.first));
+ ReportResults(GetTestCaseName(StatsKeyToMetricName(ToStatsKey(item.first))),
+ item.second, stream_frame_counters_.at(item.first));
}
test::PrintResult("cpu_usage", "", test_label_.c_str(), GetCpuUsagePercent(),
"%", false, ImproveDirection::kSmallerIsBetter);
LogFrameCounters("Global", frame_counters_);
for (auto& item : stream_stats_) {
- LogFrameCounters(item.first, stream_frame_counters_.at(item.first));
- LogStreamInternalStats(item.first, item.second);
+ LogFrameCounters(ToStatsKey(item.first).ToString(),
+ stream_frame_counters_.at(item.first));
+ LogStreamInternalStats(ToStatsKey(item.first).ToString(), item.second);
}
if (!analyzer_stats_.comparisons_queue_size.IsEmpty()) {
RTC_LOG(INFO) << "comparisons_queue_size min="
@@ -714,6 +894,20 @@ Timestamp DefaultVideoQualityAnalyzer::Now() {
return clock_->CurrentTime();
}
+StatsKey DefaultVideoQualityAnalyzer::ToStatsKey(
+ const InternalStatsKey& key) const {
+ return StatsKey(streams_.name(key.stream), peers_->name(key.sender),
+ peers_->name(key.receiver));
+}
+
+std::string DefaultVideoQualityAnalyzer::StatsKeyToMetricName(
+ const StatsKey& key) {
+ if (peers_->size() <= 2) {
+ return key.stream_label;
+ }
+ return key.ToString();
+}
+
void DefaultVideoQualityAnalyzer::StartMeasuringCpuProcessTime() {
rtc::CritScope lock(&cpu_measurement_lock_);
cpu_time_ -= rtc::GetProcessCpuTimeNanos();
@@ -741,35 +935,208 @@ double DefaultVideoQualityAnalyzer::GetCpuUsagePercent() {
return static_cast<double>(cpu_time_) / wallclock_time_ * 100.0;
}
-DefaultVideoQualityAnalyzer::FrameStats::FrameStats(std::string stream_label,
- Timestamp captured_time)
- : stream_label(std::move(stream_label)), captured_time(captured_time) {}
-
DefaultVideoQualityAnalyzer::FrameComparison::FrameComparison(
+ InternalStatsKey stats_key,
absl::optional<VideoFrame> captured,
absl::optional<VideoFrame> rendered,
bool dropped,
FrameStats frame_stats,
OverloadReason overload_reason)
- : captured(std::move(captured)),
+ : stats_key(std::move(stats_key)),
+ captured(std::move(captured)),
rendered(std::move(rendered)),
dropped(dropped),
frame_stats(std::move(frame_stats)),
overload_reason(overload_reason) {}
-uint16_t DefaultVideoQualityAnalyzer::StreamState::PopFront() {
- uint16_t frame_id = frame_ids_.front();
- frame_ids_.pop_front();
- if (dead_frames_count_ > 0) {
- dead_frames_count_--;
+uint16_t DefaultVideoQualityAnalyzer::StreamState::PopFront(size_t peer) {
+ absl::optional<uint16_t> frame_id = frame_ids_.PopFront(peer);
+ RTC_DCHECK(frame_id.has_value());
+
+ // If alive's frame queue is longer than all others, than also pop frame from
+ // it, because that frame is received by all receivers.
+ size_t owner_size = frame_ids_.size(owner_);
+ size_t other_size = 0;
+ for (size_t i = 0; i < frame_ids_.readers_count(); ++i) {
+ size_t cur_size = frame_ids_.size(i);
+ if (i != owner_ && cur_size > other_size) {
+ other_size = cur_size;
+ }
}
- return frame_id;
+ if (owner_size > other_size) {
+ absl::optional<uint16_t> alive_frame_id = frame_ids_.PopFront(owner_);
+ RTC_DCHECK(alive_frame_id.has_value());
+ RTC_DCHECK_EQ(frame_id.value(), alive_frame_id.value());
+ }
+
+ return frame_id.value();
}
uint16_t DefaultVideoQualityAnalyzer::StreamState::MarkNextAliveFrameAsDead() {
- uint16_t frame_id = frame_ids_[dead_frames_count_];
- dead_frames_count_++;
- return frame_id;
+ absl::optional<uint16_t> frame_id = frame_ids_.PopFront(owner_);
+ RTC_DCHECK(frame_id.has_value());
+ return frame_id.value();
+}
+
+void DefaultVideoQualityAnalyzer::StreamState::SetLastRenderedFrameTime(
+ size_t peer,
+ Timestamp time) {
+ auto it = last_rendered_frame_time_.find(peer);
+ if (it == last_rendered_frame_time_.end()) {
+ last_rendered_frame_time_.insert({peer, time});
+ } else {
+ it->second = time;
+ }
+}
+
+absl::optional<Timestamp>
+DefaultVideoQualityAnalyzer::StreamState::last_rendered_frame_time(
+ size_t peer) const {
+ return MaybeGetValue(last_rendered_frame_time_, peer);
+}
+
+bool DefaultVideoQualityAnalyzer::FrameInFlight::RemoveFrame() {
+ if (!frame_) {
+ return false;
+ }
+ frame_ = absl::nullopt;
+ return true;
+}
+
+void DefaultVideoQualityAnalyzer::FrameInFlight::SetFrameId(uint16_t id) {
+ if (frame_) {
+ frame_->set_id(id);
+ }
+}
+
+std::vector<size_t>
+DefaultVideoQualityAnalyzer::FrameInFlight::GetPeersWhichDidntReceive() const {
+ std::vector<size_t> out;
+ for (size_t i = 0; i < peers_count_; ++i) {
+ auto it = receiver_stats_.find(i);
+ if (i != owner_ && it != receiver_stats_.end() &&
+ it->second.rendered_time.IsInfinite()) {
+ out.push_back(i);
+ }
+ }
+ return out;
+}
+
+bool DefaultVideoQualityAnalyzer::FrameInFlight::HaveAllPeersReceived() const {
+ for (size_t i = 0; i < peers_count_; ++i) {
+ if (i == owner_) {
+ continue;
+ }
+
+ auto it = receiver_stats_.find(i);
+ if (it == receiver_stats_.end()) {
+ return false;
+ }
+
+ if (!it->second.dropped && it->second.rendered_time.IsInfinite()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void DefaultVideoQualityAnalyzer::FrameInFlight::OnFrameEncoded(
+ webrtc::Timestamp time,
+ int64_t encoded_image_size,
+ uint32_t target_encode_bitrate) {
+ encoded_time_ = time;
+ encoded_image_size_ = encoded_image_size;
+ target_encode_bitrate_ += target_encode_bitrate;
+}
+
+void DefaultVideoQualityAnalyzer::FrameInFlight::OnFramePreDecode(
+ size_t peer,
+ webrtc::Timestamp received_time,
+ webrtc::Timestamp decode_start_time) {
+ receiver_stats_[peer].received_time = received_time;
+ receiver_stats_[peer].decode_start_time = decode_start_time;
+}
+
+bool DefaultVideoQualityAnalyzer::FrameInFlight::HasReceivedTime(
+ size_t peer) const {
+ auto it = receiver_stats_.find(peer);
+ if (it == receiver_stats_.end()) {
+ return false;
+ }
+ return it->second.received_time.IsFinite();
+}
+
+bool DefaultVideoQualityAnalyzer::FrameInFlight::HasDecodeEndTime(
+ size_t peer) const {
+ auto it = receiver_stats_.find(peer);
+ if (it == receiver_stats_.end()) {
+ return false;
+ }
+ return it->second.decode_end_time.IsFinite();
+}
+
+void DefaultVideoQualityAnalyzer::FrameInFlight::OnFrameRendered(
+ size_t peer,
+ webrtc::Timestamp time,
+ int width,
+ int height) {
+ receiver_stats_[peer].rendered_time = time;
+ receiver_stats_[peer].rendered_frame_width = width;
+ receiver_stats_[peer].rendered_frame_height = height;
+}
+
+bool DefaultVideoQualityAnalyzer::FrameInFlight::HasRenderedTime(
+ size_t peer) const {
+ auto it = receiver_stats_.find(peer);
+ if (it == receiver_stats_.end()) {
+ return false;
+ }
+ return it->second.rendered_time.IsFinite();
+}
+
+DefaultVideoQualityAnalyzer::FrameStats
+DefaultVideoQualityAnalyzer::FrameInFlight::GetStatsForPeer(size_t peer) const {
+ FrameStats stats(captured_time_);
+ stats.pre_encode_time = pre_encode_time_;
+ stats.encoded_time = encoded_time_;
+ stats.target_encode_bitrate = target_encode_bitrate_;
+ stats.encoded_image_size = encoded_image_size_;
+
+ absl::optional<ReceiverFrameStats> receiver_stats =
+ MaybeGetValue<ReceiverFrameStats>(receiver_stats_, peer);
+ if (receiver_stats.has_value()) {
+ stats.received_time = receiver_stats->received_time;
+ stats.decode_start_time = receiver_stats->decode_start_time;
+ stats.decode_end_time = receiver_stats->decode_end_time;
+ stats.rendered_time = receiver_stats->rendered_time;
+ stats.prev_frame_rendered_time = receiver_stats->prev_frame_rendered_time;
+ stats.rendered_frame_width = receiver_stats->rendered_frame_width;
+ stats.rendered_frame_height = receiver_stats->rendered_frame_height;
+ }
+ return stats;
+}
+
+size_t DefaultVideoQualityAnalyzer::NamesCollection::AddIfAbsent(
+ absl::string_view name) {
+ auto it = index_.find(name);
+ if (it != index_.end()) {
+ return it->second;
+ }
+ size_t out = names_.size();
+ size_t old_capacity = names_.capacity();
+ names_.emplace_back(name);
+ size_t new_capacity = names_.capacity();
+
+ if (old_capacity == new_capacity) {
+ index_.emplace(names_[out], out);
+ } else {
+ // Reallocation happened in the vector, so we need to rebuild |index_|
+ index_.clear();
+ for (size_t i = 0; i < names_.size(); ++i) {
+ index_.emplace(names_[i], i);
+ }
+ }
+ return out;
}
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
index 6bebb0f02b2..95049b10548 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
@@ -19,6 +19,7 @@
#include <string>
#include <vector>
+#include "api/array_view.h"
#include "api/test/video_quality_analyzer_interface.h"
#include "api/units/timestamp.h"
#include "api/video/encoded_image.h"
@@ -28,6 +29,7 @@
#include "rtc_base/numerics/samples_stats_counter.h"
#include "rtc_base/platform_thread.h"
#include "system_wrappers/include/clock.h"
+#include "test/pc/e2e/analyzer/video/multi_head_queue.h"
#include "test/testsupport/perf_test.h"
namespace webrtc {
@@ -36,7 +38,7 @@ namespace webrtc_pc_e2e {
// WebRTC will request a key frame after 3 seconds if no frames were received.
// We assume max frame rate ~60 fps, so 270 frames will cover max freeze without
// key frame request.
-constexpr int kDefaultMaxFramesInFlightPerStream = 270;
+constexpr size_t kDefaultMaxFramesInFlightPerStream = 270;
class RateCounter {
public:
@@ -124,52 +126,102 @@ struct AnalyzerStats {
// it is queued when its captured frame was already removed due to high memory
// usage for that video stream.
int64_t memory_overloaded_comparisons_done = 0;
+ // Count of frames in flight in analyzer measured when new comparison is added
+ // and after analyzer was stopped.
+ SamplesStatsCounter frames_in_flight_left_count;
};
+struct StatsKey {
+ StatsKey(std::string stream_label, std::string sender, std::string receiver)
+ : stream_label(std::move(stream_label)),
+ sender(std::move(sender)),
+ receiver(std::move(receiver)) {}
+
+ std::string ToString() const;
+
+ // Label of video stream to which stats belongs to.
+ std::string stream_label;
+ // Name of the peer which send this stream.
+ std::string sender;
+ // Name of the peer on which stream was received.
+ std::string receiver;
+};
+
+// Required to use StatsKey as std::map key.
+bool operator<(const StatsKey& a, const StatsKey& b);
+bool operator==(const StatsKey& a, const StatsKey& b);
+
+struct InternalStatsKey {
+ InternalStatsKey(size_t stream, size_t sender, size_t receiver)
+ : stream(stream), sender(sender), receiver(receiver) {}
+
+ std::string ToString() const;
+
+ size_t stream;
+ size_t sender;
+ size_t receiver;
+};
+
+// Required to use InternalStatsKey as std::map key.
+bool operator<(const InternalStatsKey& a, const InternalStatsKey& b);
+bool operator==(const InternalStatsKey& a, const InternalStatsKey& b);
+
class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
public:
explicit DefaultVideoQualityAnalyzer(
bool heavy_metrics_computation_enabled = true,
- int max_frames_in_flight_per_stream_count =
+ size_t max_frames_in_flight_per_stream_count =
kDefaultMaxFramesInFlightPerStream);
~DefaultVideoQualityAnalyzer() override;
- void Start(std::string test_case_name, int max_threads_count) override;
- uint16_t OnFrameCaptured(const std::string& stream_label,
+ void Start(std::string test_case_name,
+ rtc::ArrayView<const std::string> peer_names,
+ int max_threads_count) override;
+ uint16_t OnFrameCaptured(absl::string_view peer_name,
+ const std::string& stream_label,
const VideoFrame& frame) override;
- void OnFramePreEncode(const VideoFrame& frame) override;
- void OnFrameEncoded(uint16_t frame_id,
+ void OnFramePreEncode(absl::string_view peer_name,
+ const VideoFrame& frame) override;
+ void OnFrameEncoded(absl::string_view peer_name,
+ uint16_t frame_id,
const EncodedImage& encoded_image,
const EncoderStats& stats) override;
- void OnFrameDropped(EncodedImageCallback::DropReason reason) override;
- void OnFramePreDecode(uint16_t frame_id,
+ void OnFrameDropped(absl::string_view peer_name,
+ EncodedImageCallback::DropReason reason) override;
+ void OnFramePreDecode(absl::string_view peer_name,
+ uint16_t frame_id,
const EncodedImage& input_image) override;
- void OnFrameDecoded(const VideoFrame& frame,
+ void OnFrameDecoded(absl::string_view peer_name,
+ const VideoFrame& frame,
const DecoderStats& stats) override;
- void OnFrameRendered(const VideoFrame& frame) override;
- void OnEncoderError(const VideoFrame& frame, int32_t error_code) override;
- void OnDecoderError(uint16_t frame_id, int32_t error_code) override;
+ void OnFrameRendered(absl::string_view peer_name,
+ const VideoFrame& frame) override;
+ void OnEncoderError(absl::string_view peer_name,
+ const VideoFrame& frame,
+ int32_t error_code) override;
+ void OnDecoderError(absl::string_view peer_name,
+ uint16_t frame_id,
+ int32_t error_code) override;
void Stop() override;
std::string GetStreamLabel(uint16_t frame_id) override;
- void OnStatsReports(const std::string& pc_label,
- const StatsReports& stats_reports) override {}
+ void OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override {}
// Returns set of stream labels, that were met during test call.
- std::set<std::string> GetKnownVideoStreams() const;
+ std::set<StatsKey> GetKnownVideoStreams() const;
const FrameCounters& GetGlobalCounters() const;
// Returns frame counter per stream label. Valid stream labels can be obtained
// by calling GetKnownVideoStreams()
- const std::map<std::string, FrameCounters>& GetPerStreamCounters() const;
+ std::map<StatsKey, FrameCounters> GetPerStreamCounters() const;
// Returns video quality stats per stream label. Valid stream labels can be
// obtained by calling GetKnownVideoStreams()
- std::map<std::string, StreamStats> GetStats() const;
+ std::map<StatsKey, StreamStats> GetStats() const;
AnalyzerStats GetAnalyzerStats() const;
private:
struct FrameStats {
- FrameStats(std::string stream_label, Timestamp captured_time);
-
- std::string stream_label;
+ FrameStats(Timestamp captured_time) : captured_time(captured_time) {}
// Frame events timestamp.
Timestamp captured_time;
@@ -182,12 +234,11 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
Timestamp rendered_time = Timestamp::MinusInfinity();
Timestamp prev_frame_rendered_time = Timestamp::MinusInfinity();
+ int64_t encoded_image_size = 0;
uint32_t target_encode_bitrate = 0;
absl::optional<int> rendered_frame_width = absl::nullopt;
absl::optional<int> rendered_frame_height = absl::nullopt;
-
- int64_t encoded_image_size = 0;
};
// Describes why comparison was done in overloaded mode (without calculating
@@ -209,12 +260,14 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
// because there were too many comparisons in the queue. |dropped| can be
// true or false showing was frame dropped or not.
struct FrameComparison {
- FrameComparison(absl::optional<VideoFrame> captured,
+ FrameComparison(InternalStatsKey stats_key,
+ absl::optional<VideoFrame> captured,
absl::optional<VideoFrame> rendered,
bool dropped,
FrameStats frame_stats,
OverloadReason overload_reason);
+ InternalStatsKey stats_key;
// Frames can be omitted if there too many computations waiting in the
// queue.
absl::optional<VideoFrame> captured;
@@ -230,49 +283,175 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
// Represents a current state of video stream.
class StreamState {
public:
- void PushBack(uint16_t frame_id) { frame_ids_.emplace_back(frame_id); }
-
- uint16_t PopFront();
-
- bool Empty() { return frame_ids_.empty(); }
+ StreamState(size_t owner, size_t peers_count)
+ : owner_(owner), frame_ids_(peers_count) {}
- uint16_t Front() { return frame_ids_.front(); }
+ size_t owner() const { return owner_; }
- int GetAliveFramesCount() { return frame_ids_.size() - dead_frames_count_; }
+ void PushBack(uint16_t frame_id) { frame_ids_.PushBack(frame_id); }
+ // Crash if state is empty.
+ uint16_t PopFront(size_t peer);
+ bool IsEmpty(size_t peer) const { return frame_ids_.IsEmpty(peer); }
+ // Crash if state is empty.
+ uint16_t Front(size_t peer) const { return frame_ids_.Front(peer).value(); }
+ size_t GetAliveFramesCount() { return frame_ids_.size(owner_); }
uint16_t MarkNextAliveFrameAsDead();
- void set_last_rendered_frame_time(Timestamp time) {
- last_rendered_frame_time_ = time;
- }
- absl::optional<Timestamp> last_rendered_frame_time() const {
- return last_rendered_frame_time_;
- }
+ void SetLastRenderedFrameTime(size_t peer, Timestamp time);
+ absl::optional<Timestamp> last_rendered_frame_time(size_t peer) const;
private:
+ // Index of the owner. Owner's queue in |frame_ids_| will keep alive frames.
+ const size_t owner_;
// To correctly determine dropped frames we have to know sequence of frames
// in each stream so we will keep a list of frame ids inside the stream.
- // When the frame is rendered, we will pop ids from the list for until id
- // will match with rendered one. All ids before matched one can be
- // considered as dropped:
+ // This list is represented by multi head queue of frame ids with separate
+ // head for each receiver. When the frame is rendered, we will pop ids from
+ // the corresponding head until id will match with rendered one. All ids
+ // before matched one can be considered as dropped:
//
// | frame_id1 |->| frame_id2 |->| frame_id3 |->| frame_id4 |
//
// If we received frame with id frame_id3, then we will pop frame_id1 and
// frame_id2 and consider that frames as dropped and then compare received
// frame with the one from |captured_frames_in_flight_| with id frame_id3.
- std::deque<uint16_t> frame_ids_;
- // Count of dead frames in the beginning of the deque.
- int dead_frames_count_;
- absl::optional<Timestamp> last_rendered_frame_time_ = absl::nullopt;
+ //
+ // To track alive frames (frames that contains frame's payload in
+ // |captured_frames_in_flight_|) the head which corresponds to |owner_| will
+ // be used. So that head will point to the first alive frame in frames list.
+ MultiHeadQueue<uint16_t> frame_ids_;
+ std::map<size_t, Timestamp> last_rendered_frame_time_;
};
enum State { kNew, kActive, kStopped };
- void AddComparison(absl::optional<VideoFrame> captured,
+ struct ReceiverFrameStats {
+ // Time when last packet of a frame was received.
+ Timestamp received_time = Timestamp::MinusInfinity();
+ Timestamp decode_start_time = Timestamp::MinusInfinity();
+ Timestamp decode_end_time = Timestamp::MinusInfinity();
+ Timestamp rendered_time = Timestamp::MinusInfinity();
+ Timestamp prev_frame_rendered_time = Timestamp::MinusInfinity();
+
+ absl::optional<int> rendered_frame_width = absl::nullopt;
+ absl::optional<int> rendered_frame_height = absl::nullopt;
+
+ bool dropped = false;
+ };
+
+ class FrameInFlight {
+ public:
+ FrameInFlight(size_t stream,
+ VideoFrame frame,
+ Timestamp captured_time,
+ size_t owner,
+ size_t peers_count)
+ : stream_(stream),
+ owner_(owner),
+ peers_count_(peers_count),
+ frame_(std::move(frame)),
+ captured_time_(captured_time) {}
+
+ size_t stream() const { return stream_; }
+ const absl::optional<VideoFrame>& frame() const { return frame_; }
+ // Returns was frame removed or not.
+ bool RemoveFrame();
+ void SetFrameId(uint16_t id);
+
+ std::vector<size_t> GetPeersWhichDidntReceive() const;
+ bool HaveAllPeersReceived() const;
+
+ void SetPreEncodeTime(webrtc::Timestamp time) { pre_encode_time_ = time; }
+
+ void OnFrameEncoded(webrtc::Timestamp time,
+ int64_t encoded_image_size,
+ uint32_t target_encode_bitrate);
+
+ bool HasEncodedTime() const { return encoded_time_.IsFinite(); }
+
+ void OnFramePreDecode(size_t peer,
+ webrtc::Timestamp received_time,
+ webrtc::Timestamp decode_start_time);
+
+ bool HasReceivedTime(size_t peer) const;
+
+ void SetDecodeEndTime(size_t peer, webrtc::Timestamp time) {
+ receiver_stats_[peer].decode_end_time = time;
+ }
+
+ bool HasDecodeEndTime(size_t peer) const;
+
+ void OnFrameRendered(size_t peer,
+ webrtc::Timestamp time,
+ int width,
+ int height);
+
+ bool HasRenderedTime(size_t peer) const;
+
+ // Crash if rendered time is not set for specified |peer|.
+ webrtc::Timestamp rendered_time(size_t peer) const {
+ return receiver_stats_.at(peer).rendered_time;
+ }
+
+ void MarkDropped(size_t peer) { receiver_stats_[peer].dropped = true; }
+
+ void SetPrevFrameRenderedTime(size_t peer, webrtc::Timestamp time) {
+ receiver_stats_[peer].prev_frame_rendered_time = time;
+ }
+
+ FrameStats GetStatsForPeer(size_t peer) const;
+
+ private:
+ const size_t stream_;
+ const size_t owner_;
+ const size_t peers_count_;
+ absl::optional<VideoFrame> frame_;
+
+ // Frame events timestamp.
+ Timestamp captured_time_;
+ Timestamp pre_encode_time_ = Timestamp::MinusInfinity();
+ Timestamp encoded_time_ = Timestamp::MinusInfinity();
+ int64_t encoded_image_size_ = 0;
+ uint32_t target_encode_bitrate_ = 0;
+ std::map<size_t, ReceiverFrameStats> receiver_stats_;
+ };
+
+ class NamesCollection {
+ public:
+ NamesCollection() = default;
+ explicit NamesCollection(rtc::ArrayView<const std::string> names) {
+ names_ = std::vector<std::string>(names.begin(), names.end());
+ for (size_t i = 0; i < names_.size(); ++i) {
+ index_.emplace(names_[i], i);
+ }
+ }
+
+ size_t size() const { return names_.size(); }
+
+ size_t index(absl::string_view name) const { return index_.at(name); }
+
+ const std::string& name(size_t index) const { return names_[index]; }
+
+ bool HasName(absl::string_view name) const {
+ return index_.find(name) != index_.end();
+ }
+
+ // Add specified |name| to the collection if it isn't presented.
+ // Returns index which corresponds to specified |name|.
+ size_t AddIfAbsent(absl::string_view name);
+
+ private:
+ std::vector<std::string> names_;
+ std::map<absl::string_view, size_t> index_;
+ };
+
+ void AddComparison(InternalStatsKey stats_key,
+ absl::optional<VideoFrame> captured,
absl::optional<VideoFrame> rendered,
bool dropped,
- FrameStats frame_stats);
+ FrameStats frame_stats)
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(comparison_lock_);
static void ProcessComparisonsThread(void* obj);
void ProcessComparisons();
void ProcessComparison(const FrameComparison& comparison);
@@ -292,6 +471,11 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
// Returns name of current test case for reporting.
std::string GetTestCaseName(const std::string& stream_label) const;
Timestamp Now();
+ StatsKey ToStatsKey(const InternalStatsKey& key) const
+ RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ // Returns string representation of stats key for metrics naming. Used for
+ // backward compatibility by metrics naming for 2 peers cases.
+ std::string StatsKeyToMetricName(const StatsKey& key);
void StartMeasuringCpuProcessTime();
void StopMeasuringCpuProcessTime();
@@ -300,15 +484,19 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
double GetCpuUsagePercent();
const bool heavy_metrics_computation_enabled_;
- const int max_frames_in_flight_per_stream_count_;
+ const size_t max_frames_in_flight_per_stream_count_;
webrtc::Clock* const clock_;
std::atomic<uint16_t> next_frame_id_{0};
std::string test_label_;
+ std::unique_ptr<NamesCollection> peers_;
rtc::CriticalSection lock_;
State state_ RTC_GUARDED_BY(lock_) = State::kNew;
Timestamp start_time_ RTC_GUARDED_BY(lock_) = Timestamp::MinusInfinity();
+ // Mapping from stream label to unique size_t value to use in stats and avoid
+ // extra string copying.
+ NamesCollection streams_ RTC_GUARDED_BY(lock_);
// Frames that were captured by all streams and still aren't rendered by any
// stream or deemed dropped. Frame with id X can be removed from this map if:
// 1. The frame with id X was received in OnFrameRendered
@@ -316,27 +504,29 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
// 3. Next available frame id for newly captured frame is X
// 4. There too many frames in flight for current video stream and X is the
// oldest frame id in this stream.
- std::map<uint16_t, VideoFrame> captured_frames_in_flight_
+ std::map<uint16_t, FrameInFlight> captured_frames_in_flight_
RTC_GUARDED_BY(lock_);
// Global frames count for all video streams.
FrameCounters frame_counters_ RTC_GUARDED_BY(lock_);
- // Frame counters per each stream.
- std::map<std::string, FrameCounters> stream_frame_counters_
+ // Frame counters per each stream per each receiver.
+ std::map<InternalStatsKey, FrameCounters> stream_frame_counters_
RTC_GUARDED_BY(lock_);
- std::map<uint16_t, FrameStats> frame_stats_ RTC_GUARDED_BY(lock_);
- std::map<std::string, StreamState> stream_states_ RTC_GUARDED_BY(lock_);
-
- // Stores history mapping between stream labels and frame ids. Updated when
- // frame id overlap. It required to properly return stream label after 1st
- // frame from simulcast streams was already rendered and last is still
- // encoding.
- std::map<std::string, std::set<uint16_t>> stream_to_frame_id_history_
+ // Map from stream index in |streams_| to its StreamState.
+ std::map<size_t, StreamState> stream_states_ RTC_GUARDED_BY(lock_);
+ // Map from stream index in |streams_| to sender peer index in |peers_|.
+ std::map<size_t, size_t> stream_to_sender_ RTC_GUARDED_BY(lock_);
+
+ // Stores history mapping between stream index in |streams_| and frame ids.
+ // Updated when frame id overlap. It required to properly return stream label
+ // after 1st frame from simulcast streams was already rendered and last is
+ // still encoding.
+ std::map<size_t, std::set<uint16_t>> stream_to_frame_id_history_
RTC_GUARDED_BY(lock_);
rtc::CriticalSection comparison_lock_;
- std::map<std::string, StreamStats> stream_stats_
+ std::map<InternalStatsKey, StreamStats> stream_stats_
RTC_GUARDED_BY(comparison_lock_);
- std::map<std::string, Timestamp> stream_last_freeze_end_time_
+ std::map<InternalStatsKey, Timestamp> stream_last_freeze_end_time_
RTC_GUARDED_BY(comparison_lock_);
std::deque<FrameComparison> comparisons_ RTC_GUARDED_BY(comparison_lock_);
AnalyzerStats analyzer_stats_ RTC_GUARDED_BY(comparison_lock_);
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
index 1bc29c5f091..55cc438b9d0 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc
@@ -18,6 +18,7 @@
#include "api/video/encoded_image.h"
#include "api/video/i420_buffer.h"
#include "api/video/video_frame.h"
+#include "rtc_base/strings/string_builder.h"
#include "system_wrappers/include/sleep.h"
#include "test/gtest.h"
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer.h"
@@ -26,11 +27,15 @@ namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
+using StatsSample = ::webrtc::SamplesStatsCounter::StatsSample;
+
constexpr int kAnalyzerMaxThreadsCount = 1;
constexpr int kMaxFramesInFlightPerStream = 10;
constexpr int kFrameWidth = 320;
constexpr int kFrameHeight = 240;
constexpr char kStreamLabel[] = "video-stream";
+constexpr char kSenderPeerName[] = "alice";
+constexpr char kReceiverPeerName[] = "bob";
VideoFrame NextFrame(test::FrameGeneratorInterface* frame_generator,
int64_t timestamp_us) {
@@ -64,6 +69,24 @@ VideoFrame DeepCopy(const VideoFrame& frame) {
return copy;
}
+std::vector<StatsSample> GetSortedSamples(const SamplesStatsCounter& counter) {
+ rtc::ArrayView<const StatsSample> view = counter.GetTimedSamples();
+ std::vector<StatsSample> out(view.begin(), view.end());
+ std::sort(out.begin(), out.end(),
+ [](const StatsSample& a, const StatsSample& b) {
+ return a.time < b.time;
+ });
+ return out;
+}
+
+std::string ToString(const std::vector<StatsSample>& values) {
+ rtc::StringBuilder out;
+ for (const auto& v : values) {
+ out << "{ time_ms=" << v.time.ms() << "; value=" << v.value << "}, ";
+ }
+ return out.str();
+}
+
TEST(DefaultVideoQualityAnalyzerTest,
MemoryOverloadedAndThenAllFramesReceived) {
std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
@@ -73,26 +96,30 @@ TEST(DefaultVideoQualityAnalyzerTest,
DefaultVideoQualityAnalyzer analyzer(
/*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream);
- analyzer.Start("test_case", kAnalyzerMaxThreadsCount);
+ analyzer.Start("test_case",
+ std::vector<std::string>{kSenderPeerName, kReceiverPeerName},
+ kAnalyzerMaxThreadsCount);
std::map<uint16_t, VideoFrame> captured_frames;
std::vector<uint16_t> frames_order;
for (int i = 0; i < kMaxFramesInFlightPerStream * 2; ++i) {
VideoFrame frame = NextFrame(frame_generator.get(), i);
- frame.set_id(analyzer.OnFrameCaptured(kStreamLabel, frame));
+ frame.set_id(
+ analyzer.OnFrameCaptured(kSenderPeerName, kStreamLabel, frame));
frames_order.push_back(frame.id());
captured_frames.insert({frame.id(), frame});
- analyzer.OnFramePreEncode(frame);
- analyzer.OnFrameEncoded(frame.id(), FakeEncode(frame),
+ analyzer.OnFramePreEncode(kSenderPeerName, frame);
+ analyzer.OnFrameEncoded(kSenderPeerName, frame.id(), FakeEncode(frame),
VideoQualityAnalyzerInterface::EncoderStats());
}
for (const uint16_t& frame_id : frames_order) {
VideoFrame received_frame = DeepCopy(captured_frames.at(frame_id));
- analyzer.OnFramePreDecode(received_frame.id(), FakeEncode(received_frame));
- analyzer.OnFrameDecoded(received_frame,
+ analyzer.OnFramePreDecode(kReceiverPeerName, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kReceiverPeerName, received_frame,
VideoQualityAnalyzerInterface::DecoderStats());
- analyzer.OnFrameRendered(received_frame);
+ analyzer.OnFrameRendered(kReceiverPeerName, received_frame);
}
// Give analyzer some time to process frames on async thread. The computations
@@ -112,6 +139,87 @@ TEST(DefaultVideoQualityAnalyzerTest,
}
TEST(DefaultVideoQualityAnalyzerTest,
+ FillMaxMemoryReceiveAllMemoryOverloadedAndThenAllFramesReceived) {
+ std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
+ test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
+ /*type=*/absl::nullopt,
+ /*num_squares=*/absl::nullopt);
+
+ DefaultVideoQualityAnalyzer analyzer(
+ /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream);
+ analyzer.Start("test_case",
+ std::vector<std::string>{kSenderPeerName, kReceiverPeerName},
+ kAnalyzerMaxThreadsCount);
+
+ std::map<uint16_t, VideoFrame> captured_frames;
+ std::vector<uint16_t> frames_order;
+ // Feel analyzer's memory up to limit
+ for (int i = 0; i < kMaxFramesInFlightPerStream; ++i) {
+ VideoFrame frame = NextFrame(frame_generator.get(), i);
+ frame.set_id(
+ analyzer.OnFrameCaptured(kSenderPeerName, kStreamLabel, frame));
+ frames_order.push_back(frame.id());
+ captured_frames.insert({frame.id(), frame});
+ analyzer.OnFramePreEncode(kSenderPeerName, frame);
+ analyzer.OnFrameEncoded(kSenderPeerName, frame.id(), FakeEncode(frame),
+ VideoQualityAnalyzerInterface::EncoderStats());
+ }
+
+ // Receive all frames.
+ for (const uint16_t& frame_id : frames_order) {
+ VideoFrame received_frame = DeepCopy(captured_frames.at(frame_id));
+ analyzer.OnFramePreDecode(kReceiverPeerName, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kReceiverPeerName, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ analyzer.OnFrameRendered(kReceiverPeerName, received_frame);
+ }
+ frames_order.clear();
+
+ // Give analyzer some time to process frames on async thread. The computations
+ // have to be fast (heavy metrics are disabled!), so if doesn't fit 100ms it
+ // means we have an issue!
+ SleepMs(100);
+
+ // Overload analyzer's memory up to limit
+ for (int i = 0; i < 2 * kMaxFramesInFlightPerStream; ++i) {
+ VideoFrame frame = NextFrame(frame_generator.get(), i);
+ frame.set_id(
+ analyzer.OnFrameCaptured(kSenderPeerName, kStreamLabel, frame));
+ frames_order.push_back(frame.id());
+ captured_frames.insert({frame.id(), frame});
+ analyzer.OnFramePreEncode(kSenderPeerName, frame);
+ analyzer.OnFrameEncoded(kSenderPeerName, frame.id(), FakeEncode(frame),
+ VideoQualityAnalyzerInterface::EncoderStats());
+ }
+
+ // Receive all frames.
+ for (const uint16_t& frame_id : frames_order) {
+ VideoFrame received_frame = DeepCopy(captured_frames.at(frame_id));
+ analyzer.OnFramePreDecode(kReceiverPeerName, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kReceiverPeerName, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ analyzer.OnFrameRendered(kReceiverPeerName, received_frame);
+ }
+
+ // Give analyzer some time to process frames on async thread. The computations
+ // have to be fast (heavy metrics are disabled!), so if doesn't fit 100ms it
+ // means we have an issue!
+ SleepMs(100);
+ analyzer.Stop();
+
+ AnalyzerStats stats = analyzer.GetAnalyzerStats();
+ EXPECT_EQ(stats.memory_overloaded_comparisons_done,
+ kMaxFramesInFlightPerStream);
+ EXPECT_EQ(stats.comparisons_done, kMaxFramesInFlightPerStream * 3);
+ FrameCounters frame_counters = analyzer.GetGlobalCounters();
+ EXPECT_EQ(frame_counters.captured, kMaxFramesInFlightPerStream * 3);
+ EXPECT_EQ(frame_counters.rendered, kMaxFramesInFlightPerStream * 3);
+ EXPECT_EQ(frame_counters.dropped, 0);
+}
+
+TEST(DefaultVideoQualityAnalyzerTest,
MemoryOverloadedHalfDroppedAndThenHalfFramesReceived) {
std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
@@ -120,27 +228,31 @@ TEST(DefaultVideoQualityAnalyzerTest,
DefaultVideoQualityAnalyzer analyzer(
/*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream);
- analyzer.Start("test_case", kAnalyzerMaxThreadsCount);
+ analyzer.Start("test_case",
+ std::vector<std::string>{kSenderPeerName, kReceiverPeerName},
+ kAnalyzerMaxThreadsCount);
std::map<uint16_t, VideoFrame> captured_frames;
std::vector<uint16_t> frames_order;
for (int i = 0; i < kMaxFramesInFlightPerStream * 2; ++i) {
VideoFrame frame = NextFrame(frame_generator.get(), i);
- frame.set_id(analyzer.OnFrameCaptured(kStreamLabel, frame));
+ frame.set_id(
+ analyzer.OnFrameCaptured(kSenderPeerName, kStreamLabel, frame));
frames_order.push_back(frame.id());
captured_frames.insert({frame.id(), frame});
- analyzer.OnFramePreEncode(frame);
- analyzer.OnFrameEncoded(frame.id(), FakeEncode(frame),
+ analyzer.OnFramePreEncode(kSenderPeerName, frame);
+ analyzer.OnFrameEncoded(kSenderPeerName, frame.id(), FakeEncode(frame),
VideoQualityAnalyzerInterface::EncoderStats());
}
for (size_t i = kMaxFramesInFlightPerStream; i < frames_order.size(); ++i) {
uint16_t frame_id = frames_order.at(i);
VideoFrame received_frame = DeepCopy(captured_frames.at(frame_id));
- analyzer.OnFramePreDecode(received_frame.id(), FakeEncode(received_frame));
- analyzer.OnFrameDecoded(received_frame,
+ analyzer.OnFramePreDecode(kReceiverPeerName, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kReceiverPeerName, received_frame,
VideoQualityAnalyzerInterface::DecoderStats());
- analyzer.OnFrameRendered(received_frame);
+ analyzer.OnFrameRendered(kReceiverPeerName, received_frame);
}
// Give analyzer some time to process frames on async thread. The computations
@@ -166,27 +278,31 @@ TEST(DefaultVideoQualityAnalyzerTest, NormalScenario) {
DefaultVideoQualityAnalyzer analyzer(
/*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream);
- analyzer.Start("test_case", kAnalyzerMaxThreadsCount);
+ analyzer.Start("test_case",
+ std::vector<std::string>{kSenderPeerName, kReceiverPeerName},
+ kAnalyzerMaxThreadsCount);
std::map<uint16_t, VideoFrame> captured_frames;
std::vector<uint16_t> frames_order;
for (int i = 0; i < kMaxFramesInFlightPerStream; ++i) {
VideoFrame frame = NextFrame(frame_generator.get(), i);
- frame.set_id(analyzer.OnFrameCaptured(kStreamLabel, frame));
+ frame.set_id(
+ analyzer.OnFrameCaptured(kSenderPeerName, kStreamLabel, frame));
frames_order.push_back(frame.id());
captured_frames.insert({frame.id(), frame});
- analyzer.OnFramePreEncode(frame);
- analyzer.OnFrameEncoded(frame.id(), FakeEncode(frame),
+ analyzer.OnFramePreEncode(kSenderPeerName, frame);
+ analyzer.OnFrameEncoded(kSenderPeerName, frame.id(), FakeEncode(frame),
VideoQualityAnalyzerInterface::EncoderStats());
}
for (size_t i = 1; i < frames_order.size(); i += 2) {
uint16_t frame_id = frames_order.at(i);
VideoFrame received_frame = DeepCopy(captured_frames.at(frame_id));
- analyzer.OnFramePreDecode(received_frame.id(), FakeEncode(received_frame));
- analyzer.OnFrameDecoded(received_frame,
+ analyzer.OnFramePreDecode(kReceiverPeerName, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kReceiverPeerName, received_frame,
VideoQualityAnalyzerInterface::DecoderStats());
- analyzer.OnFrameRendered(received_frame);
+ analyzer.OnFrameRendered(kReceiverPeerName, received_frame);
}
// Give analyzer some time to process frames on async thread. The computations
@@ -199,6 +315,11 @@ TEST(DefaultVideoQualityAnalyzerTest, NormalScenario) {
EXPECT_EQ(stats.memory_overloaded_comparisons_done, 0);
EXPECT_EQ(stats.comparisons_done, kMaxFramesInFlightPerStream);
+ std::vector<StatsSample> frames_in_flight_sizes =
+ GetSortedSamples(stats.frames_in_flight_left_count);
+ EXPECT_EQ(frames_in_flight_sizes.back().value, 0)
+ << ToString(frames_in_flight_sizes);
+
FrameCounters frame_counters = analyzer.GetGlobalCounters();
EXPECT_EQ(frame_counters.captured, kMaxFramesInFlightPerStream);
EXPECT_EQ(frame_counters.received, kMaxFramesInFlightPerStream / 2);
@@ -207,6 +328,231 @@ TEST(DefaultVideoQualityAnalyzerTest, NormalScenario) {
EXPECT_EQ(frame_counters.dropped, kMaxFramesInFlightPerStream / 2);
}
+TEST(DefaultVideoQualityAnalyzerTest, OneFrameReceivedTwice) {
+ std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
+ test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
+ /*type=*/absl::nullopt,
+ /*num_squares=*/absl::nullopt);
+
+ DefaultVideoQualityAnalyzer analyzer(
+ /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream);
+ analyzer.Start("test_case",
+ std::vector<std::string>{kSenderPeerName, kReceiverPeerName},
+ kAnalyzerMaxThreadsCount);
+
+ VideoFrame captured_frame = NextFrame(frame_generator.get(), 0);
+ captured_frame.set_id(
+ analyzer.OnFrameCaptured(kSenderPeerName, kStreamLabel, captured_frame));
+ analyzer.OnFramePreEncode(kSenderPeerName, captured_frame);
+ analyzer.OnFrameEncoded(kSenderPeerName, captured_frame.id(),
+ FakeEncode(captured_frame),
+ VideoQualityAnalyzerInterface::EncoderStats());
+
+ VideoFrame received_frame = DeepCopy(captured_frame);
+ analyzer.OnFramePreDecode(kReceiverPeerName, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kReceiverPeerName, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ analyzer.OnFrameRendered(kReceiverPeerName, received_frame);
+
+ received_frame = DeepCopy(captured_frame);
+ analyzer.OnFramePreDecode(kReceiverPeerName, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kReceiverPeerName, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ analyzer.OnFrameRendered(kReceiverPeerName, received_frame);
+
+ // Give analyzer some time to process frames on async thread. The computations
+ // have to be fast (heavy metrics are disabled!), so if doesn't fit 100ms it
+ // means we have an issue!
+ SleepMs(100);
+ analyzer.Stop();
+
+ AnalyzerStats stats = analyzer.GetAnalyzerStats();
+ EXPECT_EQ(stats.memory_overloaded_comparisons_done, 0);
+ EXPECT_EQ(stats.comparisons_done, 1);
+
+ FrameCounters frame_counters = analyzer.GetGlobalCounters();
+ EXPECT_EQ(frame_counters.captured, 1);
+ EXPECT_EQ(frame_counters.received, 1);
+ EXPECT_EQ(frame_counters.decoded, 1);
+ EXPECT_EQ(frame_counters.rendered, 1);
+ EXPECT_EQ(frame_counters.dropped, 0);
+}
+
+TEST(DefaultVideoQualityAnalyzerTest, NormalScenario2Receivers) {
+ std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
+ test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
+ /*type=*/absl::nullopt,
+ /*num_squares=*/absl::nullopt);
+
+ constexpr char kAlice[] = "alice";
+ constexpr char kBob[] = "bob";
+ constexpr char kCharlie[] = "charlie";
+
+ DefaultVideoQualityAnalyzer analyzer(
+ /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream);
+ analyzer.Start("test_case", std::vector<std::string>{kAlice, kBob, kCharlie},
+ kAnalyzerMaxThreadsCount);
+
+ std::map<uint16_t, VideoFrame> captured_frames;
+ std::vector<uint16_t> frames_order;
+ for (int i = 0; i < kMaxFramesInFlightPerStream; ++i) {
+ VideoFrame frame = NextFrame(frame_generator.get(), i);
+ frame.set_id(analyzer.OnFrameCaptured(kAlice, kStreamLabel, frame));
+ frames_order.push_back(frame.id());
+ captured_frames.insert({frame.id(), frame});
+ analyzer.OnFramePreEncode(kAlice, frame);
+ SleepMs(20);
+ analyzer.OnFrameEncoded(kAlice, frame.id(), FakeEncode(frame),
+ VideoQualityAnalyzerInterface::EncoderStats());
+ }
+
+ SleepMs(50);
+
+ for (size_t i = 1; i < frames_order.size(); i += 2) {
+ uint16_t frame_id = frames_order.at(i);
+ VideoFrame received_frame = DeepCopy(captured_frames.at(frame_id));
+ analyzer.OnFramePreDecode(kBob, received_frame.id(),
+ FakeEncode(received_frame));
+ SleepMs(30);
+ analyzer.OnFrameDecoded(kBob, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ SleepMs(10);
+ analyzer.OnFrameRendered(kBob, received_frame);
+ }
+
+ for (size_t i = 1; i < frames_order.size(); i += 2) {
+ uint16_t frame_id = frames_order.at(i);
+ VideoFrame received_frame = DeepCopy(captured_frames.at(frame_id));
+ analyzer.OnFramePreDecode(kCharlie, received_frame.id(),
+ FakeEncode(received_frame));
+ SleepMs(40);
+ analyzer.OnFrameDecoded(kCharlie, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ SleepMs(5);
+ analyzer.OnFrameRendered(kCharlie, received_frame);
+ }
+
+ // Give analyzer some time to process frames on async thread. The computations
+ // have to be fast (heavy metrics are disabled!), so if doesn't fit 100ms it
+ // means we have an issue!
+ SleepMs(100);
+ analyzer.Stop();
+
+ AnalyzerStats analyzer_stats = analyzer.GetAnalyzerStats();
+ EXPECT_EQ(analyzer_stats.memory_overloaded_comparisons_done, 0);
+ EXPECT_EQ(analyzer_stats.comparisons_done, kMaxFramesInFlightPerStream * 2);
+
+ FrameCounters frame_counters = analyzer.GetGlobalCounters();
+ EXPECT_EQ(frame_counters.captured, kMaxFramesInFlightPerStream);
+ EXPECT_EQ(frame_counters.received, kMaxFramesInFlightPerStream);
+ EXPECT_EQ(frame_counters.decoded, kMaxFramesInFlightPerStream);
+ EXPECT_EQ(frame_counters.rendered, kMaxFramesInFlightPerStream);
+ EXPECT_EQ(frame_counters.dropped, kMaxFramesInFlightPerStream);
+ EXPECT_EQ(analyzer.GetKnownVideoStreams().size(), 2lu);
+ for (auto stream_key : analyzer.GetKnownVideoStreams()) {
+ FrameCounters stream_conters =
+ analyzer.GetPerStreamCounters().at(stream_key);
+ // On some devices the pipeline can be too slow, so we actually can't
+ // force real constraints here. Lets just check, that at least 1
+ // frame passed whole pipeline.
+ EXPECT_GE(stream_conters.captured, 10);
+ EXPECT_GE(stream_conters.pre_encoded, 10);
+ EXPECT_GE(stream_conters.encoded, 10);
+ EXPECT_GE(stream_conters.received, 5);
+ EXPECT_GE(stream_conters.decoded, 5);
+ EXPECT_GE(stream_conters.rendered, 5);
+ EXPECT_GE(stream_conters.dropped, 5);
+ }
+
+ std::map<StatsKey, StreamStats> stats = analyzer.GetStats();
+ const StatsKey kAliceBobStats(kStreamLabel, kAlice, kBob);
+ const StatsKey kAliceCharlieStats(kStreamLabel, kAlice, kCharlie);
+ EXPECT_EQ(stats.size(), 2lu);
+ {
+ auto it = stats.find(kAliceBobStats);
+ EXPECT_FALSE(it == stats.end());
+ ASSERT_FALSE(it->second.encode_time_ms.IsEmpty());
+ EXPECT_GE(it->second.encode_time_ms.GetMin(), 20);
+ ASSERT_FALSE(it->second.decode_time_ms.IsEmpty());
+ EXPECT_GE(it->second.decode_time_ms.GetMin(), 30);
+ ASSERT_FALSE(it->second.resolution_of_rendered_frame.IsEmpty());
+ EXPECT_GE(it->second.resolution_of_rendered_frame.GetMin(),
+ kFrameWidth * kFrameHeight - 1);
+ EXPECT_LE(it->second.resolution_of_rendered_frame.GetMax(),
+ kFrameWidth * kFrameHeight + 1);
+ }
+ {
+ auto it = stats.find(kAliceCharlieStats);
+ EXPECT_FALSE(it == stats.end());
+ ASSERT_FALSE(it->second.encode_time_ms.IsEmpty());
+ EXPECT_GE(it->second.encode_time_ms.GetMin(), 20);
+ ASSERT_FALSE(it->second.decode_time_ms.IsEmpty());
+ EXPECT_GE(it->second.decode_time_ms.GetMin(), 30);
+ ASSERT_FALSE(it->second.resolution_of_rendered_frame.IsEmpty());
+ EXPECT_GE(it->second.resolution_of_rendered_frame.GetMin(),
+ kFrameWidth * kFrameHeight - 1);
+ EXPECT_LE(it->second.resolution_of_rendered_frame.GetMax(),
+ kFrameWidth * kFrameHeight + 1);
+ }
+}
+
+TEST(DefaultVideoQualityAnalyzerTest, OneFrameReceivedTwiceWith2Receivers) {
+ std::unique_ptr<test::FrameGeneratorInterface> frame_generator =
+ test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight,
+ /*type=*/absl::nullopt,
+ /*num_squares=*/absl::nullopt);
+
+ constexpr char kAlice[] = "alice";
+ constexpr char kBob[] = "bob";
+ constexpr char kCharlie[] = "charlie";
+
+ DefaultVideoQualityAnalyzer analyzer(
+ /*heavy_metrics_computation_enabled=*/false, kMaxFramesInFlightPerStream);
+ analyzer.Start("test_case", std::vector<std::string>{kAlice, kBob, kCharlie},
+ kAnalyzerMaxThreadsCount);
+
+ VideoFrame captured_frame = NextFrame(frame_generator.get(), 0);
+ captured_frame.set_id(
+ analyzer.OnFrameCaptured(kAlice, kStreamLabel, captured_frame));
+ analyzer.OnFramePreEncode(kAlice, captured_frame);
+ analyzer.OnFrameEncoded(kAlice, captured_frame.id(),
+ FakeEncode(captured_frame),
+ VideoQualityAnalyzerInterface::EncoderStats());
+
+ VideoFrame received_frame = DeepCopy(captured_frame);
+ analyzer.OnFramePreDecode(kBob, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kBob, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ analyzer.OnFrameRendered(kBob, received_frame);
+
+ received_frame = DeepCopy(captured_frame);
+ analyzer.OnFramePreDecode(kBob, received_frame.id(),
+ FakeEncode(received_frame));
+ analyzer.OnFrameDecoded(kBob, received_frame,
+ VideoQualityAnalyzerInterface::DecoderStats());
+ analyzer.OnFrameRendered(kBob, received_frame);
+
+ // Give analyzer some time to process frames on async thread. The computations
+ // have to be fast (heavy metrics are disabled!), so if doesn't fit 100ms it
+ // means we have an issue!
+ SleepMs(100);
+ analyzer.Stop();
+
+ AnalyzerStats stats = analyzer.GetAnalyzerStats();
+ EXPECT_EQ(stats.memory_overloaded_comparisons_done, 0);
+ EXPECT_EQ(stats.comparisons_done, 1);
+
+ FrameCounters frame_counters = analyzer.GetGlobalCounters();
+ EXPECT_EQ(frame_counters.captured, 1);
+ EXPECT_EQ(frame_counters.received, 1);
+ EXPECT_EQ(frame_counters.decoded, 1);
+ EXPECT_EQ(frame_counters.rendered, 1);
+ EXPECT_EQ(frame_counters.dropped, 0);
+}
+
} // namespace
} // namespace webrtc_pc_e2e
} // namespace webrtc
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc
index d1d1bface7d..a980b0e9d09 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.cc
@@ -10,6 +10,7 @@
#include "test/pc/e2e/analyzer/video/example_video_quality_analyzer.h"
+#include "api/array_view.h"
#include "rtc_base/logging.h"
namespace webrtc {
@@ -18,10 +19,13 @@ namespace webrtc_pc_e2e {
ExampleVideoQualityAnalyzer::ExampleVideoQualityAnalyzer() = default;
ExampleVideoQualityAnalyzer::~ExampleVideoQualityAnalyzer() = default;
-void ExampleVideoQualityAnalyzer::Start(std::string test_case_name,
- int max_threads_count) {}
+void ExampleVideoQualityAnalyzer::Start(
+ std::string test_case_name,
+ rtc::ArrayView<const std::string> peer_names,
+ int max_threads_count) {}
uint16_t ExampleVideoQualityAnalyzer::OnFrameCaptured(
+ absl::string_view peer_name,
const std::string& stream_label,
const webrtc::VideoFrame& frame) {
rtc::CritScope crit(&lock_);
@@ -45,12 +49,14 @@ uint16_t ExampleVideoQualityAnalyzer::OnFrameCaptured(
}
void ExampleVideoQualityAnalyzer::OnFramePreEncode(
+ absl::string_view peer_name,
const webrtc::VideoFrame& frame) {
rtc::CritScope crit(&lock_);
++frames_pre_encoded_;
}
void ExampleVideoQualityAnalyzer::OnFrameEncoded(
+ absl::string_view peer_name,
uint16_t frame_id,
const webrtc::EncodedImage& encoded_image,
const EncoderStats& stats) {
@@ -59,6 +65,7 @@ void ExampleVideoQualityAnalyzer::OnFrameEncoded(
}
void ExampleVideoQualityAnalyzer::OnFrameDropped(
+ absl::string_view peer_name,
webrtc::EncodedImageCallback::DropReason reason) {
RTC_LOG(INFO) << "Frame dropped by encoder";
rtc::CritScope crit(&lock_);
@@ -66,6 +73,7 @@ void ExampleVideoQualityAnalyzer::OnFrameDropped(
}
void ExampleVideoQualityAnalyzer::OnFramePreDecode(
+ absl::string_view peer_name,
uint16_t frame_id,
const webrtc::EncodedImage& encoded_image) {
rtc::CritScope crit(&lock_);
@@ -73,6 +81,7 @@ void ExampleVideoQualityAnalyzer::OnFramePreDecode(
}
void ExampleVideoQualityAnalyzer::OnFrameDecoded(
+ absl::string_view peer_name,
const webrtc::VideoFrame& frame,
const DecoderStats& stats) {
rtc::CritScope crit(&lock_);
@@ -80,6 +89,7 @@ void ExampleVideoQualityAnalyzer::OnFrameDecoded(
}
void ExampleVideoQualityAnalyzer::OnFrameRendered(
+ absl::string_view peer_name,
const webrtc::VideoFrame& frame) {
rtc::CritScope crit(&lock_);
frames_in_flight_.erase(frame.id());
@@ -87,13 +97,15 @@ void ExampleVideoQualityAnalyzer::OnFrameRendered(
}
void ExampleVideoQualityAnalyzer::OnEncoderError(
+ absl::string_view peer_name,
const webrtc::VideoFrame& frame,
int32_t error_code) {
RTC_LOG(LS_ERROR) << "Failed to encode frame " << frame.id()
<< ". Code: " << error_code;
}
-void ExampleVideoQualityAnalyzer::OnDecoderError(uint16_t frame_id,
+void ExampleVideoQualityAnalyzer::OnDecoderError(absl::string_view peer_name,
+ uint16_t frame_id,
int32_t error_code) {
RTC_LOG(LS_ERROR) << "Failed to decode frame " << frame_id
<< ". Code: " << error_code;
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h
index 0d6169f9fa2..0126093c87a 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/example_video_quality_analyzer.h
@@ -16,6 +16,7 @@
#include <set>
#include <string>
+#include "api/array_view.h"
#include "api/test/video_quality_analyzer_interface.h"
#include "api/video/encoded_image.h"
#include "api/video/video_frame.h"
@@ -33,21 +34,34 @@ class ExampleVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
ExampleVideoQualityAnalyzer();
~ExampleVideoQualityAnalyzer() override;
- void Start(std::string test_case_name, int max_threads_count) override;
- uint16_t OnFrameCaptured(const std::string& stream_label,
+ void Start(std::string test_case_name,
+ rtc::ArrayView<const std::string> peer_names,
+ int max_threads_count) override;
+ uint16_t OnFrameCaptured(absl::string_view peer_name,
+ const std::string& stream_label,
const VideoFrame& frame) override;
- void OnFramePreEncode(const VideoFrame& frame) override;
- void OnFrameEncoded(uint16_t frame_id,
+ void OnFramePreEncode(absl::string_view peer_name,
+ const VideoFrame& frame) override;
+ void OnFrameEncoded(absl::string_view peer_name,
+ uint16_t frame_id,
const EncodedImage& encoded_image,
const EncoderStats& stats) override;
- void OnFrameDropped(EncodedImageCallback::DropReason reason) override;
- void OnFramePreDecode(uint16_t frame_id,
+ void OnFrameDropped(absl::string_view peer_name,
+ EncodedImageCallback::DropReason reason) override;
+ void OnFramePreDecode(absl::string_view peer_name,
+ uint16_t frame_id,
const EncodedImage& encoded_image) override;
- void OnFrameDecoded(const VideoFrame& frame,
+ void OnFrameDecoded(absl::string_view peer_name,
+ const VideoFrame& frame,
const DecoderStats& stats) override;
- void OnFrameRendered(const VideoFrame& frame) override;
- void OnEncoderError(const VideoFrame& frame, int32_t error_code) override;
- void OnDecoderError(uint16_t frame_id, int32_t error_code) override;
+ void OnFrameRendered(absl::string_view peer_name,
+ const VideoFrame& frame) override;
+ void OnEncoderError(absl::string_view peer_name,
+ const VideoFrame& frame,
+ int32_t error_code) override;
+ void OnDecoderError(absl::string_view peer_name,
+ uint16_t frame_id,
+ int32_t error_code) override;
void Stop() override;
std::string GetStreamLabel(uint16_t frame_id) override;
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue.h
new file mode 100644
index 00000000000..52314a60d54
--- /dev/null
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_
+#define TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_
+
+#include <deque>
+#include <memory>
+#include <vector>
+
+#include "absl/types/optional.h"
+#include "rtc_base/checks.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+
+// A queue that allows more than one reader. Readers are independent, and all
+// readers will see all elements; an inserted element stays in the queue until
+// all readers have extracted it. Elements are copied and copying is assumed to
+// be cheap.
+template <typename T>
+class MultiHeadQueue {
+ public:
+ // Creates queue with exactly |readers_count| readers.
+ explicit MultiHeadQueue(size_t readers_count) {
+ for (size_t i = 0; i < readers_count; ++i) {
+ queues_.push_back(std::deque<T>());
+ }
+ }
+
+ // Add value to the end of the queue. Complexity O(readers_count).
+ void PushBack(T value) {
+ for (auto& queue : queues_) {
+ queue.push_back(value);
+ }
+ }
+
+ // Extract element from specified head. Complexity O(1).
+ absl::optional<T> PopFront(size_t index) {
+ RTC_CHECK_LT(index, queues_.size());
+ if (queues_[index].empty()) {
+ return absl::nullopt;
+ }
+ T out = queues_[index].front();
+ queues_[index].pop_front();
+ return out;
+ }
+
+ // Returns element at specified head. Complexity O(1).
+ absl::optional<T> Front(size_t index) const {
+ RTC_CHECK_LT(index, queues_.size());
+ if (queues_[index].empty()) {
+ return absl::nullopt;
+ }
+ return queues_[index].front();
+ }
+
+ // Returns true if for specified head there are no more elements in the queue
+ // or false otherwise. Complexity O(1).
+ bool IsEmpty(size_t index) const {
+ RTC_CHECK_LT(index, queues_.size());
+ return queues_[index].empty();
+ }
+
+ // Returns size of the longest queue between all readers.
+ // Complexity O(readers_count).
+ size_t size() const {
+ size_t size = 0;
+ for (auto& queue : queues_) {
+ if (queue.size() > size) {
+ size = queue.size();
+ }
+ }
+ return size;
+ }
+
+ // Returns size of the specified queue. Complexity O(1).
+ size_t size(size_t index) const {
+ RTC_CHECK_LT(index, queues_.size());
+ return queues_[index].size();
+ }
+
+ size_t readers_count() const { return queues_.size(); }
+
+ private:
+ std::vector<std::deque<T>> queues_;
+};
+
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
+
+#endif // TEST_PC_E2E_ANALYZER_VIDEO_MULTI_HEAD_QUEUE_H_
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue_test.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue_test.cc
new file mode 100644
index 00000000000..3a4ab6cdbb9
--- /dev/null
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/multi_head_queue_test.cc
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "test/pc/e2e/analyzer/video/multi_head_queue.h"
+#include "absl/types/optional.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace webrtc_pc_e2e {
+namespace {
+
+TEST(MultiHeadQueueTest, GetOnEmpty) {
+ MultiHeadQueue<int> queue = MultiHeadQueue<int>(10);
+ EXPECT_TRUE(queue.IsEmpty(0));
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_FALSE(queue.PopFront(i).has_value());
+ EXPECT_FALSE(queue.Front(i).has_value());
+ }
+}
+
+TEST(MultiHeadQueueTest, SingleHeadOneAddOneRemove) {
+ MultiHeadQueue<int> queue = MultiHeadQueue<int>(1);
+ queue.PushBack(1);
+ EXPECT_EQ(queue.size(), 1lu);
+ EXPECT_TRUE(queue.Front(0).has_value());
+ EXPECT_EQ(queue.Front(0).value(), 1);
+ absl::optional<int> value = queue.PopFront(0);
+ EXPECT_TRUE(value.has_value());
+ EXPECT_EQ(value.value(), 1);
+ EXPECT_EQ(queue.size(), 0lu);
+ EXPECT_TRUE(queue.IsEmpty(0));
+}
+
+TEST(MultiHeadQueueTest, SingleHead) {
+ MultiHeadQueue<size_t> queue = MultiHeadQueue<size_t>(1);
+ for (size_t i = 0; i < 10; ++i) {
+ queue.PushBack(i);
+ EXPECT_EQ(queue.size(), i + 1);
+ }
+ for (size_t i = 0; i < 10; ++i) {
+ absl::optional<size_t> value = queue.PopFront(0);
+ EXPECT_EQ(queue.size(), 10 - i - 1);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(value.value(), i);
+ }
+}
+
+TEST(MultiHeadQueueTest, ThreeHeadsAddAllRemoveAllPerHead) {
+ MultiHeadQueue<size_t> queue = MultiHeadQueue<size_t>(3);
+ for (size_t i = 0; i < 10; ++i) {
+ queue.PushBack(i);
+ EXPECT_EQ(queue.size(), i + 1);
+ }
+ for (size_t i = 0; i < 10; ++i) {
+ absl::optional<size_t> value = queue.PopFront(0);
+ EXPECT_EQ(queue.size(), 10lu);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(value.value(), i);
+ }
+ for (size_t i = 0; i < 10; ++i) {
+ absl::optional<size_t> value = queue.PopFront(1);
+ EXPECT_EQ(queue.size(), 10lu);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(value.value(), i);
+ }
+ for (size_t i = 0; i < 10; ++i) {
+ absl::optional<size_t> value = queue.PopFront(2);
+ EXPECT_EQ(queue.size(), 10 - i - 1);
+ ASSERT_TRUE(value.has_value());
+ EXPECT_EQ(value.value(), i);
+ }
+}
+
+TEST(MultiHeadQueueTest, ThreeHeadsAddAllRemoveAll) {
+ MultiHeadQueue<size_t> queue = MultiHeadQueue<size_t>(3);
+ for (size_t i = 0; i < 10; ++i) {
+ queue.PushBack(i);
+ EXPECT_EQ(queue.size(), i + 1);
+ }
+ for (size_t i = 0; i < 10; ++i) {
+ absl::optional<size_t> value1 = queue.PopFront(0);
+ absl::optional<size_t> value2 = queue.PopFront(1);
+ absl::optional<size_t> value3 = queue.PopFront(2);
+ EXPECT_EQ(queue.size(), 10 - i - 1);
+ ASSERT_TRUE(value1.has_value());
+ ASSERT_TRUE(value2.has_value());
+ ASSERT_TRUE(value3.has_value());
+ EXPECT_EQ(value1.value(), i);
+ EXPECT_EQ(value2.value(), i);
+ EXPECT_EQ(value3.value(), i);
+ }
+}
+
+} // namespace
+} // namespace webrtc_pc_e2e
+} // namespace webrtc
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
index 228ab8ac025..9e81c8728bd 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc
@@ -15,6 +15,7 @@
#include <memory>
#include <utility>
+#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/video/i420_buffer.h"
#include "modules/video_coding/include/video_error_codes.h"
@@ -26,10 +27,12 @@ namespace webrtc_pc_e2e {
QualityAnalyzingVideoDecoder::QualityAnalyzingVideoDecoder(
int id,
+ absl::string_view peer_name,
std::unique_ptr<VideoDecoder> delegate,
EncodedImageDataExtractor* extractor,
VideoQualityAnalyzerInterface* analyzer)
: id_(id),
+ peer_name_(peer_name),
implementation_name_("AnalyzingDecoder-" +
std::string(delegate->ImplementationName())),
delegate_(std::move(delegate)),
@@ -87,7 +90,7 @@ int32_t QualityAnalyzingVideoDecoder::Decode(const EncodedImage& input_image,
// We can safely dereference |origin_image|, because it can be removed from
// the map only after |delegate_| Decode method will be invoked. Image will be
// removed inside DecodedImageCallback, which can be done on separate thread.
- analyzer_->OnFramePreDecode(out.id, *origin_image);
+ analyzer_->OnFramePreDecode(peer_name_, out.id, *origin_image);
int32_t result =
delegate_->Decode(*origin_image, missing_frames, render_time_ms);
if (result != WEBRTC_VIDEO_CODEC_OK) {
@@ -97,7 +100,7 @@ int32_t QualityAnalyzingVideoDecoder::Decode(const EncodedImage& input_image,
timestamp_to_frame_id_.erase(input_image.Timestamp());
decoding_images_.erase(out.id);
}
- analyzer_->OnDecoderError(out.id, result);
+ analyzer_->OnDecoderError(peer_name_, out.id, result);
}
return result;
}
@@ -224,15 +227,17 @@ void QualityAnalyzingVideoDecoder::OnFrameDecoded(
frame->set_id(frame_id);
VideoQualityAnalyzerInterface::DecoderStats stats;
stats.decode_time_ms = decode_time_ms;
- analyzer_->OnFrameDecoded(*frame, stats);
+ analyzer_->OnFrameDecoded(peer_name_, *frame, stats);
}
QualityAnalyzingVideoDecoderFactory::QualityAnalyzingVideoDecoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoDecoderFactory> delegate,
IdGenerator<int>* id_generator,
EncodedImageDataExtractor* extractor,
VideoQualityAnalyzerInterface* analyzer)
- : delegate_(std::move(delegate)),
+ : peer_name_(peer_name),
+ delegate_(std::move(delegate)),
id_generator_(id_generator),
extractor_(extractor),
analyzer_(analyzer) {}
@@ -249,7 +254,8 @@ QualityAnalyzingVideoDecoderFactory::CreateVideoDecoder(
const SdpVideoFormat& format) {
std::unique_ptr<VideoDecoder> decoder = delegate_->CreateVideoDecoder(format);
return std::make_unique<QualityAnalyzingVideoDecoder>(
- id_generator_->GetNextId(), std::move(decoder), extractor_, analyzer_);
+ id_generator_->GetNextId(), peer_name_, std::move(decoder), extractor_,
+ analyzer_);
}
std::unique_ptr<VideoDecoder>
@@ -259,7 +265,8 @@ QualityAnalyzingVideoDecoderFactory::LegacyCreateVideoDecoder(
std::unique_ptr<VideoDecoder> decoder =
delegate_->LegacyCreateVideoDecoder(format, receive_stream_id);
return std::make_unique<QualityAnalyzingVideoDecoder>(
- id_generator_->GetNextId(), std::move(decoder), extractor_, analyzer_);
+ id_generator_->GetNextId(), peer_name_, std::move(decoder), extractor_,
+ analyzer_);
}
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
index 5cbc8822266..decb844bc2a 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h
@@ -16,6 +16,7 @@
#include <string>
#include <vector>
+#include "absl/strings/string_view.h"
#include "api/test/video_quality_analyzer_interface.h"
#include "api/video/encoded_image.h"
#include "api/video/video_frame.h"
@@ -45,14 +46,15 @@ namespace webrtc_pc_e2e {
// callback, where video analyzer will be called again and then decoded frame
// will be passed to origin callback, provided by user.
//
-// Quality decoder registers its own callback in origin decoder at the same
-// time, when user registers his callback in quality decoder.
+// Quality decoder registers its own callback in origin decoder, at the same
+// time the user registers their callback in quality decoder.
class QualityAnalyzingVideoDecoder : public VideoDecoder {
public:
// Creates analyzing decoder. |id| is unique coding entity id, that will
// be used to distinguish all encoders and decoders inside
// EncodedImageDataInjector and EncodedImageIdExtracor.
QualityAnalyzingVideoDecoder(int id,
+ absl::string_view peer_name,
std::unique_ptr<VideoDecoder> delegate,
EncodedImageDataExtractor* extractor,
VideoQualityAnalyzerInterface* analyzer);
@@ -104,6 +106,7 @@ class QualityAnalyzingVideoDecoder : public VideoDecoder {
absl::optional<uint8_t> qp);
const int id_;
+ const std::string peer_name_;
const std::string implementation_name_;
std::unique_ptr<VideoDecoder> delegate_;
EncodedImageDataExtractor* const extractor_;
@@ -129,6 +132,7 @@ class QualityAnalyzingVideoDecoder : public VideoDecoder {
class QualityAnalyzingVideoDecoderFactory : public VideoDecoderFactory {
public:
QualityAnalyzingVideoDecoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoDecoderFactory> delegate,
IdGenerator<int>* id_generator,
EncodedImageDataExtractor* extractor,
@@ -144,6 +148,7 @@ class QualityAnalyzingVideoDecoderFactory : public VideoDecoderFactory {
const std::string& receive_stream_id) override;
private:
+ const std::string peer_name_;
std::unique_ptr<VideoDecoderFactory> delegate_;
IdGenerator<int>* const id_generator_;
EncodedImageDataExtractor* const extractor_;
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
index 2e7b8f41529..4d04a2ccbbb 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.cc
@@ -14,6 +14,7 @@
#include <memory>
#include <utility>
+#include "absl/strings/string_view.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/video_encoder.h"
#include "modules/video_coding/include/video_error_codes.h"
@@ -54,12 +55,14 @@ std::pair<uint32_t, uint32_t> GetMinMaxBitratesBps(const VideoCodec& codec,
QualityAnalyzingVideoEncoder::QualityAnalyzingVideoEncoder(
int id,
+ absl::string_view peer_name,
std::unique_ptr<VideoEncoder> delegate,
double bitrate_multiplier,
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
EncodedImageDataInjector* injector,
VideoQualityAnalyzerInterface* analyzer)
: id_(id),
+ peer_name_(peer_name),
delegate_(std::move(delegate)),
bitrate_multiplier_(bitrate_multiplier),
stream_required_spatial_index_(std::move(stream_required_spatial_index)),
@@ -134,7 +137,7 @@ int32_t QualityAnalyzingVideoEncoder::Encode(
// images from encoder. So it should be a bug in setup on in the encoder.
RTC_DCHECK_LT(timestamp_to_frame_id_list_.size(), kMaxFrameInPipelineCount);
}
- analyzer_->OnFramePreEncode(frame);
+ analyzer_->OnFramePreEncode(peer_name_, frame);
int32_t result = delegate_->Encode(frame, frame_types);
if (result != WEBRTC_VIDEO_CODEC_OK) {
// If origin encoder failed, then cleanup data for this frame.
@@ -152,7 +155,7 @@ int32_t QualityAnalyzingVideoEncoder::Encode(
}
}
}
- analyzer_->OnEncoderError(frame, result);
+ analyzer_->OnEncoderError(peer_name_, frame, result);
}
return result;
}
@@ -277,7 +280,7 @@ EncodedImageCallback::Result QualityAnalyzingVideoEncoder::OnEncodedImage(
// not discarded layers have to be passed.
VideoQualityAnalyzerInterface::EncoderStats stats;
stats.target_encode_bitrate = target_encode_bitrate;
- analyzer_->OnFrameEncoded(frame_id, encoded_image, stats);
+ analyzer_->OnFrameEncoded(peer_name_, frame_id, encoded_image, stats);
}
// Image data injector injects frame id and discard flag into provided
@@ -298,7 +301,7 @@ EncodedImageCallback::Result QualityAnalyzingVideoEncoder::OnEncodedImage(
void QualityAnalyzingVideoEncoder::OnDroppedFrame(
EncodedImageCallback::DropReason reason) {
rtc::CritScope crit(&lock_);
- analyzer_->OnFrameDropped(reason);
+ analyzer_->OnFrameDropped(peer_name_, reason);
RTC_DCHECK(delegate_callback_);
delegate_callback_->OnDroppedFrame(reason);
}
@@ -348,13 +351,15 @@ bool QualityAnalyzingVideoEncoder::ShouldDiscard(
}
QualityAnalyzingVideoEncoderFactory::QualityAnalyzingVideoEncoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoEncoderFactory> delegate,
double bitrate_multiplier,
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
IdGenerator<int>* id_generator,
EncodedImageDataInjector* injector,
VideoQualityAnalyzerInterface* analyzer)
- : delegate_(std::move(delegate)),
+ : peer_name_(peer_name),
+ delegate_(std::move(delegate)),
bitrate_multiplier_(bitrate_multiplier),
stream_required_spatial_index_(std::move(stream_required_spatial_index)),
id_generator_(id_generator),
@@ -378,9 +383,9 @@ std::unique_ptr<VideoEncoder>
QualityAnalyzingVideoEncoderFactory::CreateVideoEncoder(
const SdpVideoFormat& format) {
return std::make_unique<QualityAnalyzingVideoEncoder>(
- id_generator_->GetNextId(), delegate_->CreateVideoEncoder(format),
- bitrate_multiplier_, stream_required_spatial_index_, injector_,
- analyzer_);
+ id_generator_->GetNextId(), peer_name_,
+ delegate_->CreateVideoEncoder(format), bitrate_multiplier_,
+ stream_required_spatial_index_, injector_, analyzer_);
}
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
index 3307dc73255..f6db1369b09 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h
@@ -16,6 +16,7 @@
#include <utility>
#include <vector>
+#include "absl/strings/string_view.h"
#include "api/test/video_quality_analyzer_interface.h"
#include "api/video/video_frame.h"
#include "api/video_codecs/sdp_video_format.h"
@@ -49,8 +50,8 @@ constexpr int kAnalyzeAnySpatialStream = -1;
// injected into EncodedImage with passed EncodedImageDataInjector. Then new
// EncodedImage will be passed to origin callback, provided by user.
//
-// Quality encoder registers its own callback in origin encoder at the same
-// time, when user registers his callback in quality encoder.
+// Quality encoder registers its own callback in origin encoder, at the same
+// time the user registers their callback in quality encoder.
class QualityAnalyzingVideoEncoder : public VideoEncoder,
public EncodedImageCallback {
public:
@@ -59,6 +60,7 @@ class QualityAnalyzingVideoEncoder : public VideoEncoder,
// EncodedImageDataInjector and EncodedImageIdExtracor.
QualityAnalyzingVideoEncoder(
int id,
+ absl::string_view peer_name,
std::unique_ptr<VideoEncoder> delegate,
double bitrate_multiplier,
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
@@ -139,6 +141,7 @@ class QualityAnalyzingVideoEncoder : public VideoEncoder,
RTC_EXCLUSIVE_LOCKS_REQUIRED(lock_);
const int id_;
+ const std::string peer_name_;
std::unique_ptr<VideoEncoder> delegate_;
const double bitrate_multiplier_;
// Contains mapping from stream label to optional spatial index.
@@ -170,6 +173,7 @@ class QualityAnalyzingVideoEncoder : public VideoEncoder,
class QualityAnalyzingVideoEncoderFactory : public VideoEncoderFactory {
public:
QualityAnalyzingVideoEncoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoEncoderFactory> delegate,
double bitrate_multiplier,
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
@@ -186,6 +190,7 @@ class QualityAnalyzingVideoEncoderFactory : public VideoEncoderFactory {
const SdpVideoFormat& format) override;
private:
+ const std::string peer_name_;
std::unique_ptr<VideoEncoderFactory> delegate_;
const double bitrate_multiplier_;
std::map<std::string, absl::optional<int>> stream_required_spatial_index_;
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc
index ec0d26b780b..75f1265e1f4 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.cc
@@ -19,13 +19,6 @@
namespace webrtc {
namespace webrtc_pc_e2e {
-namespace {
-
-// Number of bytes from the beginning of the EncodedImage buffer that will be
-// used to store frame id and sub id.
-constexpr size_t kUsedBufferSize = 3;
-
-} // namespace
SingleProcessEncodedImageDataInjector::SingleProcessEncodedImageDataInjector() =
default;
@@ -37,13 +30,13 @@ EncodedImage SingleProcessEncodedImageDataInjector::InjectData(
bool discard,
const EncodedImage& source,
int coding_entity_id) {
- RTC_CHECK(source.size() >= kUsedBufferSize);
+ RTC_CHECK(source.size() >= ExtractionInfo::kUsedBufferSize);
ExtractionInfo info;
- info.length = source.size();
info.discard = discard;
- size_t insertion_pos = source.size() - kUsedBufferSize;
- memcpy(info.origin_data, &source.data()[insertion_pos], kUsedBufferSize);
+ size_t insertion_pos = source.size() - ExtractionInfo::kUsedBufferSize;
+ memcpy(info.origin_data, &source.data()[insertion_pos],
+ ExtractionInfo::kUsedBufferSize);
{
rtc::CritScope crit(&lock_);
// Will create new one if missed.
@@ -69,15 +62,27 @@ EncodedImageExtractionResult SingleProcessEncodedImageDataInjector::ExtractData(
uint8_t* buffer = out.data();
size_t size = out.size();
- // |pos| is pointing to end of current encoded image.
- size_t pos = size - 1;
+ std::vector<size_t> frame_sizes;
+ std::vector<size_t> frame_sl_index;
+ size_t max_spatial_index = out.SpatialIndex().value_or(0);
+ for (size_t i = 0; i <= max_spatial_index; ++i) {
+ auto frame_size = source.SpatialLayerFrameSize(i);
+ if (frame_size.value_or(0)) {
+ frame_sl_index.push_back(i);
+ frame_sizes.push_back(frame_size.value());
+ }
+ }
+ if (frame_sizes.empty()) {
+ frame_sizes.push_back(size);
+ }
+
+ size_t prev_frames_size = 0;
absl::optional<uint16_t> id = absl::nullopt;
bool discard = true;
std::vector<ExtractionInfo> extraction_infos;
- // Go through whole buffer and find all related extraction infos in
- // order from 1st encoded image to the last.
- while (true) {
- size_t insertion_pos = pos - kUsedBufferSize + 1;
+ for (size_t frame_size : frame_sizes) {
+ size_t insertion_pos =
+ prev_frames_size + frame_size - ExtractionInfo::kUsedBufferSize;
// Extract frame id from first 2 bytes starting from insertion pos.
uint16_t next_id = buffer[insertion_pos] + (buffer[insertion_pos + 1] << 8);
// Extract frame sub id from second 3 byte starting from insertion pos.
@@ -90,6 +95,8 @@ EncodedImageExtractionResult SingleProcessEncodedImageDataInjector::ExtractData(
{
rtc::CritScope crit(&lock_);
auto ext_vector_it = extraction_cache_.find(next_id);
+ // TODO(titovartem) add support for receiving single frame multiple times
+ // when in simulcast key frame for another spatial stream can be received.
RTC_CHECK(ext_vector_it != extraction_cache_.end())
<< "Unknown frame_id=" << next_id;
@@ -99,41 +106,45 @@ EncodedImageExtractionResult SingleProcessEncodedImageDataInjector::ExtractData(
info = info_it->second;
ext_vector_it->second.infos.erase(info_it);
}
- extraction_infos.push_back(info);
// We need to discard encoded image only if all concatenated encoded images
// have to be discarded.
discard = discard && info.discard;
- if (pos < info.length) {
- break;
- }
- pos -= info.length;
+
+ extraction_infos.push_back(info);
+ prev_frames_size += frame_size;
}
RTC_CHECK(id);
- std::reverse(extraction_infos.begin(), extraction_infos.end());
+
if (discard) {
out.set_size(0);
+ for (size_t i = 0; i <= max_spatial_index; ++i) {
+ out.SetSpatialLayerFrameSize(i, 0);
+ }
return EncodedImageExtractionResult{*id, out, true};
}
// Make a pass from begin to end to restore origin payload and erase discarded
// encoded images.
- pos = 0;
- auto extraction_infos_it = extraction_infos.begin();
- while (pos < size) {
- RTC_DCHECK(extraction_infos_it != extraction_infos.end());
- const ExtractionInfo& info = *extraction_infos_it;
+ size_t pos = 0;
+ for (size_t frame_index = 0; frame_index < frame_sizes.size();
+ ++frame_index) {
+ RTC_CHECK(pos < size);
+ const size_t frame_size = frame_sizes[frame_index];
+ const ExtractionInfo& info = extraction_infos[frame_index];
if (info.discard) {
// If this encoded image is marked to be discarded - erase it's payload
// from the buffer.
- memmove(&buffer[pos], &buffer[pos + info.length],
- size - pos - info.length);
- size -= info.length;
+ memmove(&buffer[pos], &buffer[pos + frame_size], size - pos - frame_size);
+ RTC_CHECK_LT(frame_index, frame_sl_index.size())
+ << "codec doesn't support discard option or the image, that was "
+ "supposed to be discarded, is lost";
+ out.SetSpatialLayerFrameSize(frame_sl_index[frame_index], 0);
+ size -= frame_size;
} else {
- memcpy(&buffer[pos + info.length - kUsedBufferSize], info.origin_data,
- kUsedBufferSize);
- pos += info.length;
+ memcpy(&buffer[pos + frame_size - ExtractionInfo::kUsedBufferSize],
+ info.origin_data, ExtractionInfo::kUsedBufferSize);
+ pos += frame_size;
}
- ++extraction_infos_it;
}
out.set_size(pos);
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h
index 3787cc51aac..f79532e0961 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector.h
@@ -57,15 +57,16 @@ class SingleProcessEncodedImageDataInjector : public EncodedImageDataInjector,
// Contains data required to extract frame id from EncodedImage and restore
// original buffer.
struct ExtractionInfo {
+ // Number of bytes from the beginning of the EncodedImage buffer that will
+ // be used to store frame id and sub id.
+ const static size_t kUsedBufferSize = 3;
// Frame sub id to distinguish encoded images for different spatial layers.
uint8_t sub_id;
- // Length of the origin buffer encoded image.
- size_t length;
// Flag to show is this encoded images should be discarded by analyzing
// decoder because of not required spatial layer/simulcast stream.
bool discard;
// Data from first 3 bytes of origin encoded image's payload.
- uint8_t origin_data[3];
+ uint8_t origin_data[ExtractionInfo::kUsedBufferSize];
};
struct ExtractionInfoVector {
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector_unittest.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector_unittest.cc
index 67cafa75a6d..e25361e337b 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector_unittest.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/single_process_encoded_image_data_injector_unittest.cc
@@ -44,6 +44,7 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardFalse) {
EXPECT_FALSE(out.discard);
EXPECT_EQ(out.image.size(), 10ul);
EXPECT_EQ(out.image.capacity(), 10ul);
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out.image.data()[i], i + 1);
}
@@ -63,6 +64,60 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractDiscardTrue) {
EXPECT_TRUE(out.discard);
EXPECT_EQ(out.image.size(), 0ul);
EXPECT_EQ(out.image.capacity(), 10ul);
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
+}
+
+TEST(SingleProcessEncodedImageDataInjector, InjectWithUnsetSpatialLayerSizes) {
+ SingleProcessEncodedImageDataInjector injector;
+
+ rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
+
+ EncodedImage source(buffer.data(), 10, 10);
+ source.SetTimestamp(123456789);
+
+ EncodedImage intermediate = injector.InjectData(512, false, source, 1);
+ intermediate.SetSpatialIndex(2);
+
+ EncodedImageExtractionResult out = injector.ExtractData(intermediate, 2);
+ EXPECT_EQ(out.id, 512);
+ EXPECT_FALSE(out.discard);
+ EXPECT_EQ(out.image.size(), 10ul);
+ EXPECT_EQ(out.image.capacity(), 10ul);
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(out.image.data()[i], i + 1);
+ }
+ EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
+ for (int i = 0; i < 3; ++i) {
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(i).value_or(0), 0ul);
+ }
+}
+
+TEST(SingleProcessEncodedImageDataInjector, InjectWithZeroSpatialLayerSizes) {
+ SingleProcessEncodedImageDataInjector injector;
+
+ rtc::Buffer buffer = CreateBufferOfSizeNFilledWithValuesFromX(10, 1);
+
+ EncodedImage source(buffer.data(), 10, 10);
+ source.SetTimestamp(123456789);
+
+ EncodedImage intermediate = injector.InjectData(512, false, source, 1);
+ intermediate.SetSpatialIndex(2);
+ intermediate.SetSpatialLayerFrameSize(0, 0);
+ intermediate.SetSpatialLayerFrameSize(1, 0);
+ intermediate.SetSpatialLayerFrameSize(2, 0);
+
+ EncodedImageExtractionResult out = injector.ExtractData(intermediate, 2);
+ EXPECT_EQ(out.id, 512);
+ EXPECT_FALSE(out.discard);
+ EXPECT_EQ(out.image.size(), 10ul);
+ EXPECT_EQ(out.image.capacity(), 10ul);
+ for (int i = 0; i < 10; ++i) {
+ EXPECT_EQ(out.image.data()[i], i + 1);
+ }
+ EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
+ for (int i = 0; i < 3; ++i) {
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(i).value_or(0), 0ul);
+ }
}
TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
@@ -95,6 +150,7 @@ TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
EXPECT_FALSE(out1.discard);
EXPECT_EQ(out1.image.size(), 10ul);
EXPECT_EQ(out1.image.capacity(), 10ul);
+ EXPECT_EQ(out1.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out1.image.data()[i], i + 1);
}
@@ -102,10 +158,12 @@ TEST(SingleProcessEncodedImageDataInjector, Inject3Extract3) {
EXPECT_TRUE(out2.discard);
EXPECT_EQ(out2.image.size(), 0ul);
EXPECT_EQ(out2.image.capacity(), 10ul);
+ EXPECT_EQ(out2.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
EXPECT_EQ(out3.id, 520);
EXPECT_FALSE(out3.discard);
EXPECT_EQ(out3.image.size(), 10ul);
EXPECT_EQ(out3.image.capacity(), 10ul);
+ EXPECT_EQ(out3.image.SpatialLayerFrameSize(0).value_or(0), 0ul);
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(out3.image.data()[i], i + 21);
}
@@ -140,6 +198,10 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractFromConcatenated) {
concatenated_buffer.AppendData(intermediate3.data(), intermediate3.size());
EncodedImage concatenated(concatenated_buffer.data(), concatenated_length,
concatenated_length);
+ concatenated.SetSpatialIndex(2);
+ concatenated.SetSpatialLayerFrameSize(0, intermediate1.size());
+ concatenated.SetSpatialLayerFrameSize(1, intermediate2.size());
+ concatenated.SetSpatialLayerFrameSize(2, intermediate3.size());
// Extract frame id from concatenated image
EncodedImageExtractionResult out = injector.ExtractData(concatenated, 2);
@@ -152,6 +214,10 @@ TEST(SingleProcessEncodedImageDataInjector, InjectExtractFromConcatenated) {
EXPECT_EQ(out.image.data()[i], i + 1);
EXPECT_EQ(out.image.data()[i + 10], i + 21);
}
+ EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(0).value_or(0), 10ul);
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(1).value_or(0), 0ul);
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(2).value_or(0), 10ul);
}
TEST(SingleProcessEncodedImageDataInjector,
@@ -184,6 +250,10 @@ TEST(SingleProcessEncodedImageDataInjector,
concatenated_buffer.AppendData(intermediate3.data(), intermediate3.size());
EncodedImage concatenated(concatenated_buffer.data(), concatenated_length,
concatenated_length);
+ concatenated.SetSpatialIndex(2);
+ concatenated.SetSpatialLayerFrameSize(0, intermediate1.size());
+ concatenated.SetSpatialLayerFrameSize(1, intermediate2.size());
+ concatenated.SetSpatialLayerFrameSize(2, intermediate3.size());
// Extract frame id from concatenated image
EncodedImageExtractionResult out = injector.ExtractData(concatenated, 2);
@@ -192,6 +262,10 @@ TEST(SingleProcessEncodedImageDataInjector,
EXPECT_TRUE(out.discard);
EXPECT_EQ(out.image.size(), 0ul);
EXPECT_EQ(out.image.capacity(), 3 * 10ul);
+ EXPECT_EQ(out.image.SpatialIndex().value_or(0), 2);
+ for (int i = 0; i < 3; ++i) {
+ EXPECT_EQ(out.image.SpatialLayerFrameSize(i).value_or(0), 0ul);
+ }
}
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc
index 074188439b3..19487778485 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.cc
@@ -14,6 +14,8 @@
#include <vector>
#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
#include "test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h"
#include "test/pc/e2e/analyzer/video/quality_analyzing_video_encoder.h"
#include "test/pc/e2e/analyzer/video/simulcast_dummy_buffer_helper.h"
@@ -43,10 +45,12 @@ class AnalyzingFramePreprocessor
: public test::TestVideoCapturer::FramePreprocessor {
public:
AnalyzingFramePreprocessor(
- std::string stream_label,
+ absl::string_view peer_name,
+ absl::string_view stream_label,
VideoQualityAnalyzerInterface* analyzer,
std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>> sinks)
- : stream_label_(std::move(stream_label)),
+ : peer_name_(peer_name),
+ stream_label_(stream_label),
analyzer_(analyzer),
sinks_(std::move(sinks)) {}
~AnalyzingFramePreprocessor() override = default;
@@ -54,7 +58,8 @@ class AnalyzingFramePreprocessor
VideoFrame Preprocess(const VideoFrame& source_frame) override {
// Copy VideoFrame to be able to set id on it.
VideoFrame frame = source_frame;
- uint16_t frame_id = analyzer_->OnFrameCaptured(stream_label_, frame);
+ uint16_t frame_id =
+ analyzer_->OnFrameCaptured(peer_name_, stream_label_, frame);
frame.set_id(frame_id);
for (auto& sink : sinks_) {
@@ -64,6 +69,7 @@ class AnalyzingFramePreprocessor
}
private:
+ const std::string peer_name_;
const std::string stream_label_;
VideoQualityAnalyzerInterface* const analyzer_;
const std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>>
@@ -88,26 +94,29 @@ VideoQualityAnalyzerInjectionHelper::~VideoQualityAnalyzerInjectionHelper() =
std::unique_ptr<VideoEncoderFactory>
VideoQualityAnalyzerInjectionHelper::WrapVideoEncoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoEncoderFactory> delegate,
double bitrate_multiplier,
std::map<std::string, absl::optional<int>> stream_required_spatial_index)
const {
return std::make_unique<QualityAnalyzingVideoEncoderFactory>(
- std::move(delegate), bitrate_multiplier,
+ peer_name, std::move(delegate), bitrate_multiplier,
std::move(stream_required_spatial_index),
encoding_entities_id_generator_.get(), injector_, analyzer_.get());
}
std::unique_ptr<VideoDecoderFactory>
VideoQualityAnalyzerInjectionHelper::WrapVideoDecoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoDecoderFactory> delegate) const {
return std::make_unique<QualityAnalyzingVideoDecoderFactory>(
- std::move(delegate), encoding_entities_id_generator_.get(), extractor_,
- analyzer_.get());
+ peer_name, std::move(delegate), encoding_entities_id_generator_.get(),
+ extractor_, analyzer_.get());
}
std::unique_ptr<test::TestVideoCapturer::FramePreprocessor>
VideoQualityAnalyzerInjectionHelper::CreateFramePreprocessor(
+ absl::string_view peer_name,
const VideoConfig& config) {
std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>> sinks;
test::VideoFrameWriter* writer =
@@ -125,23 +134,27 @@ VideoQualityAnalyzerInjectionHelper::CreateFramePreprocessor(
known_video_configs_.insert({*config.stream_label, config});
}
return std::make_unique<AnalyzingFramePreprocessor>(
- std::move(*config.stream_label), analyzer_.get(), std::move(sinks));
+ peer_name, std::move(*config.stream_label), analyzer_.get(),
+ std::move(sinks));
}
std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>
-VideoQualityAnalyzerInjectionHelper::CreateVideoSink() {
- return std::make_unique<AnalyzingVideoSink>(this);
+VideoQualityAnalyzerInjectionHelper::CreateVideoSink(
+ absl::string_view peer_name) {
+ return std::make_unique<AnalyzingVideoSink>(peer_name, this);
}
-void VideoQualityAnalyzerInjectionHelper::Start(std::string test_case_name,
- int max_threads_count) {
- analyzer_->Start(std::move(test_case_name), max_threads_count);
+void VideoQualityAnalyzerInjectionHelper::Start(
+ std::string test_case_name,
+ rtc::ArrayView<const std::string> peer_names,
+ int max_threads_count) {
+ analyzer_->Start(std::move(test_case_name), peer_names, max_threads_count);
}
void VideoQualityAnalyzerInjectionHelper::OnStatsReports(
- const std::string& pc_label,
- const StatsReports& stats_reports) {
- analyzer_->OnStatsReports(pc_label, stats_reports);
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) {
+ analyzer_->OnStatsReports(pc_label, report);
}
void VideoQualityAnalyzerInjectionHelper::Stop() {
@@ -169,12 +182,13 @@ VideoQualityAnalyzerInjectionHelper::MaybeCreateVideoWriter(
return out;
}
-void VideoQualityAnalyzerInjectionHelper::OnFrame(const VideoFrame& frame) {
+void VideoQualityAnalyzerInjectionHelper::OnFrame(absl::string_view peer_name,
+ const VideoFrame& frame) {
if (IsDummyFrameBuffer(frame.video_frame_buffer()->ToI420())) {
// This is dummy frame, so we don't need to process it further.
return;
}
- analyzer_->OnFrameRendered(frame);
+ analyzer_->OnFrameRendered(peer_name, frame);
std::string stream_label = analyzer_->GetStreamLabel(frame.id());
std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>>* sinks =
PopulateSinks(stream_label);
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h
index a0daa9ff18a..ca5243484d4 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_analyzer_injection_helper.h
@@ -14,7 +14,10 @@
#include <map>
#include <memory>
#include <string>
+#include <vector>
+#include "absl/strings/string_view.h"
+#include "api/array_view.h"
#include "api/test/peerconnection_quality_test_fixture.h"
#include "api/test/stats_observer_interface.h"
#include "api/test/video_quality_analyzer_interface.h"
@@ -46,6 +49,7 @@ class VideoQualityAnalyzerInjectionHelper : public StatsObserverInterface {
// Wraps video encoder factory to give video quality analyzer access to frames
// before encoding and encoded images after.
std::unique_ptr<VideoEncoderFactory> WrapVideoEncoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoEncoderFactory> delegate,
double bitrate_multiplier,
std::map<std::string, absl::optional<int>> stream_required_spatial_index)
@@ -53,25 +57,31 @@ class VideoQualityAnalyzerInjectionHelper : public StatsObserverInterface {
// Wraps video decoder factory to give video quality analyzer access to
// received encoded images and frames, that were decoded from them.
std::unique_ptr<VideoDecoderFactory> WrapVideoDecoderFactory(
+ absl::string_view peer_name,
std::unique_ptr<VideoDecoderFactory> delegate) const;
// Creates VideoFrame preprocessor, that will allow video quality analyzer to
// get access to the captured frames. If provided config also specifies
// |input_dump_file_name|, video will be written into that file.
std::unique_ptr<test::TestVideoCapturer::FramePreprocessor>
- CreateFramePreprocessor(const VideoConfig& config);
+ CreateFramePreprocessor(absl::string_view peer_name,
+ const VideoConfig& config);
// Creates sink, that will allow video quality analyzer to get access to
// the rendered frames. If corresponding video track has
// |output_dump_file_name| in its VideoConfig, then video also will be written
// into that file.
- std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> CreateVideoSink();
+ std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> CreateVideoSink(
+ absl::string_view peer_name);
- void Start(std::string test_case_name, int max_threads_count);
+ void Start(std::string test_case_name,
+ rtc::ArrayView<const std::string> peer_names,
+ int max_threads_count);
// Forwards |stats_reports| for Peer Connection |pc_label| to
// |analyzer_|.
- void OnStatsReports(const std::string& pc_label,
- const StatsReports& stats_reports) override;
+ void OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override;
// Stops VideoQualityAnalyzerInterface to populate final data and metrics.
// Should be invoked after analyzed video tracks are disposed.
@@ -80,20 +90,24 @@ class VideoQualityAnalyzerInjectionHelper : public StatsObserverInterface {
private:
class AnalyzingVideoSink final : public rtc::VideoSinkInterface<VideoFrame> {
public:
- explicit AnalyzingVideoSink(VideoQualityAnalyzerInjectionHelper* helper)
- : helper_(helper) {}
+ explicit AnalyzingVideoSink(absl::string_view peer_name,
+ VideoQualityAnalyzerInjectionHelper* helper)
+ : peer_name_(peer_name), helper_(helper) {}
~AnalyzingVideoSink() override = default;
- void OnFrame(const VideoFrame& frame) override { helper_->OnFrame(frame); }
+ void OnFrame(const VideoFrame& frame) override {
+ helper_->OnFrame(peer_name_, frame);
+ }
private:
+ const std::string peer_name_;
VideoQualityAnalyzerInjectionHelper* const helper_;
};
test::VideoFrameWriter* MaybeCreateVideoWriter(
absl::optional<std::string> file_name,
const PeerConnectionE2EQualityTestFixture::VideoConfig& config);
- void OnFrame(const VideoFrame& frame);
+ void OnFrame(absl::string_view peer_name, const VideoFrame& frame);
std::vector<std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>>>*
PopulateSinks(const std::string& stream_label);
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
index 754a0a468fe..baf973f2770 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.cc
@@ -10,51 +10,88 @@
#include "test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h"
+#include "api/stats/rtc_stats.h"
+#include "api/stats/rtcstats_objects.h"
+#include "api/units/data_rate.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
+
namespace webrtc {
namespace webrtc_pc_e2e {
-namespace {
-
-constexpr int kBitsInByte = 8;
-
-} // namespace
void VideoQualityMetricsReporter::Start(absl::string_view test_case_name) {
test_case_name_ = std::string(test_case_name);
+ start_time_ = Now();
}
-// TODO(bugs.webrtc.org/10430): Migrate to the new GetStats as soon as
-// bugs.webrtc.org/10428 is fixed.
void VideoQualityMetricsReporter::OnStatsReports(
- const std::string& pc_label,
- const StatsReports& stats_reports) {
- for (const StatsReport* stats_report : stats_reports) {
- // The only stats collected by this analyzer are present in
- // kStatsReportTypeBwe reports, so all other reports are just ignored.
- if (stats_report->type() != StatsReport::StatsType::kStatsReportTypeBwe) {
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) {
+ RTC_CHECK(start_time_)
+ << "Please invoke Start(...) method before calling OnStatsReports(...)";
+
+ auto transport_stats = report->GetStatsOfType<RTCTransportStats>();
+ if (transport_stats.size() == 0u ||
+ !transport_stats[0]->selected_candidate_pair_id.is_defined()) {
+ return;
+ }
+ RTC_DCHECK_EQ(transport_stats.size(), 1);
+ std::string selected_ice_id =
+ transport_stats[0]->selected_candidate_pair_id.ValueToString();
+ // Use the selected ICE candidate pair ID to get the appropriate ICE stats.
+ const RTCIceCandidatePairStats ice_candidate_pair_stats =
+ report->Get(selected_ice_id)->cast_to<const RTCIceCandidatePairStats>();
+
+ auto outbound_rtp_stats = report->GetStatsOfType<RTCOutboundRTPStreamStats>();
+ StatsSample sample;
+ for (auto& s : outbound_rtp_stats) {
+ if (!s->media_type.is_defined()) {
+ continue;
+ }
+ if (!(*s->media_type == RTCMediaStreamTrackKind::kVideo)) {
continue;
}
- const webrtc::StatsReport::Value* available_send_bandwidth =
- stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameAvailableSendBandwidth);
- const webrtc::StatsReport::Value* retransmission_bitrate =
- stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameRetransmitBitrate);
- const webrtc::StatsReport::Value* transmission_bitrate =
- stats_report->FindValue(
- StatsReport::StatsValueName::kStatsValueNameTransmitBitrate);
- RTC_CHECK(available_send_bandwidth);
- RTC_CHECK(retransmission_bitrate);
- RTC_CHECK(transmission_bitrate);
-
- rtc::CritScope crit(&video_bwe_stats_lock_);
- VideoBweStats& video_bwe_stats = video_bwe_stats_[pc_label];
+ if (s->timestamp_us() > sample.sample_time.us()) {
+ sample.sample_time = Timestamp::Micros(s->timestamp_us());
+ }
+ sample.retransmitted_bytes_sent +=
+ DataSize::Bytes(s->retransmitted_bytes_sent.ValueOrDefault(0ul));
+ sample.bytes_sent += DataSize::Bytes(s->bytes_sent.ValueOrDefault(0ul));
+ sample.header_bytes_sent +=
+ DataSize::Bytes(s->header_bytes_sent.ValueOrDefault(0ul));
+ }
+
+ rtc::CritScope crit(&video_bwe_stats_lock_);
+ VideoBweStats& video_bwe_stats = video_bwe_stats_[std::string(pc_label)];
+ if (ice_candidate_pair_stats.available_outgoing_bitrate.is_defined()) {
video_bwe_stats.available_send_bandwidth.AddSample(
- available_send_bandwidth->int_val());
- video_bwe_stats.transmission_bitrate.AddSample(
- transmission_bitrate->int_val());
- video_bwe_stats.retransmission_bitrate.AddSample(
- retransmission_bitrate->int_val());
+ DataRate::BitsPerSec(
+ *ice_candidate_pair_stats.available_outgoing_bitrate)
+ .bytes_per_sec());
+ }
+
+ StatsSample prev_sample = last_stats_sample_[std::string(pc_label)];
+ if (prev_sample.sample_time.IsZero()) {
+ prev_sample.sample_time = start_time_.value();
+ }
+ last_stats_sample_[std::string(pc_label)] = sample;
+
+ TimeDelta time_between_samples = sample.sample_time - prev_sample.sample_time;
+ if (time_between_samples.IsZero()) {
+ return;
}
+
+ DataRate retransmission_bitrate =
+ (sample.retransmitted_bytes_sent - prev_sample.retransmitted_bytes_sent) /
+ time_between_samples;
+ video_bwe_stats.retransmission_bitrate.AddSample(
+ retransmission_bitrate.bytes_per_sec());
+ DataRate transmission_bitrate =
+ (sample.bytes_sent + sample.header_bytes_sent - prev_sample.bytes_sent -
+ prev_sample.header_bytes_sent) /
+ time_between_samples;
+ video_bwe_stats.transmission_bitrate.AddSample(
+ transmission_bitrate.bytes_per_sec());
}
void VideoQualityMetricsReporter::StopAndReportResults() {
@@ -73,14 +110,11 @@ void VideoQualityMetricsReporter::ReportVideoBweResults(
const std::string& test_case_name,
const VideoBweStats& video_bwe_stats) {
ReportResult("available_send_bandwidth", test_case_name,
- video_bwe_stats.available_send_bandwidth / kBitsInByte,
- "bytesPerSecond");
+ video_bwe_stats.available_send_bandwidth, "bytesPerSecond");
ReportResult("transmission_bitrate", test_case_name,
- video_bwe_stats.transmission_bitrate / kBitsInByte,
- "bytesPerSecond");
+ video_bwe_stats.transmission_bitrate, "bytesPerSecond");
ReportResult("retransmission_bitrate", test_case_name,
- video_bwe_stats.retransmission_bitrate / kBitsInByte,
- "bytesPerSecond");
+ video_bwe_stats.retransmission_bitrate, "bytesPerSecond");
}
void VideoQualityMetricsReporter::ReportResult(
diff --git a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h
index 1688a7b6fcf..a6ac9b4fa18 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h
@@ -15,6 +15,8 @@
#include <string>
#include "api/test/peerconnection_quality_test_fixture.h"
+#include "api/units/data_size.h"
+#include "api/units/timestamp.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/numerics/samples_stats_counter.h"
#include "test/testsupport/perf_test.h"
@@ -31,15 +33,24 @@ struct VideoBweStats {
class VideoQualityMetricsReporter
: public PeerConnectionE2EQualityTestFixture::QualityMetricsReporter {
public:
- VideoQualityMetricsReporter() = default;
+ VideoQualityMetricsReporter(Clock* const clock) : clock_(clock) {}
~VideoQualityMetricsReporter() override = default;
void Start(absl::string_view test_case_name) override;
- void OnStatsReports(const std::string& pc_label,
- const StatsReports& reports) override;
+ void OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override;
void StopAndReportResults() override;
private:
+ struct StatsSample {
+ DataSize bytes_sent = DataSize::Zero();
+ DataSize header_bytes_sent = DataSize::Zero();
+ DataSize retransmitted_bytes_sent = DataSize::Zero();
+
+ Timestamp sample_time = Timestamp::Zero();
+ };
+
std::string GetTestCaseName(const std::string& stream_label) const;
static void ReportVideoBweResults(const std::string& test_case_name,
const VideoBweStats& video_bwe_stats);
@@ -50,14 +61,20 @@ class VideoQualityMetricsReporter
const std::string& unit,
webrtc::test::ImproveDirection improve_direction =
webrtc::test::ImproveDirection::kNone);
+ Timestamp Now() const { return clock_->CurrentTime(); }
+
+ Clock* const clock_;
std::string test_case_name_;
+ absl::optional<Timestamp> start_time_;
rtc::CriticalSection video_bwe_stats_lock_;
// Map between a peer connection label (provided by the framework) and
// its video BWE stats.
std::map<std::string, VideoBweStats> video_bwe_stats_
RTC_GUARDED_BY(video_bwe_stats_lock_);
+ std::map<std::string, StatsSample> last_stats_sample_
+ RTC_GUARDED_BY(video_bwe_stats_lock_);
};
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/echo/echo_emulation.cc b/chromium/third_party/webrtc/test/pc/e2e/echo/echo_emulation.cc
index 2beaa34cbd8..230e8e3eca9 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/echo/echo_emulation.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/echo/echo_emulation.cc
@@ -57,17 +57,7 @@ void EchoEmulatingCapturer::OnAudioRendered(
}
queue_input_.assign(data.begin(), data.end());
if (!renderer_queue_.Insert(&queue_input_)) {
- // Test audio device works too slow with sanitizers and on some platforms
- // and can't properly process audio, so when capturer will be stopped
- // renderer will quickly overfill the queue.
- // TODO(crbug.com/webrtc/10850) remove it when test ADM will be fast enough.
-#if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
- defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \
- (defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG))
RTC_LOG(WARNING) << "Echo queue is full";
-#else
- RTC_CHECK(false) << "Echo queue is full";
-#endif
}
}
diff --git a/chromium/third_party/webrtc/test/pc/e2e/media/media_helper.cc b/chromium/third_party/webrtc/test/pc/e2e/media/media_helper.cc
index d3fa6ffe039..d1c27838a6e 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/media/media_helper.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/media/media_helper.cc
@@ -58,7 +58,7 @@ MediaHelper::MaybeAddVideo(TestPeer* peer) {
std::unique_ptr<test::TestVideoCapturer> capturer = CreateVideoCapturer(
video_config, peer->ReleaseVideoSource(i),
video_quality_analyzer_injection_helper_->CreateFramePreprocessor(
- video_config));
+ params->name.value(), video_config));
bool is_screencast =
video_config.content_hint == VideoTrackInterface::ContentHint::kText ||
video_config.content_hint ==
diff --git a/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.cc b/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.cc
index 56f0337037c..3b232fdc710 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.cc
@@ -11,7 +11,8 @@
#include <utility>
-#include "api/stats_types.h"
+#include "api/stats/rtc_stats.h"
+#include "api/stats/rtcstats_objects.h"
#include "rtc_base/event.h"
#include "system_wrappers/include/field_trial.h"
#include "test/testsupport/perf_test.h"
@@ -40,28 +41,29 @@ void NetworkQualityMetricsReporter::Start(absl::string_view test_case_name) {
}
void NetworkQualityMetricsReporter::OnStatsReports(
- const std::string& pc_label,
- const StatsReports& reports) {
- rtc::CritScope cs(&lock_);
- int64_t payload_bytes_received = 0;
- int64_t payload_bytes_sent = 0;
- for (const StatsReport* report : reports) {
- if (report->type() == StatsReport::kStatsReportTypeSsrc) {
- const auto* received =
- report->FindValue(StatsReport::kStatsValueNameBytesReceived);
- if (received) {
- payload_bytes_received += received->int64_val();
- }
- const auto* sent =
- report->FindValue(StatsReport::kStatsValueNameBytesSent);
- if (sent) {
- payload_bytes_sent += sent->int64_val();
- }
- }
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) {
+ DataSize payload_received = DataSize::Zero();
+ DataSize payload_sent = DataSize::Zero();
+
+ auto inbound_stats = report->GetStatsOfType<RTCInboundRTPStreamStats>();
+ for (const auto& stat : inbound_stats) {
+ payload_received +=
+ DataSize::Bytes(stat->bytes_received.ValueOrDefault(0ul) +
+ stat->header_bytes_received.ValueOrDefault(0ul));
+ }
+
+ auto outbound_stats = report->GetStatsOfType<RTCOutboundRTPStreamStats>();
+ for (const auto& stat : outbound_stats) {
+ payload_sent +=
+ DataSize::Bytes(stat->bytes_sent.ValueOrDefault(0ul) +
+ stat->header_bytes_sent.ValueOrDefault(0ul));
}
- PCStats& stats = pc_stats_[pc_label];
- stats.payload_bytes_received = payload_bytes_received;
- stats.payload_bytes_sent = payload_bytes_sent;
+
+ rtc::CritScope cs(&lock_);
+ PCStats& stats = pc_stats_[std::string(pc_label)];
+ stats.payload_received = payload_received;
+ stats.payload_sent = payload_sent;
}
void NetworkQualityMetricsReporter::StopAndReportResults() {
@@ -125,9 +127,9 @@ void NetworkQualityMetricsReporter::ReportStats(
void NetworkQualityMetricsReporter::ReportPCStats(const std::string& pc_label,
const PCStats& stats) {
- ReportResult("payload_bytes_received", pc_label, stats.payload_bytes_received,
- "sizeInBytes");
- ReportResult("payload_bytes_sent", pc_label, stats.payload_bytes_sent,
+ ReportResult("payload_bytes_received", pc_label,
+ stats.payload_received.bytes(), "sizeInBytes");
+ ReportResult("payload_bytes_sent", pc_label, stats.payload_sent.bytes(),
"sizeInBytes");
}
diff --git a/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.h b/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.h
index 6454f175260..932e03140be 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/network_quality_metrics_reporter.h
@@ -15,6 +15,7 @@
#include "api/test/network_emulation_manager.h"
#include "api/test/peerconnection_quality_test_fixture.h"
+#include "api/units/data_size.h"
#include "rtc_base/critical_section.h"
namespace webrtc {
@@ -30,16 +31,17 @@ class NetworkQualityMetricsReporter
// Network stats must be empty when this method will be invoked.
void Start(absl::string_view test_case_name) override;
- void OnStatsReports(const std::string& pc_label,
- const StatsReports& reports) override;
+ void OnStatsReports(
+ absl::string_view pc_label,
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override;
void StopAndReportResults() override;
private:
struct PCStats {
// TODO(nisse): Separate audio and video counters. Depends on standard stat
// counters, enabled by field trial "WebRTC-UseStandardBytesStats".
- int64_t payload_bytes_received = 0;
- int64_t payload_bytes_sent = 0;
+ DataSize payload_received = DataSize::Zero();
+ DataSize payload_sent = DataSize::Zero();
};
static EmulatedNetworkStats PopulateStats(
diff --git a/chromium/third_party/webrtc/test/pc/e2e/peer_configurer.h b/chromium/third_party/webrtc/test/pc/e2e/peer_configurer.h
index 010ddcee82c..7da547bdc31 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/peer_configurer.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/peer_configurer.h
@@ -23,7 +23,6 @@
#include "api/task_queue/task_queue_factory.h"
#include "api/test/create_peer_connection_quality_test_frame_generator.h"
#include "api/test/peerconnection_quality_test_fixture.h"
-#include "api/transport/media/media_transport_interface.h"
#include "api/transport/network_control.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
@@ -86,12 +85,6 @@ class PeerConfigurerImpl final
std::move(network_controller_factory);
return this;
}
- PeerConfigurer* SetMediaTransportFactory(
- std::unique_ptr<MediaTransportFactory> media_transport_factory) override {
- components_->pcf_dependencies->media_transport_factory =
- std::move(media_transport_factory);
- return this;
- }
PeerConfigurer* SetVideoEncoderFactory(
std::unique_ptr<VideoEncoderFactory> video_encoder_factory) override {
components_->pcf_dependencies->video_encoder_factory =
@@ -172,7 +165,15 @@ class PeerConfigurerImpl final
}
PeerConfigurer* SetBitrateParameters(
PeerConnectionInterface::BitrateParameters bitrate_params) override {
- params_->bitrate_params = bitrate_params;
+ BitrateSettings bitrate_settings;
+ bitrate_settings.min_bitrate_bps = bitrate_params.min_bitrate_bps;
+ bitrate_settings.start_bitrate_bps = bitrate_params.current_bitrate_bps;
+ bitrate_settings.max_bitrate_bps = bitrate_params.max_bitrate_bps;
+ return SetBitrateSettings(bitrate_settings);
+ }
+ PeerConfigurer* SetBitrateSettings(
+ BitrateSettings bitrate_settings) override {
+ params_->bitrate_settings = bitrate_settings;
return this;
}
diff --git a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc
index 8080d4bb0a5..ab6aaa07313 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_e2e_smoke_test.cc
@@ -83,7 +83,7 @@ class PeerConnectionE2EQualityTestSmokeTest : public ::testing::Test {
auto fixture = CreatePeerConnectionE2EQualityTestFixture(
test_case_name, /*audio_quality_analyzer=*/nullptr,
std::move(video_quality_analyzer));
- fixture->ExecuteAt(TimeDelta::Seconds(2),
+ fixture->ExecuteAt(TimeDelta::Seconds(1),
[alice_network_behavior_ptr](TimeDelta) {
BuiltInNetworkBehaviorConfig config;
config.loss_percent = 5;
@@ -110,19 +110,20 @@ class PeerConnectionE2EQualityTestSmokeTest : public ::testing::Test {
fixture->Run(run_params);
EXPECT_GE(fixture->GetRealTestDuration(), run_params.run_duration);
- for (auto stream_label : video_analyzer_ptr->GetKnownVideoStreams()) {
+ for (auto stream_key : video_analyzer_ptr->GetKnownVideoStreams()) {
FrameCounters stream_conters =
- video_analyzer_ptr->GetPerStreamCounters().at(stream_label);
+ video_analyzer_ptr->GetPerStreamCounters().at(stream_key);
// On some devices the pipeline can be too slow, so we actually can't
// force real constraints here. Lets just check, that at least 1
// frame passed whole pipeline.
- int64_t expected_min_fps = run_params.run_duration.seconds() * 30;
- EXPECT_GE(stream_conters.captured, expected_min_fps);
- EXPECT_GE(stream_conters.pre_encoded, 1);
- EXPECT_GE(stream_conters.encoded, 1);
- EXPECT_GE(stream_conters.received, 1);
- EXPECT_GE(stream_conters.decoded, 1);
- EXPECT_GE(stream_conters.rendered, 1);
+ int64_t expected_min_fps = run_params.run_duration.seconds() * 15;
+ EXPECT_GE(stream_conters.captured, expected_min_fps)
+ << stream_key.ToString();
+ EXPECT_GE(stream_conters.pre_encoded, 1) << stream_key.ToString();
+ EXPECT_GE(stream_conters.encoded, 1) << stream_key.ToString();
+ EXPECT_GE(stream_conters.received, 1) << stream_key.ToString();
+ EXPECT_GE(stream_conters.decoded, 1) << stream_key.ToString();
+ EXPECT_GE(stream_conters.rendered, 1) << stream_key.ToString();
}
}
};
@@ -148,7 +149,7 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Smoke) {
RunTest(
"smoke", run_params,
[](PeerConfigurer* alice) {
- VideoConfig video(640, 360, 30);
+ VideoConfig video(160, 120, 15);
video.stream_label = "alice-video";
video.sync_group = "alice-media";
alice->AddVideoConfig(std::move(video));
@@ -164,23 +165,11 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Smoke) {
},
[](PeerConfigurer* charlie) {
charlie->SetName("charlie");
- VideoConfig video(640, 360, 30);
+ VideoConfig video(160, 120, 15);
video.stream_label = "charlie-video";
video.temporal_layers_count = 2;
charlie->AddVideoConfig(std::move(video));
- VideoConfig screenshare(640, 360, 30);
- screenshare.stream_label = "charlie-screenshare";
- screenshare.content_hint = VideoTrackInterface::ContentHint::kText;
- ScreenShareConfig screen_share_config =
- ScreenShareConfig(TimeDelta::Seconds(2));
- screen_share_config.scrolling_params = ScrollingParams(
- TimeDelta::Millis(1800), kDefaultSlidesWidth, kDefaultSlidesHeight);
- auto screen_share_frame_generator =
- CreateScreenShareFrameGenerator(screenshare, screen_share_config);
- charlie->AddVideoConfig(std::move(screenshare),
- std::move(screen_share_frame_generator));
-
AudioConfig audio;
audio.stream_label = "charlie-audio";
audio.mode = AudioConfig::Mode::kFile;
@@ -192,6 +181,35 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Smoke) {
// IOS debug builds can be quite slow, disabling to avoid issues with timeouts.
#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM64) && !defined(NDEBUG)
+#define MAYBE_Screenshare DISABLED_Screenshare
+#else
+#define MAYBE_Screenshare Screenshare
+#endif
+TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Screenshare) {
+ RunParams run_params(TimeDelta::Seconds(2));
+ test::ScopedFieldTrials field_trials(
+ std::string(field_trial::GetFieldTrialString()) +
+ "WebRTC-UseStandardBytesStats/Enabled/");
+ RunTest(
+ "screenshare", run_params,
+ [](PeerConfigurer* alice) {
+ VideoConfig screenshare(320, 180, 30);
+ screenshare.stream_label = "alice-screenshare";
+ screenshare.content_hint = VideoTrackInterface::ContentHint::kText;
+ ScreenShareConfig screen_share_config =
+ ScreenShareConfig(TimeDelta::Seconds(2));
+ screen_share_config.scrolling_params = ScrollingParams(
+ TimeDelta::Millis(1800), kDefaultSlidesWidth, kDefaultSlidesHeight);
+ auto screen_share_frame_generator =
+ CreateScreenShareFrameGenerator(screenshare, screen_share_config);
+ alice->AddVideoConfig(std::move(screenshare),
+ std::move(screen_share_frame_generator));
+ },
+ [](PeerConfigurer* charlie) {});
+}
+
+// IOS debug builds can be quite slow, disabling to avoid issues with timeouts.
+#if defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_ARM64) && !defined(NDEBUG)
#define MAYBE_Echo DISABLED_Echo
#else
#define MAYBE_Echo Echo
@@ -232,9 +250,9 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Simulcast) {
RunTest(
"simulcast", run_params,
[](PeerConfigurer* alice) {
- VideoConfig simulcast(1280, 720, 30);
+ VideoConfig simulcast(1280, 720, 15);
simulcast.stream_label = "alice-simulcast";
- simulcast.simulcast_config = VideoSimulcastConfig(3, 0);
+ simulcast.simulcast_config = VideoSimulcastConfig(2, 0);
alice->AddVideoConfig(std::move(simulcast));
AudioConfig audio;
@@ -244,18 +262,7 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Simulcast) {
test::ResourcePath("pc_quality_smoke_test_alice_source", "wav");
alice->SetAudioConfig(std::move(audio));
},
- [](PeerConfigurer* bob) {
- VideoConfig video(640, 360, 30);
- video.stream_label = "bob-video";
- bob->AddVideoConfig(std::move(video));
-
- AudioConfig audio;
- audio.stream_label = "bob-audio";
- audio.mode = AudioConfig::Mode::kFile;
- audio.input_file_name =
- test::ResourcePath("pc_quality_smoke_test_bob_source", "wav");
- bob->SetAudioConfig(std::move(audio));
- });
+ [](PeerConfigurer* bob) {});
}
// IOS debug builds can be quite slow, disabling to avoid issues with timeouts.
@@ -270,11 +277,11 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Svc) {
RunTest(
"simulcast", run_params,
[](PeerConfigurer* alice) {
- VideoConfig simulcast(1280, 720, 30);
+ VideoConfig simulcast(1280, 720, 15);
simulcast.stream_label = "alice-svc";
// Because we have network with packets loss we can analyze only the
// highest spatial layer in SVC mode.
- simulcast.simulcast_config = VideoSimulcastConfig(3, 2);
+ simulcast.simulcast_config = VideoSimulcastConfig(2, 1);
alice->AddVideoConfig(std::move(simulcast));
AudioConfig audio;
@@ -284,18 +291,7 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_Svc) {
test::ResourcePath("pc_quality_smoke_test_alice_source", "wav");
alice->SetAudioConfig(std::move(audio));
},
- [](PeerConfigurer* bob) {
- VideoConfig video(640, 360, 30);
- video.stream_label = "bob-video";
- bob->AddVideoConfig(std::move(video));
-
- AudioConfig audio;
- audio.stream_label = "bob-audio";
- audio.mode = AudioConfig::Mode::kFile;
- audio.input_file_name =
- test::ResourcePath("pc_quality_smoke_test_bob_source", "wav");
- bob->SetAudioConfig(std::move(audio));
- });
+ [](PeerConfigurer* bob) {});
}
// IOS debug builds can be quite slow, disabling to avoid issues with timeouts.
@@ -312,11 +308,11 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_HighBitrate) {
RunTest(
"smoke", run_params,
[](PeerConfigurer* alice) {
- PeerConnectionInterface::BitrateParameters bitrate_params;
- bitrate_params.current_bitrate_bps = 3'000'000;
- bitrate_params.max_bitrate_bps = 3'000'000;
- alice->SetBitrateParameters(bitrate_params);
- VideoConfig video(800, 600, 30);
+ BitrateSettings bitrate_settings;
+ bitrate_settings.start_bitrate_bps = 3'000'000;
+ bitrate_settings.max_bitrate_bps = 3'000'000;
+ alice->SetBitrateSettings(bitrate_settings);
+ VideoConfig video(800, 600, 15);
video.stream_label = "alice-video";
video.min_encode_bitrate_bps = 500'000;
video.max_encode_bitrate_bps = 3'000'000;
@@ -330,24 +326,7 @@ TEST_F(PeerConnectionE2EQualityTestSmokeTest, MAYBE_HighBitrate) {
audio.sampling_frequency_in_hz = 48000;
alice->SetAudioConfig(std::move(audio));
},
- [](PeerConfigurer* bob) {
- PeerConnectionInterface::BitrateParameters bitrate_params;
- bitrate_params.current_bitrate_bps = 3'000'000;
- bitrate_params.max_bitrate_bps = 3'000'000;
- bob->SetBitrateParameters(bitrate_params);
- VideoConfig video(800, 600, 30);
- video.stream_label = "bob-video";
- video.min_encode_bitrate_bps = 500'000;
- video.max_encode_bitrate_bps = 3'000'000;
- bob->AddVideoConfig(std::move(video));
-
- AudioConfig audio;
- audio.stream_label = "bob-audio";
- audio.mode = AudioConfig::Mode::kFile;
- audio.input_file_name =
- test::ResourcePath("pc_quality_smoke_test_bob_source", "wav");
- bob->SetAudioConfig(std::move(audio));
- });
+ [](PeerConfigurer* bob) {});
}
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.cc b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.cc
index 17104a90aa2..a23d2248f3c 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.cc
@@ -14,6 +14,7 @@
#include <set>
#include <utility>
+#include "absl/strings/string_view.h"
#include "api/jsep.h"
#include "api/media_stream_interface.h"
#include "api/peer_connection_interface.h"
@@ -205,18 +206,21 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
RemotePeerAudioConfig::Create(bob_configurer->params()->audio_config);
absl::optional<RemotePeerAudioConfig> bob_remote_audio_config =
RemotePeerAudioConfig::Create(alice_configurer->params()->audio_config);
- // Copy Alice and Bob video configs to correctly pass them into lambdas.
+ // Copy Alice and Bob video configs and names to correctly pass them into
+ // lambdas.
std::vector<VideoConfig> alice_video_configs =
alice_configurer->params()->video_configs;
+ std::string alice_name = alice_configurer->params()->name.value();
std::vector<VideoConfig> bob_video_configs =
bob_configurer->params()->video_configs;
+ std::string bob_name = bob_configurer->params()->name.value();
alice_ = TestPeerFactory::CreateTestPeer(
std::move(alice_configurer),
std::make_unique<FixturePeerConnectionObserver>(
- [this, bob_video_configs](
+ [this, bob_video_configs, alice_name](
rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
- OnTrackCallback(transceiver, bob_video_configs);
+ OnTrackCallback(alice_name, transceiver, bob_video_configs);
},
[this]() { StartVideo(alice_video_sources_); }),
video_quality_analyzer_injection_helper_.get(), signaling_thread.get(),
@@ -225,9 +229,9 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
bob_ = TestPeerFactory::CreateTestPeer(
std::move(bob_configurer),
std::make_unique<FixturePeerConnectionObserver>(
- [this, alice_video_configs](
- rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
- OnTrackCallback(transceiver, alice_video_configs);
+ [this, alice_video_configs,
+ bob_name](rtc::scoped_refptr<RtpTransceiverInterface> transceiver) {
+ OnTrackCallback(bob_name, transceiver, alice_video_configs);
},
[this]() { StartVideo(bob_video_sources_); }),
video_quality_analyzer_injection_helper_.get(), signaling_thread.get(),
@@ -246,10 +250,13 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) {
std::min(video_analyzer_threads, kMaxVideoAnalyzerThreads);
RTC_LOG(INFO) << "video_analyzer_threads=" << video_analyzer_threads;
quality_metrics_reporters_.push_back(
- std::make_unique<VideoQualityMetricsReporter>());
+ std::make_unique<VideoQualityMetricsReporter>(clock_));
- video_quality_analyzer_injection_helper_->Start(test_case_name_,
- video_analyzer_threads);
+ video_quality_analyzer_injection_helper_->Start(
+ test_case_name_,
+ std::vector<std::string>{alice_->params()->name.value(),
+ bob_->params()->name.value()},
+ video_analyzer_threads);
audio_quality_analyzer_->Start(test_case_name_, &analyzer_helper_);
for (auto& reporter : quality_metrics_reporters_) {
reporter->Start(test_case_name_);
@@ -371,6 +378,7 @@ void PeerConnectionE2EQualityTest::SetupRequiredFieldTrials(
}
void PeerConnectionE2EQualityTest::OnTrackCallback(
+ absl::string_view peer_name,
rtc::scoped_refptr<RtpTransceiverInterface> transceiver,
std::vector<VideoConfig> remote_video_configs) {
const rtc::scoped_refptr<MediaStreamTrackInterface>& track =
@@ -387,7 +395,7 @@ void PeerConnectionE2EQualityTest::OnTrackCallback(
// track->kind() is kVideoKind.
auto* video_track = static_cast<VideoTrackInterface*>(track.get());
std::unique_ptr<rtc::VideoSinkInterface<VideoFrame>> video_sink =
- video_quality_analyzer_injection_helper_->CreateVideoSink();
+ video_quality_analyzer_injection_helper_->CreateVideoSink(peer_name);
video_track->AddOrUpdateSink(video_sink.get(), rtc::VideoSinkWants());
output_video_sinks_.push_back(std::move(video_sink));
}
diff --git a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.h b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.h
index 2eb7e708c6f..b302e5c51b5 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test.h
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
+#include "absl/strings/string_view.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/test/audio_quality_analyzer_interface.h"
#include "api/test/peerconnection_quality_test_fixture.h"
@@ -80,7 +81,8 @@ class PeerConnectionE2EQualityTest
// For some functionality some field trials have to be enabled, so we will
// enable them here.
void SetupRequiredFieldTrials(const RunParams& run_params);
- void OnTrackCallback(rtc::scoped_refptr<RtpTransceiverInterface> transceiver,
+ void OnTrackCallback(absl::string_view peer_name,
+ rtc::scoped_refptr<RtpTransceiverInterface> transceiver,
std::vector<VideoConfig> remote_video_configs);
// Have to be run on the signaling thread.
void SetupCallOnSignalingThread(const RunParams& run_params);
diff --git a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test_params.h b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test_params.h
index ccb53492c3a..edefc7a0084 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test_params.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/peer_connection_quality_test_params.h
@@ -20,7 +20,6 @@
#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/test/peerconnection_quality_test_fixture.h"
-#include "api/transport/media/media_transport_interface.h"
#include "api/transport/network_control.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
@@ -47,7 +46,6 @@ struct PeerConnectionFactoryComponents {
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory;
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory;
std::unique_ptr<NetworkControllerFactoryInterface> network_controller_factory;
- std::unique_ptr<MediaTransportFactory> media_transport_factory;
std::unique_ptr<NetEqFactory> neteq_factory;
// Will be passed to MediaEngineInterface, that will be used in
@@ -114,7 +112,7 @@ struct Params {
absl::optional<std::string> aec_dump_path;
PeerConnectionInterface::RTCConfiguration rtc_configuration;
- PeerConnectionInterface::BitrateParameters bitrate_params;
+ BitrateSettings bitrate_settings;
};
} // namespace webrtc_pc_e2e
diff --git a/chromium/third_party/webrtc/test/pc/e2e/stats_poller.cc b/chromium/third_party/webrtc/test/pc/e2e/stats_poller.cc
index 987f26e7e80..e6973e6af19 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/stats_poller.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/stats_poller.cc
@@ -18,14 +18,13 @@ namespace webrtc {
namespace webrtc_pc_e2e {
void InternalStatsObserver::PollStats() {
- peer_->pc()->GetStats(this, nullptr,
- webrtc::PeerConnectionInterface::StatsOutputLevel::
- kStatsOutputLevelStandard);
+ peer_->pc()->GetStats(this);
}
-void InternalStatsObserver::OnComplete(const StatsReports& reports) {
+void InternalStatsObserver::OnStatsDelivered(
+ const rtc::scoped_refptr<const RTCStatsReport>& report) {
for (auto* observer : observers_) {
- observer->OnStatsReports(pc_label_, reports);
+ observer->OnStatsReports(pc_label_, report);
}
}
diff --git a/chromium/third_party/webrtc/test/pc/e2e/stats_poller.h b/chromium/third_party/webrtc/test/pc/e2e/stats_poller.h
index 3d0c2d68013..157a1478349 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/stats_poller.h
+++ b/chromium/third_party/webrtc/test/pc/e2e/stats_poller.h
@@ -17,6 +17,7 @@
#include <vector>
#include "api/peer_connection_interface.h"
+#include "api/stats/rtc_stats_collector_callback.h"
#include "api/test/stats_observer_interface.h"
#include "test/pc/e2e/test_peer.h"
@@ -25,7 +26,7 @@ namespace webrtc_pc_e2e {
// Helper class that will notify all the webrtc::test::StatsObserverInterface
// objects subscribed.
-class InternalStatsObserver : public StatsObserver {
+class InternalStatsObserver : public RTCStatsCollectorCallback {
public:
InternalStatsObserver(std::string pc_label,
TestPeer* peer,
@@ -36,7 +37,8 @@ class InternalStatsObserver : public StatsObserver {
void PollStats();
- void OnComplete(const StatsReports& reports) override;
+ void OnStatsDelivered(
+ const rtc::scoped_refptr<const RTCStatsReport>& report) override;
private:
std::string pc_label_;
diff --git a/chromium/third_party/webrtc/test/pc/e2e/test_peer_factory.cc b/chromium/third_party/webrtc/test/pc/e2e/test_peer_factory.cc
index 455337ef3a3..f700f1cb787 100644
--- a/chromium/third_party/webrtc/test/pc/e2e/test_peer_factory.cc
+++ b/chromium/third_party/webrtc/test/pc/e2e/test_peer_factory.cc
@@ -12,6 +12,7 @@
#include <utility>
#include "absl/memory/memory.h"
+#include "absl/strings/string_view.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/video_codecs/builtin_video_decoder_factory.h"
#include "api/video_codecs/builtin_video_encoder_factory.h"
@@ -172,6 +173,7 @@ std::unique_ptr<cricket::MediaEngineInterface> CreateMediaEngine(
}
void WrapVideoEncoderFactory(
+ absl::string_view peer_name,
double bitrate_multiplier,
std::map<std::string, absl::optional<int>> stream_required_spatial_index,
PeerConnectionFactoryComponents* pcf_dependencies,
@@ -184,11 +186,12 @@ void WrapVideoEncoderFactory(
}
pcf_dependencies->video_encoder_factory =
video_analyzer_helper->WrapVideoEncoderFactory(
- std::move(video_encoder_factory), bitrate_multiplier,
+ peer_name, std::move(video_encoder_factory), bitrate_multiplier,
std::move(stream_required_spatial_index));
}
void WrapVideoDecoderFactory(
+ absl::string_view peer_name,
PeerConnectionFactoryComponents* pcf_dependencies,
VideoQualityAnalyzerInjectionHelper* video_analyzer_helper) {
std::unique_ptr<VideoDecoderFactory> video_decoder_factory;
@@ -199,7 +202,7 @@ void WrapVideoDecoderFactory(
}
pcf_dependencies->video_decoder_factory =
video_analyzer_helper->WrapVideoDecoderFactory(
- std::move(video_decoder_factory));
+ peer_name, std::move(video_decoder_factory));
}
// Creates PeerConnectionFactoryDependencies objects, providing entities
@@ -226,10 +229,6 @@ PeerConnectionFactoryDependencies CreatePCFDependencies(
pcf_deps.network_controller_factory =
std::move(pcf_dependencies->network_controller_factory);
}
- if (pcf_dependencies->media_transport_factory != nullptr) {
- pcf_deps.media_transport_factory =
- std::move(pcf_dependencies->media_transport_factory);
- }
if (pcf_dependencies->neteq_factory != nullptr) {
pcf_deps.neteq_factory = std::move(pcf_dependencies->neteq_factory);
}
@@ -309,10 +308,11 @@ std::unique_ptr<TestPeer> TestPeerFactory::CreateTestPeer(
params->audio_config, remote_audio_config, echo_emulation_config,
components->pcf_dependencies->task_queue_factory.get());
WrapVideoEncoderFactory(
- bitrate_multiplier,
+ params->name.value(), bitrate_multiplier,
CalculateRequiredSpatialIndexPerStream(params->video_configs),
components->pcf_dependencies.get(), video_analyzer_helper);
- WrapVideoDecoderFactory(components->pcf_dependencies.get(),
+ WrapVideoDecoderFactory(params->name.value(),
+ components->pcf_dependencies.get(),
video_analyzer_helper);
std::unique_ptr<cricket::MediaEngineInterface> media_engine =
CreateMediaEngine(components->pcf_dependencies.get(), audio_device_module,
@@ -329,7 +329,7 @@ std::unique_ptr<TestPeer> TestPeerFactory::CreateTestPeer(
rtc::scoped_refptr<PeerConnectionInterface> peer_connection =
peer_connection_factory->CreatePeerConnection(params->rtc_configuration,
std::move(pc_deps));
- peer_connection->SetBitrate(params->bitrate_params);
+ peer_connection->SetBitrate(params->bitrate_settings);
return absl::WrapUnique(new TestPeer(
peer_connection_factory, peer_connection, std::move(observer),
diff --git a/chromium/third_party/webrtc/test/peer_scenario/BUILD.gn b/chromium/third_party/webrtc/test/peer_scenario/BUILD.gn
index d702cf539f2..bdc77b70c8d 100644
--- a/chromium/third_party/webrtc/test/peer_scenario/BUILD.gn
+++ b/chromium/third_party/webrtc/test/peer_scenario/BUILD.gn
@@ -52,6 +52,8 @@ if (rtc_include_tests) {
"../network:emulated_network",
"../scenario",
"../time_controller",
+ ]
+ absl_deps = [
"//third_party/abseil-cpp/absl/flags:flag",
"//third_party/abseil-cpp/absl/memory",
]
diff --git a/chromium/third_party/webrtc/test/run_loop_unittest.cc b/chromium/third_party/webrtc/test/run_loop_unittest.cc
index a356cc265a5..160aba0716a 100644
--- a/chromium/third_party/webrtc/test/run_loop_unittest.cc
+++ b/chromium/third_party/webrtc/test/run_loop_unittest.cc
@@ -17,7 +17,6 @@
namespace webrtc {
TEST(RunLoopTest, TaskQueueOnThread) {
- EXPECT_EQ(TaskQueueBase::Current(), nullptr);
test::RunLoop loop;
EXPECT_EQ(TaskQueueBase::Current(), loop.task_queue());
EXPECT_TRUE(loop.task_queue()->IsCurrent());
diff --git a/chromium/third_party/webrtc/test/scenario/BUILD.gn b/chromium/third_party/webrtc/test/scenario/BUILD.gn
index e2e5f8cef22..33c68a8211d 100644
--- a/chromium/third_party/webrtc/test/scenario/BUILD.gn
+++ b/chromium/third_party/webrtc/test/scenario/BUILD.gn
@@ -141,6 +141,8 @@ if (rtc_include_tests) {
"../logging:log_writer",
"../network:emulated_network",
"../time_controller",
+ ]
+ absl_deps = [
"//third_party/abseil-cpp/absl/flags:flag",
"//third_party/abseil-cpp/absl/flags:parse",
"//third_party/abseil-cpp/absl/memory",
diff --git a/chromium/third_party/webrtc/test/scenario/call_client.cc b/chromium/third_party/webrtc/test/scenario/call_client.cc
index fb888df6946..0107497252d 100644
--- a/chromium/third_party/webrtc/test/scenario/call_client.cc
+++ b/chromium/third_party/webrtc/test/scenario/call_client.cc
@@ -54,7 +54,8 @@ Call* CreateCall(TimeController* time_controller,
RtcEventLog* event_log,
CallClientConfig config,
LoggingNetworkControllerFactory* network_controller_factory,
- rtc::scoped_refptr<AudioState> audio_state) {
+ rtc::scoped_refptr<AudioState> audio_state,
+ rtc::scoped_refptr<SharedModuleThread> call_thread) {
CallConfig call_config(event_log);
call_config.bitrate_config.max_bitrate_bps =
config.transport.rates.max_rate.bps_or(-1);
@@ -67,7 +68,7 @@ Call* CreateCall(TimeController* time_controller,
call_config.audio_state = audio_state;
call_config.trials = config.field_trials;
return Call::Create(call_config, time_controller->GetClock(),
- time_controller->CreateProcessThread("CallModules"),
+ std::move(call_thread),
time_controller->CreateProcessThread("Pacer"));
}
@@ -213,9 +214,14 @@ CallClient::CallClient(
event_log_ = CreateEventLog(time_controller_->GetTaskQueueFactory(),
log_writer_factory_.get());
fake_audio_setup_ = InitAudio(time_controller_);
+ RTC_DCHECK(!module_thread_);
+ module_thread_ = SharedModuleThread::Create(
+ time_controller_->CreateProcessThread("CallThread"),
+ [this]() { module_thread_ = nullptr; });
+
call_.reset(CreateCall(time_controller_, event_log_.get(), config,
&network_controller_factory_,
- fake_audio_setup_.audio_state));
+ fake_audio_setup_.audio_state, module_thread_));
transport_ = std::make_unique<NetworkNodeTransport>(clock_, call_.get());
});
}
@@ -223,6 +229,7 @@ CallClient::CallClient(
CallClient::~CallClient() {
SendTask([&] {
call_.reset();
+ RTC_DCHECK(!module_thread_); // Should be set to null in the lambda above.
fake_audio_setup_ = {};
rtc::Event done;
event_log_->StopLogging([&done] { done.Set(); });
diff --git a/chromium/third_party/webrtc/test/scenario/call_client.h b/chromium/third_party/webrtc/test/scenario/call_client.h
index 33fa2765cb5..80814eb1b3b 100644
--- a/chromium/third_party/webrtc/test/scenario/call_client.h
+++ b/chromium/third_party/webrtc/test/scenario/call_client.h
@@ -157,6 +157,8 @@ class CallClient : public EmulatedNetworkReceiverInterface {
// Defined last so it's destroyed first.
TaskQueueForTest task_queue_;
+ rtc::scoped_refptr<SharedModuleThread> module_thread_;
+
const FieldTrialBasedConfig field_trials_;
};
diff --git a/chromium/third_party/webrtc/test/scenario/scenario_unittest.cc b/chromium/third_party/webrtc/test/scenario/scenario_unittest.cc
index 839e6a375e5..f74c1a5bdf3 100644
--- a/chromium/third_party/webrtc/test/scenario/scenario_unittest.cc
+++ b/chromium/third_party/webrtc/test/scenario/scenario_unittest.cc
@@ -119,7 +119,8 @@ TEST(ScenarioTest, MAYBE_RealTimeEncoding) {
}
// Regression tests based on previous runs.
EXPECT_LT(analyzer.stats().lost_count, 2);
- EXPECT_NEAR(analyzer.stats().psnr_with_freeze.Mean(), 38, 10);
+ // This far below expected but ensures that we get something.
+ EXPECT_GT(analyzer.stats().psnr_with_freeze.Mean(), 10);
}
TEST(ScenarioTest, SimTimeFakeing) {
diff --git a/chromium/third_party/webrtc/test/test_main.cc b/chromium/third_party/webrtc/test/test_main.cc
index 8555d5e6dae..50469795486 100644
--- a/chromium/third_party/webrtc/test/test_main.cc
+++ b/chromium/third_party/webrtc/test/test_main.cc
@@ -16,11 +16,10 @@
int main(int argc, char* argv[]) {
// Initialize the symbolizer to get a human-readable stack trace
- // TODO(crbug.com/1050976): Breaks iossim tests, re-enable when fixed.
- // absl::InitializeSymbolizer(argv[0]);
+ absl::InitializeSymbolizer(argv[0]);
- // absl::FailureSignalHandlerOptions options;
- // absl::InstallFailureSignalHandler(options);
+ absl::FailureSignalHandlerOptions options;
+ absl::InstallFailureSignalHandler(options);
std::unique_ptr<webrtc::TestMain> main = webrtc::TestMain::Create();
int err_code = main->Init(&argc, argv);
diff --git a/chromium/third_party/webrtc/test/test_main_lib.cc b/chromium/third_party/webrtc/test/test_main_lib.cc
index 15318b49e15..f5e02341f3f 100644
--- a/chromium/third_party/webrtc/test/test_main_lib.cc
+++ b/chromium/third_party/webrtc/test/test_main_lib.cc
@@ -17,6 +17,7 @@
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/memory/memory.h"
+#include "absl/strings/match.h"
#include "absl/types/optional.h"
#include "rtc_base/checks.h"
#include "rtc_base/event_tracer.h"
@@ -100,6 +101,62 @@ namespace {
class TestMainImpl : public TestMain {
public:
+ // In order to set up a fresh rtc::Thread state for each test and avoid
+ // accidentally carrying over pending tasks that might be sent from one test
+ // and executed while another test is running, we inject a TestListener
+ // that sets up a new rtc::Thread instance for the main thread, per test.
+ class TestListener : public ::testing::EmptyTestEventListener {
+ public:
+ TestListener() = default;
+
+ private:
+ bool IsDeathTest(const char* test_case_name, const char* test_name) {
+ // Workaround to avoid wrapping the main thread when we run death tests.
+ // The approach we take for detecting death tests is essentially the same
+ // as gtest does internally. Gtest does this:
+ //
+ // static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+ // ::testing::internal::UnitTestOptions::MatchesFilter(
+ // test_case_name, kDeathTestCaseFilter);
+ //
+ // Our approach is a little more straight forward.
+ if (absl::EndsWith(test_case_name, "DeathTest"))
+ return true;
+
+ return absl::EndsWith(test_name, "DeathTest");
+ }
+
+ void OnTestStart(const ::testing::TestInfo& test_info) override {
+ if (!IsDeathTest(test_info.test_suite_name(), test_info.name())) {
+ // Ensure that main thread gets wrapped as an rtc::Thread.
+ // TODO(bugs.webrtc.org/9714): It might be better to avoid wrapping the
+ // main thread, or leave it to individual tests that need it. But as
+ // long as we have automatic thread wrapping, we need this to avoid that
+ // some other random thread (which one depending on which tests are run)
+ // gets automatically wrapped.
+ thread_ = rtc::Thread::CreateWithSocketServer();
+ thread_->WrapCurrent();
+ RTC_DCHECK_EQ(rtc::Thread::Current(), thread_.get());
+ } else {
+ RTC_LOG(LS_INFO) << "No thread auto wrap for death test.";
+ }
+ }
+
+ void OnTestEnd(const ::testing::TestInfo& test_info) override {
+ // Terminate the message loop. Note that if the test failed to clean
+ // up pending messages, this may execute part of the test. Ideally we
+ // should print a warning message here, or even fail the test if it leaks.
+ if (thread_) {
+ thread_->Quit(); // Signal quit.
+ thread_->Run(); // Flush + process Quit signal.
+ thread_->UnwrapCurrent();
+ thread_ = nullptr;
+ }
+ }
+
+ std::unique_ptr<rtc::Thread> thread_;
+ };
+
int Init(int* argc, char* argv[]) override {
::testing::InitGoogleMock(argc, argv);
absl::ParseCommandLine(*argc, argv);
@@ -134,14 +191,7 @@ class TestMainImpl : public TestMain {
rtc::InitializeSSL();
rtc::SSLStreamAdapter::EnableTimeCallbackForTesting();
- // Ensure that main thread gets wrapped as an rtc::Thread.
- // TODO(bugs.webrt.org/9714): It might be better to avoid wrapping the main
- // thread, or leave it to individual tests that need it. But as long as we
- // have automatic thread wrapping, we need this to avoid that some other
- // random thread (which one depending on which tests are run) gets
- // automatically wrapped.
- rtc::ThreadManager::Instance()->WrapCurrentThread();
- RTC_CHECK(rtc::Thread::Current());
+ ::testing::UnitTest::GetInstance()->listeners().Append(new TestListener());
return 0;
}
diff --git a/chromium/third_party/webrtc/test/testsupport/mock/mock_frame_reader.h b/chromium/third_party/webrtc/test/testsupport/mock/mock_frame_reader.h
index 8da3695d23b..bda6b1ad2dc 100644
--- a/chromium/third_party/webrtc/test/testsupport/mock/mock_frame_reader.h
+++ b/chromium/third_party/webrtc/test/testsupport/mock/mock_frame_reader.h
@@ -19,11 +19,11 @@ namespace test {
class MockFrameReader : public FrameReader {
public:
- MOCK_METHOD0(Init, bool());
- MOCK_METHOD0(ReadFrame, rtc::scoped_refptr<I420Buffer>());
- MOCK_METHOD0(Close, void());
- MOCK_METHOD0(FrameLength, size_t());
- MOCK_METHOD0(NumberOfFrames, int());
+ MOCK_METHOD(bool, Init, (), (override));
+ MOCK_METHOD(rtc::scoped_refptr<I420Buffer>, ReadFrame, (), (override));
+ MOCK_METHOD(void, Close, (), (override));
+ MOCK_METHOD(size_t, FrameLength, (), (override));
+ MOCK_METHOD(int, NumberOfFrames, (), (override));
};
} // namespace test
diff --git a/chromium/third_party/webrtc/test/testsupport/perf_test.h b/chromium/third_party/webrtc/test/testsupport/perf_test.h
index b0a5607d20a..4bb6773336c 100644
--- a/chromium/third_party/webrtc/test/testsupport/perf_test.h
+++ b/chromium/third_party/webrtc/test/testsupport/perf_test.h
@@ -15,7 +15,6 @@
#include <string>
#include <vector>
-#include "absl/flags/flag.h"
#include "api/array_view.h"
#include "rtc_base/numerics/samples_stats_counter.h"
diff --git a/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.cc b/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.cc
index a6ab3b537be..87a449a401d 100644
--- a/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.cc
+++ b/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.cc
@@ -10,6 +10,8 @@
#include "test/testsupport/resources_dir_flag.h"
+#include "absl/flags/flag.h"
+
ABSL_FLAG(std::string,
resources_dir,
"",
diff --git a/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.h b/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.h
index 055cc825467..7d6f192d9bd 100644
--- a/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.h
+++ b/chromium/third_party/webrtc/test/testsupport/resources_dir_flag.h
@@ -13,7 +13,7 @@
#ifndef TEST_TESTSUPPORT_RESOURCES_DIR_FLAG_H__
#define TEST_TESTSUPPORT_RESOURCES_DIR_FLAG_H__
-#include "absl/flags/flag.h"
+#include "absl/flags/declare.h"
ABSL_DECLARE_FLAG(std::string, resources_dir);
diff --git a/chromium/third_party/webrtc/test/testsupport/test_artifacts_unittest.cc b/chromium/third_party/webrtc/test/testsupport/test_artifacts_unittest.cc
index 98de9e4bb83..fb577610fbb 100644
--- a/chromium/third_party/webrtc/test/testsupport/test_artifacts_unittest.cc
+++ b/chromium/third_party/webrtc/test/testsupport/test_artifacts_unittest.cc
@@ -14,6 +14,7 @@
#include <string>
+#include "absl/flags/declare.h"
#include "absl/flags/flag.h"
#include "rtc_base/system/file_wrapper.h"
#include "test/gtest.h"
diff --git a/chromium/third_party/webrtc/test/time_controller/BUILD.gn b/chromium/third_party/webrtc/test/time_controller/BUILD.gn
index 7f77f0afec7..c3d5dc9031b 100644
--- a/chromium/third_party/webrtc/test/time_controller/BUILD.gn
+++ b/chromium/third_party/webrtc/test/time_controller/BUILD.gn
@@ -41,8 +41,8 @@ rtc_library("time_controller") {
"../../rtc_base/synchronization:yield_policy",
"../../rtc_base/task_utils:to_queued_task",
"../../system_wrappers",
- "//third_party/abseil-cpp/absl/strings",
]
+ absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
}
if (rtc_include_tests) {
diff --git a/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.cc b/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.cc
index a81083b4fb9..769be3ff782 100644
--- a/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.cc
+++ b/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.cc
@@ -57,7 +57,6 @@ SimulatedTimeControllerImpl::CreateTaskQueue(
std::unique_ptr<ProcessThread> SimulatedTimeControllerImpl::CreateProcessThread(
const char* thread_name) {
- rtc::CritScope lock(&lock_);
auto process_thread =
std::make_unique<SimulatedProcessThread>(this, thread_name);
Register(process_thread.get());
@@ -117,10 +116,12 @@ void SimulatedTimeControllerImpl::RunReadyRunners() {
while (!ready_runners_.empty()) {
auto* runner = ready_runners_.front();
ready_runners_.pop_front();
+ lock_.Leave();
// Note that the RunReady function might indirectly cause a call to
- // Unregister() which will recursively grab |lock_| again to remove items
- // from |ready_runners_|.
+ // Unregister() which will grab |lock_| again to remove items from
+ // |ready_runners_|.
runner->RunReady(current_time);
+ lock_.Enter();
}
}
}
@@ -169,6 +170,7 @@ void SimulatedTimeControllerImpl::StartYield(TaskQueueBase* yielding_from) {
void SimulatedTimeControllerImpl::StopYield(TaskQueueBase* yielding_from) {
yielded_.erase(yielding_from);
}
+
} // namespace sim_time_impl
GlobalSimulatedTimeController::GlobalSimulatedTimeController(
diff --git a/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.h b/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.h
index 758f90989e8..48112b3a318 100644
--- a/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.h
+++ b/chromium/third_party/webrtc/test/time_controller/simulated_time_controller.h
@@ -52,32 +52,34 @@ class SimulatedTimeControllerImpl : public TaskQueueFactory,
std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
absl::string_view name,
- Priority priority) const override;
+ Priority priority) const RTC_LOCKS_EXCLUDED(time_lock_) override;
// Implements the YieldInterface by running ready tasks on all task queues,
// except that if this method is called from a task, the task queue running
// that task is skipped.
- void YieldExecution() override;
+ void YieldExecution() RTC_LOCKS_EXCLUDED(time_lock_, lock_) override;
// Create process thread with the name |thread_name|.
- std::unique_ptr<ProcessThread> CreateProcessThread(const char* thread_name);
+ std::unique_ptr<ProcessThread> CreateProcessThread(const char* thread_name)
+ RTC_LOCKS_EXCLUDED(time_lock_, lock_);
// Create thread using provided |socket_server|.
std::unique_ptr<rtc::Thread> CreateThread(
const std::string& name,
- std::unique_ptr<rtc::SocketServer> socket_server);
+ std::unique_ptr<rtc::SocketServer> socket_server)
+ RTC_LOCKS_EXCLUDED(time_lock_, lock_);
// Runs all runners in |runners_| that has tasks or modules ready for
// execution.
- void RunReadyRunners();
+ void RunReadyRunners() RTC_LOCKS_EXCLUDED(time_lock_, lock_);
// Return |current_time_|.
- Timestamp CurrentTime() const;
+ Timestamp CurrentTime() const RTC_LOCKS_EXCLUDED(time_lock_);
// Return min of runner->GetNextRunTime() for runner in |runners_|.
- Timestamp NextRunTime() const;
+ Timestamp NextRunTime() const RTC_LOCKS_EXCLUDED(lock_);
// Set |current_time_| to |target_time|.
- void AdvanceTime(Timestamp target_time);
+ void AdvanceTime(Timestamp target_time) RTC_LOCKS_EXCLUDED(time_lock_);
// Adds |runner| to |runners_|.
- void Register(SimulatedSequenceRunner* runner);
+ void Register(SimulatedSequenceRunner* runner) RTC_LOCKS_EXCLUDED(lock_);
// Removes |runner| from |runners_|.
- void Unregister(SimulatedSequenceRunner* runner);
+ void Unregister(SimulatedSequenceRunner* runner) RTC_LOCKS_EXCLUDED(lock_);
// Indicates that |yielding_from| is not ready to run.
void StartYield(TaskQueueBase* yielding_from);