SVC: Add end to end tests for VP8 and VP9

The tests check that the various scalability mode are supported
and the frames are marked properly by the encoder with their
spatial and temporal index.
The same information is then checked on the receiving side.

A new member is added on EncodedImage to store the temporal index,
and is filled by the encoders and retreived by the ref finder
objects on the decoding side.

Bug: webrtc:11607
Change-Id: I7522f6a6fc5402244cab0c4c64b544ce09bc5204
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260189
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37303}
This commit is contained in:
Florent Castelli 2022-04-25 17:28:00 +02:00 committed by WebRTC LUCI CQ
parent d151cc6fa3
commit 90b74389a2
17 changed files with 1666 additions and 5 deletions

View File

@ -67,6 +67,7 @@ if (!build_with_chromium) {
"pc:peerconnection_unittests",
"pc:rtc_pc_unittests",
"pc:slow_peer_connection_unittests",
"pc:svc_tests",
"rtc_tools:rtp_generator",
"rtc_tools:video_replay",
"stats:rtc_stats_unittests",

View File

@ -97,6 +97,13 @@ class RTC_EXPORT EncodedImage {
spatial_index_ = spatial_index;
}
absl::optional<int> TemporalIndex() const { return temporal_index_; }
void SetTemporalIndex(absl::optional<int> temporal_index) {
RTC_DCHECK_GE(temporal_index_.value_or(0), 0);
RTC_DCHECK_LT(temporal_index_.value_or(0), kMaxTemporalStreams);
temporal_index_ = temporal_index;
}
// These methods can be used to set/get size of subframe with spatial index
// `spatial_index` on encoded frames that consist of multiple spatial layers.
absl::optional<size_t> SpatialLayerFrameSize(int spatial_index) const;
@ -199,6 +206,7 @@ class RTC_EXPORT EncodedImage {
size_t size_ = 0; // Size of encoded frame data.
uint32_t timestamp_rtp_ = 0;
absl::optional<int> spatial_index_;
absl::optional<int> temporal_index_;
std::map<int, size_t> spatial_layer_frame_size_bytes_;
absl::optional<webrtc::ColorSpace> color_space_;
// This field is meant for media quality testing purpose only. When enabled it

View File

@ -427,6 +427,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -1058,6 +1088,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -1727,6 +1787,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -2358,6 +2448,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -2873,6 +2993,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -3284,6 +3425,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -3695,6 +3857,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -4106,6 +4289,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -4517,6 +4721,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -4928,6 +5153,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -5340,6 +5586,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -5753,6 +6020,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -6165,6 +6453,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -6613,6 +6922,28 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cores": "12",
"cpu": "x86-64",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -7044,6 +7375,28 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cores": "12",
"cpu": "x86-64",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -7461,6 +7814,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -7894,6 +8268,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "arm64-64-Apple_M1",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -8334,6 +8729,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-7-SP1"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -8767,6 +9183,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-10-15063"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -9493,6 +9930,51 @@
},
"test_id_prefix": "ninja://sdk:sdk_unittests/"
},
{
"args": [
"--platform",
"iPhone X",
"--version",
"12.4",
"--xcode-build-version",
"13c100",
"--out-dir",
"${ISOLATED_OUTDIR}"
],
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/mac_toolchain/${platform}",
"location": ".",
"revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1"
}
],
"dimension_sets": [
{
"os": "Mac-11|Mac-12"
}
],
"named_caches": [
{
"name": "xcode_ios_13c100",
"path": "Xcode.app"
}
],
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"args": [
"--platform",
@ -10404,6 +10886,51 @@
},
"test_id_prefix": "ninja://sdk:sdk_unittests/"
},
{
"args": [
"--platform",
"iPhone X",
"--version",
"13.6",
"--xcode-build-version",
"13c100",
"--out-dir",
"${ISOLATED_OUTDIR}"
],
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/mac_toolchain/${platform}",
"location": ".",
"revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1"
}
],
"dimension_sets": [
{
"os": "Mac-11|Mac-12"
}
],
"named_caches": [
{
"name": "xcode_ios_13c100",
"path": "Xcode.app"
}
],
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"args": [
"--platform",
@ -11315,6 +11842,51 @@
},
"test_id_prefix": "ninja://sdk:sdk_unittests/"
},
{
"args": [
"--platform",
"iPhone X",
"--version",
"14.5",
"--xcode-build-version",
"13c100",
"--out-dir",
"${ISOLATED_OUTDIR}"
],
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/mac_toolchain/${platform}",
"location": ".",
"revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1"
}
],
"dimension_sets": [
{
"os": "Mac-11|Mac-12"
}
],
"named_caches": [
{
"name": "xcode_ios_13c100",
"path": "Xcode.app"
}
],
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"args": [
"--platform",

View File

@ -108,6 +108,10 @@
"label": "//pc:slow_peer_connection_unittests",
"type": "console_test_launcher",
},
"svc_tests": {
"label": "//pc:svc_tests",
"type": "console_test_launcher",
},
"system_wrappers_unittests": {
"label": "//system_wrappers:system_wrappers_unittests",
"type": "console_test_launcher",

View File

@ -50,6 +50,7 @@
'mixins': ['shards-6'],
},
'slow_peer_connection_unittests': {},
'svc_tests': {},
'system_wrappers_unittests': {},
'test_support_unittests': {},
'tools_unittests': {},
@ -101,6 +102,7 @@
'mixins': ['shards-6'],
},
'slow_peer_connection_unittests': {},
'svc_tests': {},
'system_wrappers_unittests': {},
'test_support_unittests': {},
'tools_unittests': {},
@ -164,6 +166,7 @@
'sdk_unittests': {
'mixins': ['xcode_parallelization']
},
'svc_tests': {},
'system_wrappers_unittests': {},
'test_support_unittests': {},
'tools_unittests': {},

View File

@ -427,6 +427,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -1092,6 +1122,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -1757,6 +1817,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -2457,6 +2547,36 @@
"test": "slow_peer_connection_unittests",
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_gtest_merge.py"
},
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/luci/logdog/butler/${platform}",
"location": "bin",
"revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
}
],
"dimension_sets": [
{
"android_devices": "1",
"device_os": "MMB29Q",
"device_type": "bullhead",
"os": "Android"
}
]
},
"test": "svc_tests",
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"merge": {
"args": [],
@ -3299,6 +3419,51 @@
},
"test_id_prefix": "ninja://sdk:sdk_unittests/"
},
{
"args": [
"--platform",
"iPhone X",
"--version",
"12.4",
"--xcode-build-version",
"13c100",
"--out-dir",
"${ISOLATED_OUTDIR}"
],
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/mac_toolchain/${platform}",
"location": ".",
"revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1"
}
],
"dimension_sets": [
{
"os": "Mac-11|Mac-12"
}
],
"named_caches": [
{
"name": "xcode_ios_13c100",
"path": "Xcode.app"
}
],
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"args": [
"--platform",
@ -4210,6 +4375,51 @@
},
"test_id_prefix": "ninja://sdk:sdk_unittests/"
},
{
"args": [
"--platform",
"iPhone X",
"--version",
"13.6",
"--xcode-build-version",
"13c100",
"--out-dir",
"${ISOLATED_OUTDIR}"
],
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/mac_toolchain/${platform}",
"location": ".",
"revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1"
}
],
"dimension_sets": [
{
"os": "Mac-11|Mac-12"
}
],
"named_caches": [
{
"name": "xcode_ios_13c100",
"path": "Xcode.app"
}
],
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"args": [
"--platform",
@ -5121,6 +5331,51 @@
},
"test_id_prefix": "ninja://sdk:sdk_unittests/"
},
{
"args": [
"--platform",
"iPhone X",
"--version",
"14.5",
"--xcode-build-version",
"13c100",
"--out-dir",
"${ISOLATED_OUTDIR}"
],
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"enable": true,
"has_native_resultdb_integration": true
},
"swarming": {
"can_use_on_swarming_builders": true,
"cipd_packages": [
{
"cipd_package": "infra/tools/mac_toolchain/${platform}",
"location": ".",
"revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1"
}
],
"dimension_sets": [
{
"os": "Mac-11|Mac-12"
}
],
"named_caches": [
{
"name": "xcode_ios_13c100",
"path": "Xcode.app"
}
],
"service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"args": [
"--platform",
@ -5721,6 +5976,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -6138,6 +6414,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -6550,6 +6847,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -6987,6 +7305,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -7398,6 +7737,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -7858,6 +8218,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -8269,6 +8650,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -8680,6 +9082,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -9091,6 +9514,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -9502,6 +9946,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Ubuntu-18.04"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -9926,6 +10391,28 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cores": "12",
"cpu": "x86-64",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -10358,6 +10845,28 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cores": "12",
"cpu": "x86-64",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -10775,6 +11284,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "arm64-64-Apple_M1",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -11186,6 +11716,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -11646,6 +12197,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "arm64-64-Apple_M1",
"os": "Mac-11|Mac-12"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -12057,6 +12629,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-10-15063"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -12472,6 +13065,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-7-SP1"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -12883,6 +13497,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-10-15063"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -13294,6 +13929,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-7-SP1"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -13705,6 +14361,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-7-SP1"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {
@ -14116,6 +14793,27 @@
},
"test_id_prefix": "ninja://pc:slow_peer_connection_unittests/"
},
{
"isolate_name": "svc_tests",
"merge": {
"args": [],
"script": "//testing/merge_scripts/standard_isolated_script_merge.py"
},
"name": "svc_tests",
"resultdb": {
"result_format": "json"
},
"swarming": {
"can_use_on_swarming_builders": true,
"dimension_sets": [
{
"cpu": "x86-64",
"os": "Windows-7-SP1"
}
]
},
"test_id_prefix": "ninja://pc:svc_tests/"
},
{
"isolate_name": "system_wrappers_unittests",
"merge": {

View File

@ -49,8 +49,8 @@ namespace {
// Encoder configuration parameters
constexpr int kQpMin = 10;
constexpr int kUsageProfile = AOM_USAGE_REALTIME;
constexpr int kMinQindex = 145; // Min qindex threshold for QP scaling.
constexpr int kMaxQindex = 205; // Max qindex threshold for QP scaling.
constexpr int kMinQindex = 145; // Min qindex threshold for QP scaling.
constexpr int kMaxQindex = 205; // Max qindex threshold for QP scaling.
constexpr int kBitDepth = 8;
constexpr int kLagInFrames = 0; // No look ahead.
constexpr int kRtpTicksPerSecond = 90000;
@ -684,6 +684,7 @@ int32_t LibaomAv1Encoder::Encode(
encoded_image._encodedWidth = cfg_.g_w * n / d;
encoded_image._encodedHeight = cfg_.g_h * n / d;
encoded_image.SetSpatialIndex(layer_frame->SpatialId());
encoded_image.SetTemporalIndex(layer_frame->TemporalId());
} else {
encoded_image._encodedWidth = cfg_.g_w;
encoded_image._encodedHeight = cfg_.g_h;

View File

@ -1156,6 +1156,10 @@ int LibvpxVp8Encoder::GetEncodedPartitions(const VideoFrame& input_image,
encoded_images_[encoder_idx].SetSpatialIndex(stream_idx);
PopulateCodecSpecific(&codec_specific, *pkt, stream_idx, encoder_idx,
input_image.timestamp());
if (codec_specific.codecSpecific.VP8.temporalIdx != kNoTemporalIdx) {
encoded_images_[encoder_idx].SetTemporalIndex(
codec_specific.codecSpecific.VP8.temporalIdx);
}
break;
}
}

View File

@ -1260,6 +1260,7 @@ int LibvpxVp9Encoder::Encode(const VideoFrame& input_image,
bool LibvpxVp9Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
absl::optional<int>* spatial_idx,
absl::optional<int>* temporal_idx,
const vpx_codec_cx_pkt& pkt) {
RTC_CHECK(codec_specific != nullptr);
codec_specific->codecType = kVideoCodecVP9;
@ -1285,8 +1286,10 @@ bool LibvpxVp9Encoder::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
if (num_temporal_layers_ == 1) {
RTC_CHECK_EQ(layer_id.temporal_layer_id, 0);
vp9_info->temporal_idx = kNoTemporalIdx;
*temporal_idx = absl::nullopt;
} else {
vp9_info->temporal_idx = layer_id.temporal_layer_id;
*temporal_idx = layer_id.temporal_layer_id;
}
if (num_active_spatial_layers_ == 1) {
RTC_CHECK_EQ(layer_id.spatial_layer_id, 0);
@ -1702,12 +1705,15 @@ void LibvpxVp9Encoder::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
codec_specific_ = {};
absl::optional<int> spatial_index;
if (!PopulateCodecSpecific(&codec_specific_, &spatial_index, *pkt)) {
absl::optional<int> temporal_index;
if (!PopulateCodecSpecific(&codec_specific_, &spatial_index, &temporal_index,
*pkt)) {
// Drop the frame.
encoded_image_.set_size(0);
return;
}
encoded_image_.SetSpatialIndex(spatial_index);
encoded_image_.SetTemporalIndex(temporal_index);
const bool is_key_frame =
((pkt->data.frame.flags & VPX_FRAME_IS_KEY) ? true : false) &&

View File

@ -67,6 +67,7 @@ class LibvpxVp9Encoder : public VP9Encoder {
bool PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
absl::optional<int>* spatial_idx,
absl::optional<int>* temporal_idx,
const vpx_codec_cx_pkt& pkt);
void FillReferenceIndices(const vpx_codec_cx_pkt& pkt,
size_t pic_num,

View File

@ -23,6 +23,8 @@ RtpFrameReferenceFinder::ReturnVector RtpGenericFrameRefFinder::ManageFrame(
// them here.
frame->SetId(descriptor.frame_id);
frame->SetSpatialIndex(descriptor.spatial_index);
if (descriptor.temporal_index != kNoTemporalIdx)
frame->SetTemporalIndex(descriptor.temporal_index);
RtpFrameReferenceFinder::ReturnVector res;
if (EncodedFrame::kMaxFrameReferences < descriptor.dependencies.size()) {

View File

@ -20,6 +20,10 @@ RtpFrameReferenceFinder::ReturnVector RtpVp8RefFinder::ManageFrame(
std::unique_ptr<RtpFrameObject> frame) {
const RTPVideoHeaderVP8& codec_header = absl::get<RTPVideoHeaderVP8>(
frame->GetRtpVideoHeader().video_type_header);
if (codec_header.temporalIdx != kNoTemporalIdx)
frame->SetTemporalIndex(codec_header.temporalIdx);
int64_t unwrapped_tl0 = tl0_unwrapper_.Unwrap(codec_header.tl0PicIdx & 0xFF);
FrameDecision decision =
ManageFrameInternal(frame.get(), codec_header, unwrapped_tl0);

View File

@ -21,6 +21,8 @@ RtpFrameReferenceFinder::ReturnVector RtpVp9RefFinder::ManageFrame(
const RTPVideoHeaderVP9& codec_header = absl::get<RTPVideoHeaderVP9>(
frame->GetRtpVideoHeader().video_type_header);
if (codec_header.temporal_idx != kNoTemporalIdx)
frame->SetTemporalIndex(codec_header.temporal_idx);
frame->SetSpatialIndex(codec_header.spatial_idx);
frame->SetId(codec_header.picture_id & (kFrameIdLength - 1));

View File

@ -2719,4 +2719,50 @@ if (rtc_include_tests && !build_with_chromium) {
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
svc_tests_resources = [
"../resources/difficult_photo_1850_1110.yuv",
"../resources/photo_1850_1110.yuv",
"../resources/presentation_1850_1110.yuv",
"../resources/web_screenshot_1850_1110.yuv",
]
if (is_ios) {
bundle_data("svc_tests_bundle_data") {
testonly = true
sources = svc_tests_resources
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
}
}
rtc_test("svc_tests") {
sources = [ "test/svc_e2e_tests.cc" ]
data = svc_tests_resources
deps = [
"../api:create_network_emulation_manager",
"../api:create_peer_connection_quality_test_frame_generator",
"../api:create_peerconnection_quality_test_fixture",
"../api:frame_generator_api",
"../api:media_stream_interface",
"../api:network_emulation_manager_api",
"../api:peer_connection_quality_test_fixture_api",
"../api:simulated_network_api",
"../api:time_controller",
"../api/video_codecs:video_codecs_api",
"../call:simulated_network",
"../modules/video_coding:webrtc_vp9",
"../rtc_base/containers:flat_map",
"../system_wrappers:field_trial",
"../test:field_trial",
"../test:fileutils",
"../test:test_main",
"../test:test_support",
"../test/pc/e2e:default_video_quality_analyzer",
"../test/pc/e2e:network_quality_metrics_reporter",
]
if (is_ios) {
deps += [ ":svc_tests_bundle_data" ]
}
}
}

302
pc/test/svc_e2e_tests.cc Normal file
View File

@ -0,0 +1,302 @@
/*
* Copyright (c) 2022 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 <memory>
#include <string>
#include <utility>
#include <vector>
#include "api/media_stream_interface.h"
#include "api/test/create_network_emulation_manager.h"
#include "api/test/create_peer_connection_quality_test_frame_generator.h"
#include "api/test/create_peerconnection_quality_test_fixture.h"
#include "api/test/frame_generator_interface.h"
#include "api/test/network_emulation_manager.h"
#include "api/test/peerconnection_quality_test_fixture.h"
#include "api/test/simulated_network.h"
#include "api/test/time_controller.h"
#include "api/video_codecs/vp9_profile.h"
#include "call/simulated_network.h"
#include "modules/video_coding/codecs/vp9/include/vp9.h"
#include "rtc_base/containers/flat_map.h"
#include "system_wrappers/include/field_trial.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer.h"
#include "test/pc/e2e/network_quality_metrics_reporter.h"
#include "test/testsupport/file_utils.h"
namespace webrtc {
namespace {
using PeerConfigurer = ::webrtc::webrtc_pc_e2e::
PeerConnectionE2EQualityTestFixture::PeerConfigurer;
using RunParams =
::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::RunParams;
using VideoConfig =
::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig;
using ScreenShareConfig = ::webrtc::webrtc_pc_e2e::
PeerConnectionE2EQualityTestFixture::ScreenShareConfig;
using VideoCodecConfig = ::webrtc::webrtc_pc_e2e::
PeerConnectionE2EQualityTestFixture::VideoCodecConfig;
using ::testing::UnitTest;
using ::testing::Values;
EmulatedNetworkNode* CreateEmulatedNodeWithConfig(
NetworkEmulationManager* emulation,
const BuiltInNetworkBehaviorConfig& config) {
return emulation->CreateEmulatedNode(config);
}
std::pair<EmulatedNetworkManagerInterface*, EmulatedNetworkManagerInterface*>
CreateTwoNetworkLinks(NetworkEmulationManager* emulation,
const BuiltInNetworkBehaviorConfig& config) {
auto* alice_node = CreateEmulatedNodeWithConfig(emulation, config);
auto* bob_node = CreateEmulatedNodeWithConfig(emulation, config);
auto* alice_endpoint = emulation->CreateEndpoint(EmulatedEndpointConfig());
auto* bob_endpoint = emulation->CreateEndpoint(EmulatedEndpointConfig());
emulation->CreateRoute(alice_endpoint, {alice_node}, bob_endpoint);
emulation->CreateRoute(bob_endpoint, {bob_node}, alice_endpoint);
return {
emulation->CreateEmulatedNetworkManagerInterface({alice_endpoint}),
emulation->CreateEmulatedNetworkManagerInterface({bob_endpoint}),
};
}
std::unique_ptr<webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture>
CreateTestFixture(absl::string_view test_case_name,
TimeController& time_controller,
std::pair<EmulatedNetworkManagerInterface*,
EmulatedNetworkManagerInterface*> network_links,
rtc::FunctionView<void(PeerConfigurer*)> alice_configurer,
rtc::FunctionView<void(PeerConfigurer*)> bob_configurer,
std::unique_ptr<webrtc_pc_e2e::VideoQualityAnalyzerInterface>
video_quality_analyzer = nullptr) {
auto fixture = webrtc_pc_e2e::CreatePeerConnectionE2EQualityTestFixture(
std::string(test_case_name), time_controller, nullptr,
std::move(video_quality_analyzer));
fixture->AddPeer(network_links.first->network_dependencies(),
alice_configurer);
fixture->AddPeer(network_links.second->network_dependencies(),
bob_configurer);
return fixture;
}
// Takes the current active field trials set, and appends some new trials.
std::string AppendFieldTrials(std::string new_trial_string) {
return std::string(field_trial::GetFieldTrialString()) + new_trial_string;
}
struct SvcTestParameters {
std::string codec_name;
std::string scalability_mode;
int expected_spatial_layers;
int expected_temporal_layers;
};
class SvcTest : public testing::TestWithParam<SvcTestParameters> {
public:
SvcTest() : video_codec_config(ToVideoCodecConfig(GetParam().codec_name)) {}
static VideoCodecConfig ToVideoCodecConfig(absl::string_view codec) {
if (codec == cricket::kVp9CodecName) {
return VideoCodecConfig(
cricket::kVp9CodecName,
{{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile0)}});
}
return VideoCodecConfig(std::string(codec));
}
protected:
VideoCodecConfig video_codec_config;
};
} // namespace
// Records how many frames are seen for each spatial and temporal index at the
// encoder and decoder level.
class SvcVideoQualityAnalyzer : public DefaultVideoQualityAnalyzer {
public:
using SpatialTemporalLayerCounts =
webrtc::flat_map<int, webrtc::flat_map<int, int>>;
explicit SvcVideoQualityAnalyzer(webrtc::Clock* clock)
: DefaultVideoQualityAnalyzer(clock,
DefaultVideoQualityAnalyzerOptions{
.compute_psnr = false,
.compute_ssim = false,
}) {}
~SvcVideoQualityAnalyzer() override = default;
void OnFrameEncoded(absl::string_view peer_name,
uint16_t frame_id,
const EncodedImage& encoded_image,
const EncoderStats& stats) override {
absl::optional<int> spatial_id = encoded_image.SpatialIndex();
absl::optional<int> temporal_id = encoded_image.TemporalIndex();
encoder_layers_seen_[spatial_id.value_or(0)][temporal_id.value_or(0)]++;
DefaultVideoQualityAnalyzer::OnFrameEncoded(peer_name, frame_id,
encoded_image, stats);
}
void OnFramePreDecode(absl::string_view peer_name,
uint16_t frame_id,
const EncodedImage& input_image) override {
absl::optional<int> spatial_id = input_image.SpatialIndex();
absl::optional<int> temporal_id = input_image.TemporalIndex();
for (int i = 0; i <= spatial_id.value_or(0); ++i) {
// If there are no spatial layers (for example VP8), we still want to
// record the temporal index for pseudo-layer "0" frames.
if (i == 0 || input_image.SpatialLayerFrameSize(i).has_value()) {
decoder_layers_seen_[i][temporal_id.value_or(0)]++;
}
}
DefaultVideoQualityAnalyzer::OnFramePreDecode(peer_name, frame_id,
input_image);
}
const SpatialTemporalLayerCounts& encoder_layers_seen() const {
return encoder_layers_seen_;
}
const SpatialTemporalLayerCounts& decoder_layers_seen() const {
return decoder_layers_seen_;
}
private:
SpatialTemporalLayerCounts encoder_layers_seen_;
SpatialTemporalLayerCounts decoder_layers_seen_;
};
MATCHER_P2(HasSpatialAndTemporalLayers,
expected_spatial_layers,
expected_temporal_layers,
"") {
if (arg.size() != (size_t)expected_spatial_layers) {
*result_listener << "spatial layer count mismatch expected "
<< expected_spatial_layers << " but got " << arg.size();
return false;
}
for (const auto& spatial_layer : arg) {
if (spatial_layer.first < 0 ||
spatial_layer.first >= expected_spatial_layers) {
*result_listener << "spatial layer index is not in range [0,"
<< expected_spatial_layers << "[.";
return false;
}
if (spatial_layer.second.size() != (size_t)expected_temporal_layers) {
*result_listener << "temporal layer count mismatch on spatial layer "
<< spatial_layer.first << ", expected "
<< expected_temporal_layers << " but got "
<< spatial_layer.second.size();
return false;
}
for (const auto& temporal_layer : spatial_layer.second) {
if (temporal_layer.first < 0 ||
temporal_layer.first >= expected_temporal_layers) {
*result_listener << "temporal layer index on spatial layer "
<< spatial_layer.first << " is not in range [0,"
<< expected_temporal_layers << "[.";
return false;
}
}
}
return true;
}
TEST_P(SvcTest, ScalabilityModeSupported) {
// Track frames using an RTP header instead of modifying the encoded data as
// this doesn't seem to work for AV1.
webrtc::test::ScopedFieldTrials override_trials(
AppendFieldTrials("WebRTC-VideoFrameTrackingIdAdvertised/Enabled/"));
std::unique_ptr<NetworkEmulationManager> network_emulation_manager =
CreateNetworkEmulationManager(webrtc::TimeMode::kSimulated);
auto analyzer = std::make_unique<SvcVideoQualityAnalyzer>(
network_emulation_manager->time_controller()->GetClock());
SvcVideoQualityAnalyzer* analyzer_ptr = analyzer.get();
auto fixture = CreateTestFixture(
UnitTest::GetInstance()->current_test_info()->name(),
*network_emulation_manager->time_controller(),
CreateTwoNetworkLinks(network_emulation_manager.get(),
BuiltInNetworkBehaviorConfig()),
[this](PeerConfigurer* alice) {
VideoConfig video(/*stream_label=*/"alice-video", /*width=*/1850,
/*height=*/1110, /*fps=*/30);
RtpEncodingParameters parameters;
parameters.scalability_mode = GetParam().scalability_mode;
video.encoding_params.push_back(parameters);
alice->AddVideoConfig(
std::move(video),
CreateScreenShareFrameGenerator(
video, ScreenShareConfig(TimeDelta::Seconds(5))));
alice->SetVideoCodecs({video_codec_config});
},
[](PeerConfigurer* bob) {}, std::move(analyzer));
fixture->Run(RunParams(TimeDelta::Seconds(5)));
EXPECT_THAT(analyzer_ptr->encoder_layers_seen(),
HasSpatialAndTemporalLayers(GetParam().expected_spatial_layers,
GetParam().expected_temporal_layers));
EXPECT_THAT(analyzer_ptr->decoder_layers_seen(),
HasSpatialAndTemporalLayers(GetParam().expected_spatial_layers,
GetParam().expected_temporal_layers));
RTC_LOG(LS_INFO) << "Encoder layers seen: "
<< analyzer_ptr->encoder_layers_seen().size();
for (auto& [spatial_index, temporal_layers] :
analyzer_ptr->encoder_layers_seen()) {
for (auto& [temporal_index, frame_count] : temporal_layers) {
RTC_LOG(LS_INFO) << " Layer: " << spatial_index << "," << temporal_index
<< " frames: " << frame_count;
}
}
RTC_LOG(LS_INFO) << "Decoder layers seen: "
<< analyzer_ptr->decoder_layers_seen().size();
for (auto& [spatial_index, temporal_layers] :
analyzer_ptr->decoder_layers_seen()) {
for (auto& [temporal_index, frame_count] : temporal_layers) {
RTC_LOG(LS_INFO) << " Layer: " << spatial_index << "," << temporal_index
<< " frames: " << frame_count;
}
}
}
INSTANTIATE_TEST_SUITE_P(
SvcTestVP8,
SvcTest,
Values(SvcTestParameters{cricket::kVp8CodecName, "L1T1", 1, 1},
SvcTestParameters{cricket::kVp8CodecName, "L1T2", 1, 2},
SvcTestParameters{cricket::kVp8CodecName, "L1T3", 1, 3}));
#if RTC_ENABLE_VP9
INSTANTIATE_TEST_SUITE_P(
SvcTestVP9,
SvcTest,
Values(SvcTestParameters{cricket::kVp9CodecName, "L1T1", 1, 1},
SvcTestParameters{cricket::kVp9CodecName, "L1T2", 1, 2},
SvcTestParameters{cricket::kVp9CodecName, "L1T3", 1, 3},
SvcTestParameters{cricket::kVp9CodecName, "L2T1", 2, 1},
SvcTestParameters{cricket::kVp9CodecName, "L2T1h", 2, 1},
SvcTestParameters{cricket::kVp9CodecName, "L2T1_KEY", 2, 1},
SvcTestParameters{cricket::kVp9CodecName, "L2T2", 2, 2},
SvcTestParameters{cricket::kVp9CodecName, "L2T2_KEY", 2, 2},
SvcTestParameters{cricket::kVp9CodecName, "L2T2_KEY_SHIFT", 2, 2},
SvcTestParameters{cricket::kVp9CodecName, "L2T3_KEY", 2, 3},
SvcTestParameters{cricket::kVp9CodecName, "L3T1", 3, 1},
SvcTestParameters{cricket::kVp9CodecName, "L3T3", 3, 3}));
// TODO(bugs.webrtc.org/11607): Fix and enable tests
// SvcTestParameters{cricket::kVp9CodecName, "L3T3_KEY", 3, 3},
// SvcTestParameters{cricket::kVp9CodecName, "S2T1", 2, 1},
// SvcTestParameters{cricket::kVp9CodecName, "S3T3", 3, 3},
#endif
} // namespace webrtc

View File

@ -386,6 +386,7 @@ if (!build_with_chromium) {
":test_activities_executor",
":test_peer",
":test_peer_factory",
":video_frame_tracking_id_injector",
":video_quality_analyzer_injection_helper",
":video_quality_metrics_reporter",
"../..:field_trial",

View File

@ -33,6 +33,7 @@
#include "test/field_trial.h"
#include "test/pc/e2e/analyzer/audio/default_audio_quality_analyzer.h"
#include "test/pc/e2e/analyzer/video/default_video_quality_analyzer.h"
#include "test/pc/e2e/analyzer/video/video_frame_tracking_id_injector.h"
#include "test/pc/e2e/analyzer/video/video_quality_metrics_reporter.h"
#include "test/pc/e2e/cross_media_metrics_reporter.h"
#include "test/pc/e2e/stats_poller.h"
@ -138,8 +139,13 @@ PeerConnectionE2EQualityTest::PeerConnectionE2EQualityTest(
video_quality_analyzer = std::make_unique<DefaultVideoQualityAnalyzer>(
time_controller_.GetClock());
}
encoded_image_data_propagator_ =
std::make_unique<SingleProcessEncodedImageDataInjector>();
if (field_trial::IsEnabled("WebRTC-VideoFrameTrackingIdAdvertised")) {
encoded_image_data_propagator_ =
std::make_unique<VideoFrameTrackingIdInjector>();
} else {
encoded_image_data_propagator_ =
std::make_unique<SingleProcessEncodedImageDataInjector>();
}
video_quality_analyzer_injection_helper_ =
std::make_unique<VideoQualityAnalyzerInjectionHelper>(
std::move(video_quality_analyzer),