Merge branch 'm110' into 5481

This commit is contained in:
Rashad Sookram 2023-02-17 11:35:29 -05:00
commit 03ddb5df82
887 changed files with 32952 additions and 55419 deletions

View file

@ -68,6 +68,7 @@ Jose Antonio Olivera Ortega <josea.olivera@gmail.com>
Keiichi Enomoto <enm10k@gmail.com> Keiichi Enomoto <enm10k@gmail.com>
Kiran Thind <kiran.thind@gmail.com> Kiran Thind <kiran.thind@gmail.com>
Korniltsev Anatoly <korniltsev.anatoly@gmail.com> Korniltsev Anatoly <korniltsev.anatoly@gmail.com>
Kyutae Lee <gorisanson@gmail.com>
Lennart Grahl <lennart.grahl@gmail.com> Lennart Grahl <lennart.grahl@gmail.com>
Luke Weber <luke.weber@gmail.com> Luke Weber <luke.weber@gmail.com>
Maksim Khobat <maksimkhobat@gmail.com> Maksim Khobat <maksimkhobat@gmail.com>
@ -79,6 +80,7 @@ Maksim Sisov <msisov@igalia.com>
Maxim Pavlov <pavllovmax@gmail.com> Maxim Pavlov <pavllovmax@gmail.com>
Maxim Potapov <vopatop.skam@gmail.com> Maxim Potapov <vopatop.skam@gmail.com>
Michael Iedema <michael@kapsulate.com> Michael Iedema <michael@kapsulate.com>
Michał Zarach <michalzaq12@gmail.com>
Michel Promonet <michel.promonet.1@gmail.com> Michel Promonet <michel.promonet.1@gmail.com>
Miguel Paris <mparisdiaz@gmail.com> Miguel Paris <mparisdiaz@gmail.com>
Mike Gilbert <floppymaster@gmail.com> Mike Gilbert <floppymaster@gmail.com>
@ -106,6 +108,7 @@ Sarah Thompson <sarah@telergy.com>
Satender Saroha <ssaroha@yahoo.com> Satender Saroha <ssaroha@yahoo.com>
Saul Kravitz <Saul.Kravitz@celera.com> Saul Kravitz <Saul.Kravitz@celera.com>
Sergio Garcia Murillo <sergio.garcia.murillo@gmail.com> Sergio Garcia Murillo <sergio.garcia.murillo@gmail.com>
Shaofan Qi <vshaqi@gmail.com>
Shuhai Peng <shuhai.peng@intel.com> Shuhai Peng <shuhai.peng@intel.com>
Silviu Caragea <silviu.cpp@gmail.com> Silviu Caragea <silviu.cpp@gmail.com>
Stefan Gula <steweg@gmail.com> Stefan Gula <steweg@gmail.com>
@ -137,14 +140,17 @@ Pengfei Han <hanpfei@gmail.com>
Agora IO <*@agora.io> Agora IO <*@agora.io>
ARM Holdings <*@arm.com> ARM Holdings <*@arm.com>
BroadSoft Inc. <*@broadsoft.com> BroadSoft Inc. <*@broadsoft.com>
Canonical Ltd <*@canonical.com>
CoSMo Software Consulting, Pte Ltd <*@cosmosoftware.io> CoSMo Software Consulting, Pte Ltd <*@cosmosoftware.io>
Facebook Inc. <*@fb.com> Facebook Inc. <*@fb.com>
Google Inc. <*@google.com> Google Inc. <*@google.com>
Highfive, Inc. <*@highfive.com> Highfive, Inc. <*@highfive.com>
Hopin Ltd. <*@hopin.to>
HyperConnect Inc. <*@hpcnt.com> HyperConnect Inc. <*@hpcnt.com>
Intel Corporation <*@intel.com> Intel Corporation <*@intel.com>
LG Electronics, Inc. <*@lge.com> LG Electronics, Inc. <*@lge.com>
Life On Air Inc. <*@lifeonair.com> Life On Air Inc. <*@lifeonair.com>
Meta Platforms, Inc. <*@meta.com>
Microsoft Corporation <*@microsoft.com> Microsoft Corporation <*@microsoft.com>
MIPS Technologies <*@mips.com> MIPS Technologies <*@mips.com>
Mozilla Foundation <*@mozilla.com> Mozilla Foundation <*@mozilla.com>

View file

@ -47,6 +47,7 @@ if (!build_with_chromium) {
} }
if (rtc_include_tests) { if (rtc_include_tests) {
deps += [ deps += [
":fuchsia_perf_tests",
":rtc_unittests", ":rtc_unittests",
":video_engine_tests", ":video_engine_tests",
":voip_unittests", ":voip_unittests",
@ -106,6 +107,9 @@ if (!build_with_chromium) {
"tools_webrtc/perf:webrtc_dashboard_upload", "tools_webrtc/perf:webrtc_dashboard_upload",
] ]
} }
if ((is_linux || is_chromeos) && rtc_use_pipewire) {
deps += [ "modules/desktop_capture:shared_screencast_stream_test" ]
}
} }
if (target_os == "android") { if (target_os == "android") {
deps += [ "tools_webrtc:binary_version_check" ] deps += [ "tools_webrtc:binary_version_check" ]
@ -270,6 +274,12 @@ config("common_config") {
defines += [ "WEBRTC_ENABLE_PROTOBUF=0" ] defines += [ "WEBRTC_ENABLE_PROTOBUF=0" ]
} }
if (rtc_strict_field_trials) {
defines += [ "WEBRTC_STRICT_FIELD_TRIALS=1" ]
} else {
defines += [ "WEBRTC_STRICT_FIELD_TRIALS=0" ]
}
if (rtc_include_internal_audio_device) { if (rtc_include_internal_audio_device) {
defines += [ "WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE" ] defines += [ "WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE" ]
} }
@ -719,6 +729,22 @@ if (rtc_include_tests && !build_with_chromium) {
} }
} }
rtc_test("fuchsia_perf_tests") {
testonly = true
deps = [
#TODO(fxbug.dev/115601) - Enable when fixed
#"call:call_perf_tests",
#"video:video_pc_full_stack_tests",
"modules/audio_coding:audio_coding_perf_tests",
"modules/audio_processing:audio_processing_perf_tests",
"pc:peerconnection_perf_tests",
"test:test_main",
"video:video_full_stack_tests",
]
data = webrtc_perf_tests_resources
}
rtc_test("webrtc_nonparallel_tests") { rtc_test("webrtc_nonparallel_tests") {
testonly = true testonly = true
deps = [ "rtc_base:rtc_base_nonparallel_tests" ] deps = [ "rtc_base:rtc_base_nonparallel_tests" ]

202
DEPS
View file

@ -10,27 +10,28 @@ vars = {
# chromium waterfalls. More info at: crbug.com/570091. # chromium waterfalls. More info at: crbug.com/570091.
'checkout_configuration': 'default', 'checkout_configuration': 'default',
'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"',
'chromium_revision': '77bb30c0feae9b39c57af30e7b77a68d75727b83', 'chromium_revision': 'd4870f767ea66ffff0f83f8267d2b61dfff0bf5d',
# Keep the Chromium default of generating location tags. # Keep the Chromium default of generating location tags.
'generate_location_tags': True, 'generate_location_tags': True,
# ResultDB version # ResultDB version
'resultdb_version': 'git_revision:6cc18e2763e180929d70c786b419c1f8e6bcc66c', 'resultdb_version': 'git_revision:39e20ee396fe4a84eaa7f7d389e5659198c12e87',
# By default, download the fuchsia sdk from the public sdk directory. # By default, download the fuchsia sdk from the public sdk directory.
'fuchsia_sdk_cipd_prefix': 'fuchsia/sdk/gn/', 'fuchsia_sdk_cipd_prefix': 'fuchsia/sdk/gn/',
'fuchsia_version': 'version:9.20220919.2.1', 'fuchsia_version': 'version:10.20221201.3.1',
# By default, download the fuchsia images from the fuchsia GCS bucket. # By default, download the fuchsia images from the fuchsia GCS bucket.
'fuchsia_images_bucket': 'fuchsia', 'fuchsia_images_bucket': 'fuchsia',
'checkout_fuchsia_boot_images': "qemu.x64",
'checkout_fuchsia': False, 'checkout_fuchsia': False,
# Since the images are hundreds of MB, default to only downloading the image
# By default, do not check out the re-client binaries. # most commonly useful for developers. Bots and developers that need to use
'checkout_reclient': False, # other images can override this with additional images.
'checkout_fuchsia_boot_images': "terminal.qemu-x64",
'checkout_fuchsia_product_bundles': '"{checkout_fuchsia_boot_images}" != ""',
# reclient CIPD package version # reclient CIPD package version
'reclient_version': 're_client_version:0.81.1.0853992-gomaip', 'reclient_version': 're_client_version:0.87.0.b6908b3-gomaip',
# ninja CIPD package version # ninja CIPD package version
# https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja
@ -40,30 +41,30 @@ vars = {
deps = { deps = {
# TODO(kjellander): Move this to be Android-only. # TODO(kjellander): Move this to be Android-only.
'src/base': 'src/base':
'https://chromium.googlesource.com/chromium/src/base@b054aaefd4d4ec5aad7189c4e97000a06b594163', 'https://chromium.googlesource.com/chromium/src/base@4a17a70520935f05e354de004dcb44c7b1df534f',
'src/build': 'src/build':
'https://chromium.googlesource.com/chromium/src/build@1c4f38fd4f534d78b72cefc376a03b3e8b486e7c', 'https://chromium.googlesource.com/chromium/src/build@c91a4dbdb666e9bd82b187109ad311c58a552ce6',
'src/buildtools': 'src/buildtools':
'https://chromium.googlesource.com/chromium/src/buildtools@24fa2da896a027e7202bb8886177cccfe885b67d', 'https://chromium.googlesource.com/chromium/src/buildtools@dcbf73cdcbcd0a2948b9e40bf500de166f622261',
# Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC.
'src/examples/androidtests/third_party/gradle': { 'src/examples/androidtests/third_party/gradle': {
'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3',
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
'src/ios': { 'src/ios': {
'url': 'https://chromium.googlesource.com/chromium/src/ios@2043810d93b43e6c40586f228b85ff65fd277067', 'url': 'https://chromium.googlesource.com/chromium/src/ios@36316fedfa1873be15dcaf681bf1295696abafbc',
'condition': 'checkout_ios', 'condition': 'checkout_ios',
}, },
'src/testing': 'src/testing':
'https://chromium.googlesource.com/chromium/src/testing@6f2362298838e8789b09282cf198c8582f9c4555', 'https://chromium.googlesource.com/chromium/src/testing@9adab94016c5e0840a235b4c0a7dd85173d3f370',
'src/third_party': 'src/third_party':
'https://chromium.googlesource.com/chromium/src/third_party@28a4580f804c4fc4279ecf10100a409811030235', 'https://chromium.googlesource.com/chromium/src/third_party@fc733299410a7104a0848539baab0131b8a616b8',
'src/buildtools/linux64': { 'src/buildtools/linux64': {
'packages': [ 'packages': [
{ {
'package': 'gn/gn/linux-${{arch}}', 'package': 'gn/gn/linux-${{arch}}',
'version': 'git_revision:b9c6c19be95a3863e02f00f1fe403b2502e345b6', 'version': 'git_revision:5e19d2fb166fbd4f6f32147fbb2f497091a54ad8',
} }
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
@ -73,7 +74,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'gn/gn/mac-${{arch}}', 'package': 'gn/gn/mac-${{arch}}',
'version': 'git_revision:b9c6c19be95a3863e02f00f1fe403b2502e345b6', 'version': 'git_revision:5e19d2fb166fbd4f6f32147fbb2f497091a54ad8',
} }
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
@ -83,7 +84,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'gn/gn/windows-amd64', 'package': 'gn/gn/windows-amd64',
'version': 'git_revision:b9c6c19be95a3863e02f00f1fe403b2502e345b6', 'version': 'git_revision:5e19d2fb166fbd4f6f32147fbb2f497091a54ad8',
} }
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
@ -92,22 +93,24 @@ deps = {
'src/buildtools/reclient': { 'src/buildtools/reclient': {
'packages': [ 'packages': [
{ {
# https://chrome-infra-packages.appspot.com/p/infra/rbe/client/
'package': 'infra/rbe/client/${{platform}}', 'package': 'infra/rbe/client/${{platform}}',
'version': Var('reclient_version'), 'version': Var('reclient_version'),
} }
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
'condition': 'checkout_reclient', # Reclient doesn't have linux-arm64 package.
'condition': 'not (host_os == "linux" and host_cpu == "arm64")',
}, },
'src/buildtools/clang_format/script': 'src/buildtools/clang_format/script':
'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@8b525d2747f2584fc35d8c7e612e66f377858df7', 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@8b525d2747f2584fc35d8c7e612e66f377858df7',
'src/buildtools/third_party/libc++/trunk': 'src/buildtools/third_party/libc++/trunk':
'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@64d36e572d3f9719c5d75011a718f33f11126851', 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@2fc3d704672fbd3e85fad8492d39e02d49412891',
'src/buildtools/third_party/libc++abi/trunk': 'src/buildtools/third_party/libc++abi/trunk':
'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@9572e56a12c88c011d504a707ca94952be4664f9', 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@123239cdb67b3d69c5af933e364a84019a33575c',
'src/buildtools/third_party/libunwind/trunk': 'src/buildtools/third_party/libunwind/trunk':
'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@1111799723f6a003e6f52202b9bf84387c552081', 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@5e22a7fe2335161ab267867c8e1be481bf6c8300',
'src/third_party/ninja': { 'src/third_party/ninja': {
'packages': [ 'packages': [
@ -143,7 +146,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/android_build_tools/aapt2', 'package': 'chromium/third_party/android_build_tools/aapt2',
'version': 'nSnWUNu6ssPA-kPMvFQj4JjDXRWj2iubvvjfT1F6HCMC', 'version': 'cbNG7g8Sinh-lsT8hWsU-RyXqLT_uh4jIb1fjCdhrzIC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -154,7 +157,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/android_build_tools/bundletool', 'package': 'chromium/third_party/android_build_tools/bundletool',
'version': 'IEZQhHFQzO9Ci1QxWZmssKqGmt2r_nCDMKr8t4cKY34C', 'version': 'eYz83zbG33sGLyNdc-a64qo1K6LRcS9GwW7GmSvyWisC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -162,11 +165,11 @@ deps = {
}, },
'src/third_party/boringssl/src': 'src/third_party/boringssl/src':
'https://boringssl.googlesource.com/boringssl.git@1ee71185a2322dc354bee5e5a0abfb1810a27dc6', 'https://boringssl.googlesource.com/boringssl.git@28f96c2686459add7acedcd97cb841030bdda019',
'src/third_party/breakpad/breakpad': 'src/third_party/breakpad/breakpad':
'https://chromium.googlesource.com/breakpad/breakpad.git@e085b3b50bde862d0cf3ce4594e3f391bcf5faec', 'https://chromium.googlesource.com/breakpad/breakpad.git@cc7abac08b0c52e6581b9c9c4226816b17a4c26d',
'src/third_party/catapult': 'src/third_party/catapult':
'https://chromium.googlesource.com/catapult.git@4793433248183dd073e608f655204d4acfdc7193', 'https://chromium.googlesource.com/catapult.git@bf0782db65682f3918886ba69807c03fe515c2e8',
'src/third_party/ced/src': { 'src/third_party/ced/src': {
'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5',
}, },
@ -175,9 +178,11 @@ deps = {
'src/third_party/crc32c/src': 'src/third_party/crc32c/src':
'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6',
'src/third_party/depot_tools': 'src/third_party/depot_tools':
'https://chromium.googlesource.com/chromium/tools/depot_tools.git@2c0a8c736a59044e4acc7be9e172343adc5c4310', 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@41a2d0f1a0173723f63ca2994e17c81eaf302b65',
'src/third_party/ffmpeg': 'src/third_party/ffmpeg':
'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@b9f01c3c54576330b2cf8918c54d5ee5be8faefe', 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@a249b21db6516234e5456716ae074fbb00176b3f',
'src/third_party/flatbuffers/src':
'https://chromium.googlesource.com/external/github.com/google/flatbuffers.git@e3017029647a88eb6f509ee9744012fffeb0d371',
'src/third_party/grpc/src': { 'src/third_party/grpc/src': {
'url': 'https://chromium.googlesource.com/external/github.com/grpc/grpc.git@dd77c67217b10ffeaf766e25eb8b46d2d59de4ff', 'url': 'https://chromium.googlesource.com/external/github.com/grpc/grpc.git@dd77c67217b10ffeaf766e25eb8b46d2d59de4ff',
}, },
@ -187,9 +192,9 @@ deps = {
'condition': 'checkout_linux', 'condition': 'checkout_linux',
}, },
'src/third_party/freetype/src': 'src/third_party/freetype/src':
'https://chromium.googlesource.com/chromium/src/third_party/freetype2.git@5182264a40e70ff31be0a0ec8a0d5ffb5f65582e', 'https://chromium.googlesource.com/chromium/src/third_party/freetype2.git@ace97a02a4461bbdae29da4019c105eead95e277',
'src/third_party/harfbuzz-ng/src': 'src/third_party/harfbuzz-ng/src':
'https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz.git@56c467093598ec559a7148b61e112e9de52b7076', 'https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz.git@2822b589bc837fae6f66233e2cf2eef0f6ce8470',
'src/third_party/google_benchmark/src': { 'src/third_party/google_benchmark/src': {
'url': 'https://chromium.googlesource.com/external/github.com/google/benchmark.git@f730846b0a3c0dc0699978846fb14ffb2fad0bdc', 'url': 'https://chromium.googlesource.com/external/github.com/google/benchmark.git@f730846b0a3c0dc0699978846fb14ffb2fad0bdc',
}, },
@ -209,7 +214,7 @@ deps = {
'src/third_party/googletest/src': 'src/third_party/googletest/src':
'https://chromium.googlesource.com/external/github.com/google/googletest.git@af29db7ec28d6df1c7f0f745186884091e602e07', 'https://chromium.googlesource.com/external/github.com/google/googletest.git@af29db7ec28d6df1c7f0f745186884091e602e07',
'src/third_party/icu': { 'src/third_party/icu': {
'url': 'https://chromium.googlesource.com/chromium/deps/icu.git@20f8ac695af59b6c830def7d4e95bfeb13dd7be5', 'url': 'https://chromium.googlesource.com/chromium/deps/icu.git@1b7d391f0528fb3a4976b7541b387ee04f915f83',
}, },
'src/third_party/jdk': { 'src/third_party/jdk': {
'packages': [ 'packages': [
@ -224,7 +229,7 @@ deps = {
'src/third_party/jsoncpp/source': 'src/third_party/jsoncpp/source':
'https://chromium.googlesource.com/external/github.com/open-source-parsers/jsoncpp.git@42e892d96e47b1f6e29844cc705e148ec4856448', # from svn 248 'https://chromium.googlesource.com/external/github.com/open-source-parsers/jsoncpp.git@42e892d96e47b1f6e29844cc705e148ec4856448', # from svn 248
'src/third_party/junit/src': { 'src/third_party/junit/src': {
'url': 'https://chromium.googlesource.com/external/junit.git@64155f8a9babcfcf4263cf4d08253a1556e75481', 'url': 'https://chromium.googlesource.com/external/junit.git@05fe2a64f59127c02135be22f416e91260d6ede6',
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
# Used for building libFuzzers (only supports Linux). # Used for building libFuzzers (only supports Linux).
@ -237,17 +242,17 @@ deps = {
'src/third_party/dav1d/libdav1d': 'src/third_party/dav1d/libdav1d':
'https://chromium.googlesource.com/external/github.com/videolan/dav1d.git@87f9a81cd770e49394a45deca7a3df41243de00b', 'https://chromium.googlesource.com/external/github.com/videolan/dav1d.git@87f9a81cd770e49394a45deca7a3df41243de00b',
'src/third_party/libaom/source/libaom': 'src/third_party/libaom/source/libaom':
'https://aomedia.googlesource.com/aom.git@7f32eb35ff2589369f095388701e3dfc4d6a9381', 'https://aomedia.googlesource.com/aom.git@a84503456d4276348da3e80de7569adb1b389a60',
'src/third_party/libunwindstack': { 'src/third_party/libunwindstack': {
'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@8740b09bd1f8b81bdba92766afcb9df1d6a1f14e', 'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@4dbfa0e8c844c8e243b297bc185e54a99ff94f9e',
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
'src/third_party/perfetto': 'src/third_party/perfetto':
'https://android.googlesource.com/platform/external/perfetto.git@129b11632395a84eb3307d72fde9a90945e18619', 'https://android.googlesource.com/platform/external/perfetto.git@61ba4b9b606100828e425eb9a245dd45c5591f28',
'src/third_party/libvpx/source/libvpx': 'src/third_party/libvpx/source/libvpx':
'https://chromium.googlesource.com/webm/libvpx.git@9d6d0624d7943a09cc0be9df1a7402522989ac1a', 'https://chromium.googlesource.com/webm/libvpx.git@605350bd5b68ac47f595d60cc8ef346588e773c0',
'src/third_party/libyuv': 'src/third_party/libyuv':
'https://chromium.googlesource.com/libyuv/libyuv.git@00950840d1c9bcbb3eb6ebc5aac5793e71166c8b', 'https://chromium.googlesource.com/libyuv/libyuv.git@4a3c79cb31aee310443039c37d64377ed06f1d14',
'src/third_party/lss': { 'src/third_party/lss': {
'url': 'https://chromium.googlesource.com/linux-syscall-support.git@ce877209e11aa69dcfffbd53ef90ea1d07136521', 'url': 'https://chromium.googlesource.com/linux-syscall-support.git@ce877209e11aa69dcfffbd53ef90ea1d07136521',
'condition': 'checkout_android or checkout_linux', 'condition': 'checkout_android or checkout_linux',
@ -259,16 +264,16 @@ deps = {
# Used by boringssl. # Used by boringssl.
'src/third_party/nasm': { 'src/third_party/nasm': {
'url': 'https://chromium.googlesource.com/chromium/deps/nasm.git@9215e8e1d0fe474ffd3e16c1a07a0f97089e6224' 'url': 'https://chromium.googlesource.com/chromium/deps/nasm.git@0873b2bae6a5388a1c55deac8456e3c60a47ca08'
}, },
'src/third_party/openh264/src': 'src/third_party/openh264/src':
'https://chromium.googlesource.com/external/github.com/cisco/openh264@fac04ceb3e966f613ed17e98178e9d690280bba6', 'https://chromium.googlesource.com/external/github.com/cisco/openh264@db956674bbdfbaab5acdd3fdb4117c2fef5527e9',
'src/third_party/r8': { 'src/third_party/r8': {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/r8', 'package': 'chromium/third_party/r8',
'version': 'szXK3tCGU7smsNs4r2mGqxme7d9KWLaOk0_ghbCJxUQC', 'version': 'pv_BIbpK8sxEFp63muv1gKsbyWJoyv4PDw342wc9H6AC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -281,7 +286,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/r8', 'package': 'chromium/third_party/r8',
'version': 'tQcmB4wHWxamdPd8ix5IwMv8eBEbMBeN4vEtGjikDeQC', 'version': 'qGtBu6TtxyR5XNy4cmsslb7c946YtkZF5_QCjVP-wc8C',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -292,7 +297,7 @@ deps = {
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
'src/tools': 'src/tools':
'https://chromium.googlesource.com/chromium/src/tools@d97453670f86a8cc5050802a4a49083c5db3b39a', 'https://chromium.googlesource.com/chromium/src/tools@0c34fd995e2cfdb007209c44bb0d28e894b1d2ea',
'src/third_party/accessibility_test_framework': { 'src/third_party/accessibility_test_framework': {
'packages': [ 'packages': [
@ -369,7 +374,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/androidx', 'package': 'chromium/third_party/androidx',
'version': 'h7h2tZ_Dqu-O57Bk14oz6B7AaJLu1naK5jGnsQ5vaJQC', 'version': '3ADwB26rDMIdmScjo6j4e98VQl6amFOyrvsvrVRthBMC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -380,7 +385,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/android_build_tools/manifest_merger', 'package': 'chromium/third_party/android_build_tools/manifest_merger',
'version': 'bUREd_PkCqlp2ww6zmyOLGf0jhqgbnf6GT4V1xkAZ10C', 'version': 'X4l8RIBEAF108FpSEWRF7UHqq-kY8T3ibSsObGU5u3UC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -415,7 +420,7 @@ deps = {
}, },
{ {
'package': 'chromium/third_party/android_sdk/public/cmdline-tools', 'package': 'chromium/third_party/android_sdk/public/cmdline-tools',
'version': 'IPzAG-uU5zVMxohpg9-7-N0tQC1TCSW1VbrBFw7Ld04C', 'version': 'oWlET2yQhaPKQ66tYNuSPaueU78Z9VlxpyxOoUjwRuIC',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -470,7 +475,7 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'chromium/third_party/turbine', 'package': 'chromium/third_party/turbine',
'version': 'rrpgWQ-uylo8c5IPgUVP464LwcVOmt29MqwsR59O_zkC', 'version': 'R-Qp1tMBqIuETMfXNqQU9GB00ij6dsPjVmjDuvH_194C',
}, },
], ],
'condition': 'checkout_android', 'condition': 'checkout_android',
@ -481,15 +486,30 @@ deps = {
'packages': [ 'packages': [
{ {
'package': 'infra/tools/luci/isolate/${{platform}}', 'package': 'infra/tools/luci/isolate/${{platform}}',
'version': 'git_revision:9f65ffe719f73af390727d369b342c22fa37ea54', 'version': 'git_revision:bac571b5399502fa16ac48a1d3820e1117505085',
}, },
{ {
'package': 'infra/tools/luci/swarming/${{platform}}', 'package': 'infra/tools/luci/swarming/${{platform}}',
'version': 'git_revision:9f65ffe719f73af390727d369b342c22fa37ea54', 'version': 'git_revision:bac571b5399502fa16ac48a1d3820e1117505085',
}, },
], ],
'dep_type': 'cipd', 'dep_type': 'cipd',
}, },
'src/third_party/pipewire/linux-amd64': {
'packages': [
{
'package': 'chromium/third_party/pipewire/linux-amd64',
'version': 'BaVKmAmwpjdS6O0pnjSaMNSKhO1nmk5mRnyPVAJ2-HEC',
},
{
'package': 'chromium/third_party/pipewire-media-session/linux-amd64',
'version': 'Y6wUeITvAA0QD1vt8_a7eQdzbp0gkI1B02qfZUMJdowC',
},
],
'condition': 'checkout_linux',
'dep_type': 'cipd',
},
# Everything coming after this is automatically updated by the auto-roller. # Everything coming after this is automatically updated by the auto-roller.
# === ANDROID_DEPS Generated Code Start === # === ANDROID_DEPS Generated Code Start ===
@ -923,28 +943,6 @@ deps = {
'dep_type': 'cipd', 'dep_type': 'cipd',
}, },
'src/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs': {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs',
'version': 'version:2@1.1.5.cr1',
},
],
'condition': 'checkout_android',
'dep_type': 'cipd',
},
'src/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration': {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/com_android_tools_desugar_jdk_libs_configuration',
'version': 'version:2@1.1.5.cr1',
},
],
'condition': 'checkout_android',
'dep_type': 'cipd',
},
'src/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api': { 'src/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api': {
'packages': [ 'packages': [
{ {
@ -1583,17 +1581,6 @@ deps = {
'dep_type': 'cipd', 'dep_type': 'cipd',
}, },
'src/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java': {
'packages': [
{
'package': 'chromium/third_party/android_deps/libs/com_google_flatbuffers_flatbuffers_java',
'version': 'version:2@2.0.3.cr1',
},
],
'condition': 'checkout_android',
'dep_type': 'cipd',
},
'src/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format': { 'src/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format': {
'packages': [ 'packages': [
{ {
@ -2416,16 +2403,14 @@ hooks = [
'--version={fuchsia_version}', '--version={fuchsia_version}',
], ],
}, },
{ {
'name': 'Download Fuchsia system images', 'name': 'Download Fuchsia system images',
'pattern': '.', 'pattern': '.',
'condition': 'checkout_fuchsia', 'condition': 'checkout_fuchsia and checkout_fuchsia_product_bundles',
'action': [ 'action': [
'python3', 'python3',
'src/build/fuchsia/update_images.py', 'src/build/fuchsia/update_product_bundles.py',
'--boot-images={checkout_fuchsia_boot_images}', '{checkout_fuchsia_boot_images}',
'--default-bucket={fuchsia_images_bucket}',
], ],
}, },
{ {
@ -2571,27 +2556,51 @@ hooks = [
], ],
}, },
{ {
'name': 'msan_chained_origins', 'name': 'msan_chained_origins_focal',
'pattern': '.', 'pattern': '.',
'condition': 'checkout_instrumented_libraries', 'condition': 'checkout_instrumented_libraries',
'action': [ 'python3', 'action': [ 'python3',
'src/third_party/depot_tools/download_from_google_storage.py', 'src/third_party/depot_tools/download_from_google_storage.py',
"--no_resume", '--no_resume',
"--no_auth", '--no_auth',
"--bucket", "chromium-instrumented-libraries", '--bucket', 'chromium-instrumented-libraries',
"-s", "src/third_party/instrumented_libraries/binaries/msan-chained-origins.tgz.sha1", '-s', 'src/third_party/instrumented_libraries/binaries/msan-chained-origins-focal.tgz.sha1',
], ],
}, },
{ {
'name': 'msan_no_origins', 'name': 'msan_no_origins_focal',
'pattern': '.', 'pattern': '.',
'condition': 'checkout_instrumented_libraries', 'condition': 'checkout_instrumented_libraries',
'action': [ 'python3', 'action': [ 'python3',
'src/third_party/depot_tools/download_from_google_storage.py', 'src/third_party/depot_tools/download_from_google_storage.py',
"--no_resume", '--no_resume',
"--no_auth", '--no_auth',
"--bucket", "chromium-instrumented-libraries", '--bucket', 'chromium-instrumented-libraries',
"-s", "src/third_party/instrumented_libraries/binaries/msan-no-origins.tgz.sha1", '-s', 'src/third_party/instrumented_libraries/binaries/msan-no-origins-focal.tgz.sha1',
],
},
{
'name': 'msan_chained_origins_xenial',
'pattern': '.',
'condition': 'checkout_instrumented_libraries',
'action': [ 'python3',
'src/third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-instrumented-libraries',
'-s', 'src/third_party/instrumented_libraries/binaries/msan-chained-origins-xenial.tgz.sha1',
],
},
{
'name': 'msan_no_origins_xenial',
'pattern': '.',
'condition': 'checkout_instrumented_libraries',
'action': [ 'python3',
'src/third_party/depot_tools/download_from_google_storage.py',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-instrumented-libraries',
'-s', 'src/third_party/instrumented_libraries/binaries/msan-no-origins-xenial.tgz.sha1',
], ],
}, },
{ {
@ -2663,6 +2672,7 @@ include_rules = [
"+absl/meta/type_traits.h", "+absl/meta/type_traits.h",
"+absl/numeric/bits.h", "+absl/numeric/bits.h",
"+absl/strings/ascii.h", "+absl/strings/ascii.h",
"+absl/strings/escaping.h",
"+absl/strings/match.h", "+absl/strings/match.h",
"+absl/strings/str_replace.h", "+absl/strings/str_replace.h",
"+absl/strings/string_view.h", "+absl/strings/string_view.h",

18
OWNERS
View file

@ -3,20 +3,4 @@ hta@webrtc.org
mflodman@webrtc.org mflodman@webrtc.org
stefan@webrtc.org stefan@webrtc.org
tommi@webrtc.org tommi@webrtc.org
per-file .gitignore=* include OWNERS_INFRA #{Owners for infra and repo related files}
per-file .gn=mbonadei@webrtc.org
per-file BUILD.gn=mbonadei@webrtc.org
per-file .../BUILD.gn=mbonadei@webrtc.org
per-file *.gni=mbonadei@webrtc.org
per-file .../*.gni=mbonadei@webrtc.org
per-file .vpython=mbonadei@webrtc.org
per-file .vpython3=mbonadei@webrtc.org
per-file AUTHORS=*
per-file DEPS=*
per-file pylintrc=mbonadei@webrtc.org
per-file WATCHLISTS=*
per-file native-api.md=mbonadei@webrtc.org
per-file ....lua=titovartem@webrtc.org
per-file .style.yapf=jleconte@webrtc.org
per-file *.py=jansson@webrtc.org
per-file *.py=jleconte@webrtc.org

17
OWNERS_INFRA Normal file
View file

@ -0,0 +1,17 @@
#Owners for infra and repo related files
per-file .gitignore=*
per-file .gn=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file BUILD.gn=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file .../BUILD.gn=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file *.gni=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file .../*.gni=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file .vpython=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file .vpython3=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file AUTHORS=*
per-file DEPS=*
per-file pylintrc=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org
per-file WATCHLISTS=*
per-file native-api.md=mbonadei@webrtc.org
per-file ....lua=titovartem@webrtc.org
per-file .style.yapf=jleconte@webrtc.org
per-file *.py=mbonadei@webrtc.org,jansson@webrtc.org,jleconte@webrtc.org

View file

@ -107,9 +107,7 @@
'yujie.mao@webrtc.org'], 'yujie.mao@webrtc.org'],
'build_files': ['mbonadei@webrtc.org'], 'build_files': ['mbonadei@webrtc.org'],
'common_audio': ['alessiob@webrtc.org', 'common_audio': ['alessiob@webrtc.org',
'aluebs@webrtc.org',
'audio-team@agora.io', 'audio-team@agora.io',
'minyue@webrtc.org',
'peah@webrtc.org', 'peah@webrtc.org',
'saza@webrtc.org'], 'saza@webrtc.org'],
'audio': ['peah@webrtc.org'], 'audio': ['peah@webrtc.org'],
@ -135,23 +133,19 @@
'audio_coding': ['alessiob@webrtc.org', 'audio_coding': ['alessiob@webrtc.org',
'audio-team@agora.io', 'audio-team@agora.io',
'henrik.lundin@webrtc.org', 'henrik.lundin@webrtc.org',
'minyue@webrtc.org',
'peah@webrtc.org', 'peah@webrtc.org',
'saza@webrtc.org'], 'saza@webrtc.org'],
'neteq': ['alessiob@webrtc.org', 'neteq': ['alessiob@webrtc.org',
'audio-team@agora.io', 'audio-team@agora.io',
'henrik.lundin@webrtc.org', 'henrik.lundin@webrtc.org',
'minyue@webrtc.org',
'saza@webrtc.org'], 'saza@webrtc.org'],
'audio_mixer': ['aleloi@webrtc.org', 'audio_mixer': ['aleloi@webrtc.org',
'henrik.lundin@webrtc.org', 'henrik.lundin@webrtc.org',
'peah@webrtc.org', 'peah@webrtc.org',
'saza@webrtc.org'], 'saza@webrtc.org'],
'audio_processing': ['alessiob@webrtc.org', 'audio_processing': ['alessiob@webrtc.org',
'aluebs@webrtc.org',
'audio-team@agora.io', 'audio-team@agora.io',
'henrik.lundin@webrtc.org', 'henrik.lundin@webrtc.org',
'minyue@webrtc.org',
'peah@webrtc.org', 'peah@webrtc.org',
'saza@webrtc.org'], 'saza@webrtc.org'],
'video_coding': ['mflodman@webrtc.org', 'video_coding': ['mflodman@webrtc.org',

View file

@ -193,6 +193,40 @@ rtc_library("dtls_transport_interface") {
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
} }
rtc_library("dtmf_sender_interface") {
visibility = [ "*" ]
sources = [ "dtmf_sender_interface.h" ]
deps = [
":media_stream_interface",
"../rtc_base:refcount",
]
}
rtc_library("rtp_sender_interface") {
visibility = [ "*" ]
sources = [
"rtp_sender_interface.cc",
"rtp_sender_interface.h",
]
deps = [
":dtls_transport_interface",
":dtmf_sender_interface",
":frame_transformer_interface",
":media_stream_interface",
":rtc_error",
":rtp_parameters",
":scoped_refptr",
"../rtc_base:checks",
"../rtc_base:refcount",
"../rtc_base/system:rtc_export",
"crypto:frame_encryptor_interface",
"video_codecs:video_codecs_api",
]
absl_deps = [ "//third_party/abseil-cpp/absl/functional:any_invocable" ]
}
rtc_library("libjingle_peerconnection_api") { rtc_library("libjingle_peerconnection_api") {
visibility = [ "*" ] visibility = [ "*" ]
cflags = [] cflags = []
@ -200,7 +234,6 @@ rtc_library("libjingle_peerconnection_api") {
"crypto_params.h", "crypto_params.h",
"data_channel_interface.cc", "data_channel_interface.cc",
"data_channel_interface.h", "data_channel_interface.h",
"dtmf_sender_interface.h",
# RingRTC change to add ICE forking # RingRTC change to add ICE forking
"ice_gatherer_interface.h", "ice_gatherer_interface.h",
"jsep.cc", "jsep.cc",
@ -208,21 +241,29 @@ rtc_library("libjingle_peerconnection_api") {
"jsep_ice_candidate.cc", "jsep_ice_candidate.cc",
"jsep_ice_candidate.h", "jsep_ice_candidate.h",
"jsep_session_description.h", "jsep_session_description.h",
"legacy_stats_types.cc",
"legacy_stats_types.h",
"peer_connection_interface.cc", "peer_connection_interface.cc",
"peer_connection_interface.h", "peer_connection_interface.h",
"rtp_receiver_interface.cc", "rtp_receiver_interface.cc",
"rtp_receiver_interface.h", "rtp_receiver_interface.h",
"rtp_sender_interface.h",
"rtp_transceiver_interface.cc", "rtp_transceiver_interface.cc",
"rtp_transceiver_interface.h", "rtp_transceiver_interface.h",
"sctp_transport_interface.cc", "sctp_transport_interface.cc",
"sctp_transport_interface.h", "sctp_transport_interface.h",
"set_local_description_observer_interface.h", "set_local_description_observer_interface.h",
"set_remote_description_observer_interface.h", "set_remote_description_observer_interface.h",
"stats_types.cc",
"stats_types.h",
"uma_metrics.h", "uma_metrics.h",
"video_track_source_proxy_factory.h", "video_track_source_proxy_factory.h",
# Remove when downstream has been updated
"dtmf_sender_interface.h",
"rtp_sender_interface.h",
]
public_deps = [ # no-presubmit-check TODO(webrtc:8603)
# Remove when downstream has been updated
":dtmf_sender_interface",
":rtp_sender_interface",
] ]
deps = [ deps = [
":array_view", ":array_view",
@ -246,6 +287,7 @@ rtc_library("libjingle_peerconnection_api") {
":rtc_stats_api", ":rtc_stats_api",
":rtp_packet_info", ":rtp_packet_info",
":rtp_parameters", ":rtp_parameters",
":rtp_sender_interface",
":rtp_transceiver_direction", ":rtp_transceiver_direction",
":scoped_refptr", ":scoped_refptr",
":sequence_checker", ":sequence_checker",
@ -296,6 +338,7 @@ rtc_library("libjingle_peerconnection_api") {
absl_deps = [ absl_deps = [
"//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/base:core_headers", "//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/functional:any_invocable",
"//third_party/abseil-cpp/absl/memory", "//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional", "//third_party/abseil-cpp/absl/types:optional",
@ -509,10 +552,7 @@ rtc_source_set("peer_network_dependencies") {
rtc_source_set("peer_connection_quality_test_fixture_api") { rtc_source_set("peer_connection_quality_test_fixture_api") {
visibility = [ "*" ] visibility = [ "*" ]
testonly = true testonly = true
sources = [ sources = [ "test/peerconnection_quality_test_fixture.h" ]
"test/peerconnection_quality_test_fixture.cc",
"test/peerconnection_quality_test_fixture.h",
]
deps = [ deps = [
":array_view", ":array_view",
@ -538,10 +578,12 @@ rtc_source_set("peer_connection_quality_test_fixture_api") {
"../rtc_base:stringutils", "../rtc_base:stringutils",
"../rtc_base:threading", "../rtc_base:threading",
"../test:fileutils", "../test:fileutils",
"../test/pc/e2e:video_dumping",
"audio:audio_mixer_api", "audio:audio_mixer_api",
"rtc_event_log", "rtc_event_log",
"task_queue", "task_queue",
"test/pclf:media_configuration",
"test/pclf:media_quality_test_params",
"test/pclf:peer_configurer",
"test/video:video_frame_writer", "test/video:video_frame_writer",
"transport:network_control", "transport:network_control",
"units:time_delta", "units:time_delta",
@ -549,6 +591,7 @@ rtc_source_set("peer_connection_quality_test_fixture_api") {
"video_codecs:video_codecs_api", "video_codecs:video_codecs_api",
] ]
absl_deps = [ absl_deps = [
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory", "//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings", "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional", "//third_party/abseil-cpp/absl/types:optional",
@ -662,9 +705,9 @@ rtc_library("create_peer_connection_quality_test_frame_generator") {
deps = [ deps = [
":create_frame_generator", ":create_frame_generator",
":frame_generator_api", ":frame_generator_api",
":peer_connection_quality_test_fixture_api",
"../rtc_base:checks", "../rtc_base:checks",
"../test:fileutils", "../test:fileutils",
"test/pclf:media_configuration",
] ]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
} }
@ -710,6 +753,8 @@ rtc_source_set("rtc_stats_api") {
"../rtc_base/system:rtc_export", "../rtc_base/system:rtc_export",
"units:timestamp", "units:timestamp",
] ]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
} }
rtc_library("audio_options_api") { rtc_library("audio_options_api") {
@ -942,22 +987,50 @@ if (rtc_include_tests) {
] ]
} }
rtc_library("videocodec_test_fixture_api") { rtc_library("videocodec_test_stats_api") {
visibility = [ "*" ] visibility = [ "*" ]
testonly = true testonly = true
sources = [ sources = [
"test/videocodec_test_fixture.h",
"test/videocodec_test_stats.cc", "test/videocodec_test_stats.cc",
"test/videocodec_test_stats.h", "test/videocodec_test_stats.h",
] ]
deps = [ deps = [
"../modules/video_coding:video_codec_interface", "../api/units:data_rate",
"../api/units:frequency",
"../rtc_base:stringutils", "../rtc_base:stringutils",
"video:video_frame_type", "video:video_frame_type",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("videocodec_test_fixture_api") {
visibility = [ "*" ]
testonly = true
sources = [ "test/videocodec_test_fixture.h" ]
deps = [
":videocodec_test_stats_api",
"../modules/video_coding:video_codec_interface",
"video_codecs:video_codecs_api", "video_codecs:video_codecs_api",
] ]
} }
rtc_library("video_codec_tester_api") {
visibility = [ "*" ]
testonly = true
sources = [ "test/video_codec_tester.h" ]
deps = [
":videocodec_test_stats_api",
"../modules/video_coding/svc:scalability_mode_util",
"video:encoded_image",
"video:resolution",
"video:video_frame",
]
absl_deps = [
"//third_party/abseil-cpp/absl/functional:any_invocable",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("create_videocodec_test_fixture_api") { rtc_library("create_videocodec_test_fixture_api") {
visibility = [ "*" ] visibility = [ "*" ]
testonly = true testonly = true
@ -973,6 +1046,19 @@ if (rtc_include_tests) {
] ]
} }
rtc_library("create_video_codec_tester_api") {
visibility = [ "*" ]
testonly = true
sources = [
"test/create_video_codec_tester.cc",
"test/create_video_codec_tester.h",
]
deps = [
":video_codec_tester_api",
"../modules/video_coding:videocodec_test_impl",
]
}
rtc_source_set("mock_audio_mixer") { rtc_source_set("mock_audio_mixer") {
visibility = [ "*" ] visibility = [ "*" ]
testonly = true testonly = true
@ -1013,6 +1099,7 @@ if (rtc_include_tests) {
sources = [ "test/mock_dtmf_sender.h" ] sources = [ "test/mock_dtmf_sender.h" ]
deps = [ deps = [
":dtmf_sender_interface",
":libjingle_peerconnection_api", ":libjingle_peerconnection_api",
"../test:test_support", "../test:test_support",
] ]
@ -1143,6 +1230,16 @@ if (rtc_include_tests) {
] ]
} }
rtc_source_set("mock_session_description_interface") {
visibility = [ "*" ]
testonly = true
sources = [ "test/mock_session_description_interface.h" ]
deps = [
":libjingle_peerconnection_api",
"../test:test_support",
]
}
rtc_source_set("mock_async_dns_resolver") { rtc_source_set("mock_async_dns_resolver") {
visibility = [ "*" ] visibility = [ "*" ]
testonly = true testonly = true
@ -1164,6 +1261,8 @@ if (rtc_include_tests) {
deps = [ deps = [
":libjingle_peerconnection_api", ":libjingle_peerconnection_api",
":rtp_sender_interface",
"../api/crypto:frame_decryptor_interface",
"../test:test_support", "../test:test_support",
] ]
} }
@ -1308,12 +1407,16 @@ if (rtc_include_tests) {
"../rtc_base:rtc_event", "../rtc_base:rtc_event",
"../rtc_base:rtc_task_queue", "../rtc_base:rtc_task_queue",
"../rtc_base:task_queue_for_test", "../rtc_base:task_queue_for_test",
"../rtc_base/containers:flat_set",
"../rtc_base/task_utils:repeating_task", "../rtc_base/task_utils:repeating_task",
"../system_wrappers:field_trial", "../system_wrappers:field_trial",
"../test:field_trial",
"../test:fileutils", "../test:fileutils",
"../test:rtc_expect_death", "../test:rtc_expect_death",
"../test:test_support", "../test:test_support",
"task_queue:task_queue_default_factory_unittests", "task_queue:task_queue_default_factory_unittests",
"test/pclf:media_configuration",
"test/video:video_frame_writer",
"transport:field_trial_based_config", "transport:field_trial_based_config",
"units:time_delta", "units:time_delta",
"units:timestamp", "units:timestamp",
@ -1322,7 +1425,10 @@ if (rtc_include_tests) {
"video:rtp_video_frame_assembler_unittests", "video:rtp_video_frame_assembler_unittests",
"video:video_unittests", "video:video_unittests",
] ]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
} }
rtc_library("compile_all_headers") { rtc_library("compile_all_headers") {
@ -1345,6 +1451,7 @@ if (rtc_include_tests) {
":mock_peer_connection_factory_interface", ":mock_peer_connection_factory_interface",
":mock_peerconnectioninterface", ":mock_peerconnectioninterface",
":mock_rtp", ":mock_rtp",
":mock_session_description_interface",
":mock_transformable_video_frame", ":mock_transformable_video_frame",
":mock_video_bitrate_allocator", ":mock_video_bitrate_allocator",
":mock_video_bitrate_allocator_factory", ":mock_video_bitrate_allocator_factory",
@ -1358,6 +1465,25 @@ if (rtc_include_tests) {
} }
} }
rtc_source_set("field_trials_registry") {
visibility = [ "*" ]
sources = [
"field_trials_registry.cc",
"field_trials_registry.h",
]
deps = [
":field_trials_view",
"../experiments:registered_field_trials",
"../rtc_base:checks",
"../rtc_base/containers:flat_set",
"../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/strings",
]
}
rtc_source_set("field_trials_view") { rtc_source_set("field_trials_view") {
visibility = [ "*" ] visibility = [ "*" ]
sources = [ "field_trials_view.h" ] sources = [ "field_trials_view.h" ]
@ -1378,10 +1504,26 @@ rtc_library("field_trials") {
"field_trials.h", "field_trials.h",
] ]
deps = [ deps = [
":field_trials_view", ":field_trials_registry",
"../rtc_base:checks", "../rtc_base:checks",
"../rtc_base/containers:flat_map", "../rtc_base/containers:flat_map",
"../system_wrappers:field_trial", "../system_wrappers:field_trial",
] ]
absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
} }
rtc_library("frame_transformer_factory") {
visibility = [ "*" ]
sources = [
"frame_transformer_factory.cc",
"frame_transformer_factory.h",
]
deps = [
":frame_transformer_interface",
":scoped_refptr",
"../modules/rtp_rtcp",
"../rtc_base:refcount",
"video:encoded_frame",
"video:video_frame_metadata",
]
}

View file

@ -11,6 +11,7 @@ include_rules = [
"-common_video", "-common_video",
"-data", "-data",
"-examples", "-examples",
"-experiments",
"-g3doc", "-g3doc",
"-ios", "-ios",
"-infra", "-infra",
@ -184,7 +185,7 @@ specific_include_rules = {
"+rtc_base/ref_count.h", "+rtc_base/ref_count.h",
], ],
"stats_types\.h": [ "legacy_stats_types\.h": [
"+rtc_base/ref_count.h", "+rtc_base/ref_count.h",
"+rtc_base/thread_checker.h", "+rtc_base/thread_checker.h",
], ],
@ -314,6 +315,10 @@ specific_include_rules = {
"+rtc_base/thread.h", "+rtc_base/thread.h",
], ],
"field_trials_registry\.h": [
"+rtc_base/containers/flat_set.h",
],
# .cc files in api/ should not be restricted in what they can #include, # .cc files in api/ should not be restricted in what they can #include,
# so we re-add all the top-level directories here. (That's because .h # so we re-add all the top-level directories here. (That's because .h
# files leak their #includes to whoever's #including them, but .cc files # files leak their #includes to whoever's #including them, but .cc files
@ -324,6 +329,7 @@ specific_include_rules = {
"+common_audio", "+common_audio",
"+common_video", "+common_video",
"+examples", "+examples",
"+experiments",
"+logging", "+logging",
"+media", "+media",
"+modules", "+modules",

View file

@ -59,7 +59,7 @@ struct RTC_EXPORT EchoCanceller3Config {
}; };
AlignmentMixing render_alignment_mixing = {false, true, 10000.f, true}; AlignmentMixing render_alignment_mixing = {false, true, 10000.f, true};
AlignmentMixing capture_alignment_mixing = {false, true, 10000.f, false}; AlignmentMixing capture_alignment_mixing = {false, true, 10000.f, false};
bool detect_pre_echo = false; bool detect_pre_echo = true;
} delay; } delay;
struct Filter { struct Filter {

View file

@ -62,7 +62,6 @@ rtc_library("builtin_audio_decoder_factory") {
"L16:audio_decoder_L16", "L16:audio_decoder_L16",
"g711:audio_decoder_g711", "g711:audio_decoder_g711",
"g722:audio_decoder_g722", "g722:audio_decoder_g722",
"isac:audio_decoder_isac",
] ]
defines = [] defines = []
if (rtc_include_ilbc) { if (rtc_include_ilbc) {
@ -95,7 +94,6 @@ rtc_library("builtin_audio_encoder_factory") {
"L16:audio_encoder_L16", "L16:audio_encoder_L16",
"g711:audio_encoder_g711", "g711:audio_encoder_g711",
"g722:audio_encoder_g722", "g722:audio_encoder_g722",
"isac:audio_encoder_isac",
] ]
defines = [] defines = []
if (rtc_include_ilbc) { if (rtc_include_ilbc) {

View file

@ -1,2 +1,3 @@
minyue@webrtc.org alessiob@webrtc.org
henrik.lundin@webrtc.org henrik.lundin@webrtc.org
jakobi@webrtc.org

View file

@ -20,7 +20,6 @@
#if WEBRTC_USE_BUILTIN_ILBC #if WEBRTC_USE_BUILTIN_ILBC
#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h" // nogncheck #include "api/audio_codecs/ilbc/audio_decoder_ilbc.h" // nogncheck
#endif #endif
#include "api/audio_codecs/isac/audio_decoder_isac.h"
#if WEBRTC_USE_BUILTIN_OPUS #if WEBRTC_USE_BUILTIN_OPUS
#include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h" #include "api/audio_codecs/opus/audio_decoder_multi_channel_opus.h"
#include "api/audio_codecs/opus/audio_decoder_opus.h" // nogncheck #include "api/audio_codecs/opus/audio_decoder_opus.h" // nogncheck
@ -57,7 +56,7 @@ rtc::scoped_refptr<AudioDecoderFactory> CreateBuiltinAudioDecoderFactory() {
AudioDecoderOpus, NotAdvertised<AudioDecoderMultiChannelOpus>, AudioDecoderOpus, NotAdvertised<AudioDecoderMultiChannelOpus>,
#endif #endif
AudioDecoderIsac, AudioDecoderG722, AudioDecoderG722,
#if WEBRTC_USE_BUILTIN_ILBC #if WEBRTC_USE_BUILTIN_ILBC
AudioDecoderIlbc, AudioDecoderIlbc,

View file

@ -20,7 +20,6 @@
#if WEBRTC_USE_BUILTIN_ILBC #if WEBRTC_USE_BUILTIN_ILBC
#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h" // nogncheck #include "api/audio_codecs/ilbc/audio_encoder_ilbc.h" // nogncheck
#endif #endif
#include "api/audio_codecs/isac/audio_encoder_isac.h"
#if WEBRTC_USE_BUILTIN_OPUS #if WEBRTC_USE_BUILTIN_OPUS
#include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h" #include "api/audio_codecs/opus/audio_encoder_multi_channel_opus.h"
#include "api/audio_codecs/opus/audio_encoder_opus.h" // nogncheck #include "api/audio_codecs/opus/audio_encoder_opus.h" // nogncheck
@ -63,7 +62,7 @@ rtc::scoped_refptr<AudioEncoderFactory> CreateBuiltinAudioEncoderFactory() {
AudioEncoderOpus, NotAdvertised<AudioEncoderMultiChannelOpus>, AudioEncoderOpus, NotAdvertised<AudioEncoderMultiChannelOpus>,
#endif #endif
AudioEncoderIsac, AudioEncoderG722, AudioEncoderG722,
#if WEBRTC_USE_BUILTIN_ILBC #if WEBRTC_USE_BUILTIN_ILBC
AudioEncoderIlbc, AudioEncoderIlbc,

View file

@ -1,135 +0,0 @@
# Copyright (c) 2017 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.
import("../../../webrtc.gni")
if (is_android) {
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
}
# The targets with _fix and _float suffixes unconditionally use the
# fixed-point and floating-point iSAC implementations, respectively.
# The targets without suffixes pick one of the implementations based
# on cleverly chosen criteria.
rtc_source_set("audio_encoder_isac") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
public = [ "audio_encoder_isac.h" ]
public_configs = [ ":isac_config" ]
if (current_cpu == "arm") {
deps = [ ":audio_encoder_isac_fix" ]
} else {
deps = [ ":audio_encoder_isac_float" ]
}
}
rtc_source_set("audio_decoder_isac") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
public = [ "audio_decoder_isac.h" ]
public_configs = [ ":isac_config" ]
if (current_cpu == "arm") {
deps = [ ":audio_decoder_isac_fix" ]
} else {
deps = [ ":audio_decoder_isac_float" ]
}
}
config("isac_config") {
visibility = [ ":*" ]
if (current_cpu == "arm") {
defines = [
"WEBRTC_USE_BUILTIN_ISAC_FIX=1",
"WEBRTC_USE_BUILTIN_ISAC_FLOAT=0",
]
} else {
defines = [
"WEBRTC_USE_BUILTIN_ISAC_FIX=0",
"WEBRTC_USE_BUILTIN_ISAC_FLOAT=1",
]
}
}
rtc_library("audio_encoder_isac_fix") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_encoder_isac_fix.cc",
"audio_encoder_isac_fix.h",
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:isac_fix",
"../../../rtc_base:stringutils",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("audio_decoder_isac_fix") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_decoder_isac_fix.cc",
"audio_decoder_isac_fix.h",
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:isac_fix",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("audio_encoder_isac_float") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_encoder_isac_float.cc",
"audio_encoder_isac_float.h",
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:isac",
"../../../rtc_base:stringutils",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("audio_decoder_isac_float") {
visibility = [ "*" ]
poisonous = [ "audio_codecs" ]
sources = [
"audio_decoder_isac_float.cc",
"audio_decoder_isac_float.h",
]
deps = [
"..:audio_codecs_api",
"../../../api:field_trials_view",
"../../../modules/audio_coding:isac",
"../../../rtc_base/system:rtc_export",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2017 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 API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_
#if WEBRTC_USE_BUILTIN_ISAC_FIX && !WEBRTC_USE_BUILTIN_ISAC_FLOAT
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h" // nogncheck
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT && !WEBRTC_USE_BUILTIN_ISAC_FIX
#include "api/audio_codecs/isac/audio_decoder_isac_float.h" // nogncheck
#else
#error "Must choose either fix or float"
#endif
namespace webrtc {
#if WEBRTC_USE_BUILTIN_ISAC_FIX
using AudioDecoderIsac = AudioDecoderIsacFix;
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
using AudioDecoderIsac = AudioDecoderIsacFloat;
#endif
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_H_

View file

@ -1,44 +0,0 @@
/*
* Copyright (c) 2017 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 "api/audio_codecs/isac/audio_decoder_isac_fix.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"
namespace webrtc {
absl::optional<AudioDecoderIsacFix::Config> AudioDecoderIsacFix::SdpToConfig(
const SdpAudioFormat& format) {
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
format.clockrate_hz == 16000 && format.num_channels == 1) {
return Config();
}
return absl::nullopt;
}
void AudioDecoderIsacFix::AppendSupportedDecoders(
std::vector<AudioCodecSpec>* specs) {
// RingRTC change to unused audio codecs
// specs->push_back({{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}});
}
std::unique_ptr<AudioDecoder> AudioDecoderIsacFix::MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
AudioDecoderIsacFixImpl::Config c;
c.sample_rate_hz = 16000;
return std::make_unique<AudioDecoderIsacFixImpl>(c);
}
} // namespace webrtc

View file

@ -1,40 +0,0 @@
/*
* Copyright (c) 2017 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 API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC decoder API (fixed-point implementation) for use as a template
// parameter to CreateAudioDecoderFactory<...>().
struct RTC_EXPORT AudioDecoderIsacFix {
struct Config {}; // Empty---no config values needed!
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FIX_H_

View file

@ -1,57 +0,0 @@
/*
* Copyright (c) 2017 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 "api/audio_codecs/isac/audio_decoder_isac_float.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"
namespace webrtc {
absl::optional<AudioDecoderIsacFloat::Config>
AudioDecoderIsacFloat::SdpToConfig(const SdpAudioFormat& format) {
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
(format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
format.num_channels == 1) {
Config config;
config.sample_rate_hz = format.clockrate_hz;
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
} else {
return absl::nullopt;
}
}
void AudioDecoderIsacFloat::AppendSupportedDecoders(
std::vector<AudioCodecSpec>* specs) {
// RingRTC change to unused audio codecs
// specs->push_back({{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}});
// specs->push_back({{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}});
}
std::unique_ptr<AudioDecoder> AudioDecoderIsacFloat::MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
AudioDecoderIsacFloatImpl::Config c;
c.sample_rate_hz = config.sample_rate_hz;
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return std::make_unique<AudioDecoderIsacFloatImpl>(c);
}
} // namespace webrtc

View file

@ -1,45 +0,0 @@
/*
* Copyright (c) 2017 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 API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC decoder API (floating-point implementation) for use as a template
// parameter to CreateAudioDecoderFactory<...>().
struct RTC_EXPORT AudioDecoderIsacFloat {
struct Config {
bool IsOk() const {
return sample_rate_hz == 16000 || sample_rate_hz == 32000;
}
int sample_rate_hz = 16000;
};
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
static std::unique_ptr<AudioDecoder> MakeAudioDecoder(
Config config,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_DECODER_ISAC_FLOAT_H_

View file

@ -1,32 +0,0 @@
/*
* Copyright (c) 2017 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 API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_
#if WEBRTC_USE_BUILTIN_ISAC_FIX && !WEBRTC_USE_BUILTIN_ISAC_FLOAT
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h" // nogncheck
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT && !WEBRTC_USE_BUILTIN_ISAC_FIX
#include "api/audio_codecs/isac/audio_encoder_isac_float.h" // nogncheck
#else
#error "Must choose either fix or float"
#endif
namespace webrtc {
#if WEBRTC_USE_BUILTIN_ISAC_FIX
using AudioEncoderIsac = AudioEncoderIsacFix;
#elif WEBRTC_USE_BUILTIN_ISAC_FLOAT
using AudioEncoderIsac = AudioEncoderIsacFloat;
#endif
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_H_

View file

@ -1,73 +0,0 @@
/*
* Copyright (c) 2017 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 "api/audio_codecs/isac/audio_encoder_isac_fix.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h"
#include "rtc_base/string_to_number.h"
namespace webrtc {
absl::optional<AudioEncoderIsacFix::Config> AudioEncoderIsacFix::SdpToConfig(
const SdpAudioFormat& format) {
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
format.clockrate_hz == 16000 && format.num_channels == 1) {
Config config;
const auto ptime_iter = format.parameters.find("ptime");
if (ptime_iter != format.parameters.end()) {
const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
if (ptime && *ptime >= 60) {
config.frame_size_ms = 60;
}
}
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
} else {
return absl::nullopt;
}
}
void AudioEncoderIsacFix::AppendSupportedEncoders(
std::vector<AudioCodecSpec>* specs) {
// RingRTC change to unused audio codecs
// const SdpAudioFormat fmt = {"ISAC", 16000, 1};
// const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
// specs->push_back({fmt, info});
}
AudioCodecInfo AudioEncoderIsacFix::QueryAudioEncoder(
AudioEncoderIsacFix::Config config) {
RTC_DCHECK(config.IsOk());
return {16000, 1, 32000, 10000, 32000};
}
std::unique_ptr<AudioEncoder> AudioEncoderIsacFix::MakeAudioEncoder(
AudioEncoderIsacFix::Config config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
AudioEncoderIsacFixImpl::Config c;
c.frame_size_ms = config.frame_size_ms;
c.bit_rate = config.bit_rate;
c.payload_type = payload_type;
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return std::make_unique<AudioEncoderIsacFixImpl>(c);
}
} // namespace webrtc

View file

@ -1,54 +0,0 @@
/*
* Copyright (c) 2017 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 API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC encoder API (fixed-point implementation) for use as a template
// parameter to CreateAudioEncoderFactory<...>().
struct RTC_EXPORT AudioEncoderIsacFix {
struct Config {
bool IsOk() const {
if (frame_size_ms != 30 && frame_size_ms != 60) {
return false;
}
if (bit_rate < 10000 || bit_rate > 32000) {
return false;
}
return true;
}
int frame_size_ms = 30;
int bit_rate = 32000; // Limit on short-term average bit rate, in bits/s.
};
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
static AudioCodecInfo QueryAudioEncoder(Config config);
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
Config config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FIX_H_

View file

@ -1,86 +0,0 @@
/*
* Copyright (c) 2017 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 "api/audio_codecs/isac/audio_encoder_isac_float.h"
#include <memory>
#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"
#include "rtc_base/string_to_number.h"
namespace webrtc {
absl::optional<AudioEncoderIsacFloat::Config>
AudioEncoderIsacFloat::SdpToConfig(const SdpAudioFormat& format) {
if (absl::EqualsIgnoreCase(format.name, "ISAC") &&
(format.clockrate_hz == 16000 || format.clockrate_hz == 32000) &&
format.num_channels == 1) {
Config config;
config.sample_rate_hz = format.clockrate_hz;
config.bit_rate = format.clockrate_hz == 16000 ? 32000 : 56000;
if (config.sample_rate_hz == 16000) {
// For sample rate 16 kHz, optionally use 60 ms frames, instead of the
// default 30 ms.
const auto ptime_iter = format.parameters.find("ptime");
if (ptime_iter != format.parameters.end()) {
const auto ptime = rtc::StringToNumber<int>(ptime_iter->second);
if (ptime && *ptime >= 60) {
config.frame_size_ms = 60;
}
}
}
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return absl::nullopt;
}
return config;
} else {
return absl::nullopt;
}
}
void AudioEncoderIsacFloat::AppendSupportedEncoders(
std::vector<AudioCodecSpec>* specs) {
// RingRTC change to unused audio codecs
// for (int sample_rate_hz : {16000, 32000}) {
// const SdpAudioFormat fmt = {"ISAC", sample_rate_hz, 1};
// const AudioCodecInfo info = QueryAudioEncoder(*SdpToConfig(fmt));
// specs->push_back({fmt, info});
// }
}
AudioCodecInfo AudioEncoderIsacFloat::QueryAudioEncoder(
const AudioEncoderIsacFloat::Config& config) {
RTC_DCHECK(config.IsOk());
constexpr int min_bitrate = 10000;
const int max_bitrate = config.sample_rate_hz == 16000 ? 32000 : 56000;
const int default_bitrate = max_bitrate;
return {config.sample_rate_hz, 1, default_bitrate, min_bitrate, max_bitrate};
}
std::unique_ptr<AudioEncoder> AudioEncoderIsacFloat::MakeAudioEncoder(
const AudioEncoderIsacFloat::Config& config,
int payload_type,
absl::optional<AudioCodecPairId> /*codec_pair_id*/,
const FieldTrialsView* field_trials) {
AudioEncoderIsacFloatImpl::Config c;
c.payload_type = payload_type;
c.sample_rate_hz = config.sample_rate_hz;
c.frame_size_ms = config.frame_size_ms;
c.bit_rate = config.bit_rate;
if (!config.IsOk()) {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
return std::make_unique<AudioEncoderIsacFloatImpl>(c);
}
} // namespace webrtc

View file

@ -1,68 +0,0 @@
/*
* Copyright (c) 2017 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 API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_
#define API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_
#include <memory>
#include <vector>
#include "absl/types/optional.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_format.h"
#include "api/field_trials_view.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// iSAC encoder API (floating-point implementation) for use as a template
// parameter to CreateAudioEncoderFactory<...>().
struct RTC_EXPORT AudioEncoderIsacFloat {
struct Config {
bool IsOk() const {
switch (sample_rate_hz) {
case 16000:
if (frame_size_ms != 30 && frame_size_ms != 60) {
return false;
}
if (bit_rate < 10000 || bit_rate > 32000) {
return false;
}
return true;
case 32000:
if (frame_size_ms != 30) {
return false;
}
if (bit_rate < 10000 || bit_rate > 56000) {
return false;
}
return true;
default:
return false;
}
}
int sample_rate_hz = 16000;
int frame_size_ms = 30;
int bit_rate = 32000; // Limit on short-term average bit rate, in bits/s.
};
static absl::optional<Config> SdpToConfig(const SdpAudioFormat& audio_format);
static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
static AudioCodecInfo QueryAudioEncoder(const Config& config);
static std::unique_ptr<AudioEncoder> MakeAudioEncoder(
const Config& config,
int payload_type,
absl::optional<AudioCodecPairId> codec_pair_id = absl::nullopt,
const FieldTrialsView* field_trials = nullptr);
};
} // namespace webrtc
#endif // API_AUDIO_CODECS_ISAC_AUDIO_ENCODER_ISAC_FLOAT_H_

View file

@ -32,10 +32,6 @@ if (rtc_include_tests) {
"../g722:audio_encoder_g722", "../g722:audio_encoder_g722",
"../ilbc:audio_decoder_ilbc", "../ilbc:audio_decoder_ilbc",
"../ilbc:audio_encoder_ilbc", "../ilbc:audio_encoder_ilbc",
"../isac:audio_decoder_isac_fix",
"../isac:audio_decoder_isac_float",
"../isac:audio_encoder_isac_fix",
"../isac:audio_encoder_isac_float",
"../opus:audio_decoder_opus", "../opus:audio_decoder_opus",
"../opus:audio_encoder_opus", "../opus:audio_encoder_opus",
] ]

View file

@ -16,8 +16,6 @@
#include "api/audio_codecs/g711/audio_decoder_g711.h" #include "api/audio_codecs/g711/audio_decoder_g711.h"
#include "api/audio_codecs/g722/audio_decoder_g722.h" #include "api/audio_codecs/g722/audio_decoder_g722.h"
#include "api/audio_codecs/ilbc/audio_decoder_ilbc.h" #include "api/audio_codecs/ilbc/audio_decoder_ilbc.h"
#include "api/audio_codecs/isac/audio_decoder_isac_fix.h"
#include "api/audio_codecs/isac/audio_decoder_isac_float.h"
#include "api/audio_codecs/opus/audio_decoder_opus.h" #include "api/audio_codecs/opus/audio_decoder_opus.h"
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -182,41 +180,6 @@ TEST(AudioDecoderFactoryTemplateTest, Ilbc) {
EXPECT_EQ(8000, dec->SampleRateHz()); EXPECT_EQ(8000, dec->SampleRateHz());
} }
TEST(AudioDecoderFactoryTemplateTest, IsacFix) {
auto factory = CreateAudioDecoderFactory<AudioDecoderIsacFix>();
EXPECT_THAT(factory->GetSupportedDecoders(),
::testing::ElementsAre(AudioCodecSpec{
{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}}));
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 16000, 2}));
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 16000, 1}));
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioDecoder({"isac", 8000, 1}, absl::nullopt));
auto dec = factory->MakeAudioDecoder({"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, dec);
EXPECT_EQ(16000, dec->SampleRateHz());
}
TEST(AudioDecoderFactoryTemplateTest, IsacFloat) {
auto factory = CreateAudioDecoderFactory<AudioDecoderIsacFloat>();
EXPECT_THAT(
factory->GetSupportedDecoders(),
::testing::ElementsAre(
AudioCodecSpec{{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}},
AudioCodecSpec{{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}}));
EXPECT_FALSE(factory->IsSupportedDecoder({"isac", 16000, 2}));
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 16000, 1}));
EXPECT_TRUE(factory->IsSupportedDecoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioDecoder({"isac", 8000, 1}, absl::nullopt));
auto dec1 = factory->MakeAudioDecoder({"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, dec1);
EXPECT_EQ(16000, dec1->SampleRateHz());
auto dec2 = factory->MakeAudioDecoder({"isac", 32000, 1}, absl::nullopt);
ASSERT_NE(nullptr, dec2);
EXPECT_EQ(32000, dec2->SampleRateHz());
}
TEST(AudioDecoderFactoryTemplateTest, L16) { TEST(AudioDecoderFactoryTemplateTest, L16) {
auto factory = CreateAudioDecoderFactory<AudioDecoderL16>(); auto factory = CreateAudioDecoderFactory<AudioDecoderL16>();
EXPECT_THAT( EXPECT_THAT(

View file

@ -16,8 +16,6 @@
#include "api/audio_codecs/g711/audio_encoder_g711.h" #include "api/audio_codecs/g711/audio_encoder_g711.h"
#include "api/audio_codecs/g722/audio_encoder_g722.h" #include "api/audio_codecs/g722/audio_encoder_g722.h"
#include "api/audio_codecs/ilbc/audio_encoder_ilbc.h" #include "api/audio_codecs/ilbc/audio_encoder_ilbc.h"
#include "api/audio_codecs/isac/audio_encoder_isac_fix.h"
#include "api/audio_codecs/isac/audio_encoder_isac_float.h"
#include "api/audio_codecs/opus/audio_encoder_opus.h" #include "api/audio_codecs/opus/audio_encoder_opus.h"
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -180,49 +178,6 @@ TEST(AudioEncoderFactoryTemplateTest, Ilbc) {
EXPECT_EQ(8000, enc->SampleRateHz()); EXPECT_EQ(8000, enc->SampleRateHz());
} }
TEST(AudioEncoderFactoryTemplateTest, IsacFix) {
auto factory = CreateAudioEncoderFactory<AudioEncoderIsacFix>();
EXPECT_THAT(factory->GetSupportedEncoders(),
::testing::ElementsAre(AudioCodecSpec{
{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}}));
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 16000, 2}));
EXPECT_EQ(AudioCodecInfo(16000, 1, 32000, 10000, 32000),
factory->QueryAudioEncoder({"isac", 16000, 1}));
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioEncoder(17, {"isac", 8000, 1}, absl::nullopt));
auto enc1 = factory->MakeAudioEncoder(17, {"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, enc1);
EXPECT_EQ(16000, enc1->SampleRateHz());
EXPECT_EQ(3u, enc1->Num10MsFramesInNextPacket());
auto enc2 = factory->MakeAudioEncoder(
17, {"isac", 16000, 1, {{"ptime", "60"}}}, absl::nullopt);
ASSERT_NE(nullptr, enc2);
EXPECT_EQ(6u, enc2->Num10MsFramesInNextPacket());
}
TEST(AudioEncoderFactoryTemplateTest, IsacFloat) {
auto factory = CreateAudioEncoderFactory<AudioEncoderIsacFloat>();
EXPECT_THAT(
factory->GetSupportedEncoders(),
::testing::ElementsAre(
AudioCodecSpec{{"ISAC", 16000, 1}, {16000, 1, 32000, 10000, 32000}},
AudioCodecSpec{{"ISAC", 32000, 1}, {32000, 1, 56000, 10000, 56000}}));
EXPECT_EQ(absl::nullopt, factory->QueryAudioEncoder({"isac", 16000, 2}));
EXPECT_EQ(AudioCodecInfo(16000, 1, 32000, 10000, 32000),
factory->QueryAudioEncoder({"isac", 16000, 1}));
EXPECT_EQ(AudioCodecInfo(32000, 1, 56000, 10000, 56000),
factory->QueryAudioEncoder({"isac", 32000, 1}));
EXPECT_EQ(nullptr,
factory->MakeAudioEncoder(17, {"isac", 8000, 1}, absl::nullopt));
auto enc1 = factory->MakeAudioEncoder(17, {"isac", 16000, 1}, absl::nullopt);
ASSERT_NE(nullptr, enc1);
EXPECT_EQ(16000, enc1->SampleRateHz());
auto enc2 = factory->MakeAudioEncoder(17, {"isac", 32000, 1}, absl::nullopt);
ASSERT_NE(nullptr, enc2);
EXPECT_EQ(32000, enc2->SampleRateHz());
}
TEST(AudioEncoderFactoryTemplateTest, L16) { TEST(AudioEncoderFactoryTemplateTest, L16) {
auto factory = CreateAudioEncoderFactory<AudioEncoderL16>(); auto factory = CreateAudioEncoderFactory<AudioEncoderL16>();
EXPECT_THAT( EXPECT_THAT(

View file

@ -22,6 +22,7 @@ Candidate::Candidate()
component_(0), component_(0),
priority_(0), priority_(0),
network_type_(rtc::ADAPTER_TYPE_UNKNOWN), network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
generation_(0), generation_(0),
network_id_(0), network_id_(0),
network_cost_(0) {} network_cost_(0) {}
@ -46,6 +47,7 @@ Candidate::Candidate(int component,
password_(password), password_(password),
type_(type), type_(type),
network_type_(rtc::ADAPTER_TYPE_UNKNOWN), network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
generation_(generation), generation_(generation),
foundation_(foundation), foundation_(foundation),
network_id_(network_id), network_id_(network_id),

View file

@ -25,6 +25,10 @@
namespace cricket { namespace cricket {
// TURN servers are limited to 32 in accordance with
// https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-iceservers
static constexpr size_t kMaxTurnServers = 32;
// Candidate for ICE based connection discovery. // Candidate for ICE based connection discovery.
// TODO(phoglund): remove things in here that are not needed in the public API. // TODO(phoglund): remove things in here that are not needed in the public API.

View file

@ -90,7 +90,7 @@ FieldTrials::~FieldTrials() {
} }
} }
std::string FieldTrials::Lookup(absl::string_view key) const { std::string FieldTrials::GetValue(absl::string_view key) const {
auto it = key_value_map_.find(std::string(key)); auto it = key_value_map_.find(std::string(key));
if (it != key_value_map_.end()) if (it != key_value_map_.end())
return it->second; return it->second;

View file

@ -15,7 +15,7 @@
#include <string> #include <string>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/field_trials_view.h" #include "api/field_trials_registry.h"
#include "rtc_base/containers/flat_map.h" #include "rtc_base/containers/flat_map.h"
namespace webrtc { namespace webrtc {
@ -34,7 +34,7 @@ namespace webrtc {
// NOTE: Creating multiple FieldTrials-object is currently prohibited // NOTE: Creating multiple FieldTrials-object is currently prohibited
// until we remove the global string (TODO(bugs.webrtc.org/10335)) // until we remove the global string (TODO(bugs.webrtc.org/10335))
// (unless using CreateNoGlobal): // (unless using CreateNoGlobal):
class FieldTrials : public FieldTrialsView { class FieldTrials : public FieldTrialsRegistry {
public: public:
explicit FieldTrials(const std::string& s); explicit FieldTrials(const std::string& s);
~FieldTrials(); ~FieldTrials();
@ -43,10 +43,11 @@ class FieldTrials : public FieldTrialsView {
// global variable (i.e can not be used for all parts of webrtc). // global variable (i.e can not be used for all parts of webrtc).
static std::unique_ptr<FieldTrials> CreateNoGlobal(const std::string& s); static std::unique_ptr<FieldTrials> CreateNoGlobal(const std::string& s);
std::string Lookup(absl::string_view key) const override;
private: private:
explicit FieldTrials(const std::string& s, bool); explicit FieldTrials(const std::string& s, bool);
std::string GetValue(absl::string_view key) const override;
const bool uses_global_; const bool uses_global_;
const std::string field_trial_string_; const std::string field_trial_string_;
const char* const previous_field_trial_string_; const char* const previous_field_trial_string_;

View file

@ -0,0 +1,31 @@
/*
* Copyright 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 "api/field_trials_registry.h"
#include <string>
#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "experiments/registered_field_trials.h"
#include "rtc_base/checks.h"
#include "rtc_base/containers/flat_set.h"
namespace webrtc {
std::string FieldTrialsRegistry::Lookup(absl::string_view key) const {
#if WEBRTC_STRICT_FIELD_TRIALS
RTC_DCHECK(absl::c_linear_search(kRegisteredFieldTrials, key) ||
test_keys_.contains(key))
<< key << " is not registered.";
#endif
return GetValue(key);
}
} // namespace webrtc

View file

@ -0,0 +1,54 @@
/*
* Copyright 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.
*/
#ifndef API_FIELD_TRIALS_REGISTRY_H_
#define API_FIELD_TRIALS_REGISTRY_H_
#include <string>
#include <utility>
#include "absl/strings/string_view.h"
#include "api/field_trials_view.h"
#include "rtc_base/containers/flat_set.h"
#include "rtc_base/system/rtc_export.h"
namespace webrtc {
// Abstract base class for a field trial registry that verifies that any looked
// up key has been pre-registered in accordance with `g3doc/field-trials.md`.
class RTC_EXPORT FieldTrialsRegistry : public FieldTrialsView {
public:
FieldTrialsRegistry() = default;
FieldTrialsRegistry(const FieldTrialsRegistry&) = default;
FieldTrialsRegistry& operator=(const FieldTrialsRegistry&) = default;
~FieldTrialsRegistry() override = default;
// Verifies that `key` is a registered field trial and then returns the
// configured value for `key` or an empty string if the field trial isn't
// configured.
std::string Lookup(absl::string_view key) const override;
// Register additional `keys` for testing. This should only be used for
// imaginary keys that are never used outside test code.
void RegisterKeysForTesting(flat_set<std::string> keys) {
test_keys_ = std::move(keys);
}
private:
virtual std::string GetValue(absl::string_view key) const = 0;
// Imaginary keys only used for testing.
flat_set<std::string> test_keys_;
};
} // namespace webrtc
#endif // API_FIELD_TRIALS_REGISTRY_H_

View file

@ -11,9 +11,13 @@
#include "api/field_trials.h" #include "api/field_trials.h"
#include <memory> #include <memory>
#include <utility>
#include "absl/strings/string_view.h"
#include "api/transport/field_trial_based_config.h" #include "api/transport/field_trial_based_config.h"
#include "rtc_base/containers/flat_set.h"
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
#include "test/field_trial.h"
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.h" #include "test/gtest.h"
@ -25,49 +29,50 @@ namespace webrtc {
namespace { namespace {
using ::testing::NotNull; using ::testing::NotNull;
using ::webrtc::field_trial::InitFieldTrialsFromString; using ::webrtc::field_trial::FieldTrialsAllowedInScopeForTesting;
using ::webrtc::test::ScopedFieldTrials;
class FieldTrialsTest : public testing::Test { TEST(FieldTrialsTest, EmptyStringHasNoEffect) {
protected: FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial"});
FieldTrialsTest() {
// Make sure global state is consistent between test runs.
InitFieldTrialsFromString(nullptr);
}
};
TEST_F(FieldTrialsTest, EmptyStringHasNoEffect) {
FieldTrials f(""); FieldTrials f("");
f.RegisterKeysForTesting({"MyCoolTrial"});
EXPECT_FALSE(f.IsEnabled("MyCoolTrial")); EXPECT_FALSE(f.IsEnabled("MyCoolTrial"));
EXPECT_FALSE(f.IsDisabled("MyCoolTrial")); EXPECT_FALSE(f.IsDisabled("MyCoolTrial"));
} }
TEST_F(FieldTrialsTest, EnabledDisabledMustBeFirstInValue) { TEST(FieldTrialsTest, EnabledDisabledMustBeFirstInValue) {
FieldTrials f( FieldTrials f(
"MyCoolTrial/EnabledFoo/" "MyCoolTrial/EnabledFoo/"
"MyUncoolTrial/DisabledBar/" "MyUncoolTrial/DisabledBar/"
"AnotherTrial/BazEnabled/"); "AnotherTrial/BazEnabled/");
f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial", "AnotherTrial"});
EXPECT_TRUE(f.IsEnabled("MyCoolTrial")); EXPECT_TRUE(f.IsEnabled("MyCoolTrial"));
EXPECT_TRUE(f.IsDisabled("MyUncoolTrial")); EXPECT_TRUE(f.IsDisabled("MyUncoolTrial"));
EXPECT_FALSE(f.IsEnabled("AnotherTrial")); EXPECT_FALSE(f.IsEnabled("AnotherTrial"));
} }
TEST_F(FieldTrialsTest, FieldTrialsDoesNotReadGlobalString) { TEST(FieldTrialsTest, FieldTrialsDoesNotReadGlobalString) {
static constexpr char s[] = "MyCoolTrial/Enabled/MyUncoolTrial/Disabled/"; FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"});
InitFieldTrialsFromString(s); ScopedFieldTrials g("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/");
FieldTrials f(""); FieldTrials f("");
f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial"});
EXPECT_FALSE(f.IsEnabled("MyCoolTrial")); EXPECT_FALSE(f.IsEnabled("MyCoolTrial"));
EXPECT_FALSE(f.IsDisabled("MyUncoolTrial")); EXPECT_FALSE(f.IsDisabled("MyUncoolTrial"));
} }
TEST_F(FieldTrialsTest, FieldTrialsWritesGlobalString) { TEST(FieldTrialsTest, FieldTrialsWritesGlobalString) {
FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"});
FieldTrials f("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/"); FieldTrials f("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/");
EXPECT_TRUE(webrtc::field_trial::IsEnabled("MyCoolTrial")); EXPECT_TRUE(webrtc::field_trial::IsEnabled("MyCoolTrial"));
EXPECT_TRUE(webrtc::field_trial::IsDisabled("MyUncoolTrial")); EXPECT_TRUE(webrtc::field_trial::IsDisabled("MyUncoolTrial"));
} }
TEST_F(FieldTrialsTest, FieldTrialsRestoresGlobalStringAfterDestruction) { TEST(FieldTrialsTest, FieldTrialsRestoresGlobalStringAfterDestruction) {
static constexpr char s[] = "SomeString/Enabled/"; static constexpr char s[] = "SomeString/Enabled/";
InitFieldTrialsFromString(s); ScopedFieldTrials g(s);
{ {
FieldTrials f("SomeOtherString/Enabled/"); FieldTrials f("SomeOtherString/Enabled/");
EXPECT_STREQ(webrtc::field_trial::GetFieldTrialString(), EXPECT_STREQ(webrtc::field_trial::GetFieldTrialString(),
@ -77,33 +82,38 @@ TEST_F(FieldTrialsTest, FieldTrialsRestoresGlobalStringAfterDestruction) {
} }
#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST_F(FieldTrialsTest, FieldTrialsDoesNotSupportSimultaneousInstances) { TEST(FieldTrialsTest, FieldTrialsDoesNotSupportSimultaneousInstances) {
FieldTrials f("SomeString/Enabled/"); FieldTrials f("SomeString/Enabled/");
RTC_EXPECT_DEATH(FieldTrials("SomeOtherString/Enabled/").Lookup("Whatever"), RTC_EXPECT_DEATH(FieldTrials("SomeOtherString/Enabled/").Lookup("Whatever"),
"Only one instance"); "Only one instance");
} }
#endif // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) #endif // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST_F(FieldTrialsTest, FieldTrialsSupportsSeparateInstances) { TEST(FieldTrialsTest, FieldTrialsSupportsSeparateInstances) {
{ FieldTrials f("SomeString/Enabled/"); } { FieldTrials f("SomeString/Enabled/"); }
{ FieldTrials f("SomeOtherString/Enabled/"); } { FieldTrials f("SomeOtherString/Enabled/"); }
} }
TEST_F(FieldTrialsTest, NonGlobalFieldTrialsInstanceDoesNotModifyGlobalString) { TEST(FieldTrialsTest, NonGlobalFieldTrialsInstanceDoesNotModifyGlobalString) {
FieldTrialsAllowedInScopeForTesting k({"SomeString"});
std::unique_ptr<FieldTrials> f = std::unique_ptr<FieldTrials> f =
FieldTrials::CreateNoGlobal("SomeString/Enabled/"); FieldTrials::CreateNoGlobal("SomeString/Enabled/");
ASSERT_THAT(f, NotNull()); ASSERT_THAT(f, NotNull());
f->RegisterKeysForTesting({"SomeString"});
EXPECT_TRUE(f->IsEnabled("SomeString")); EXPECT_TRUE(f->IsEnabled("SomeString"));
EXPECT_FALSE(webrtc::field_trial::IsEnabled("SomeString")); EXPECT_FALSE(webrtc::field_trial::IsEnabled("SomeString"));
} }
TEST_F(FieldTrialsTest, NonGlobalFieldTrialsSupportSimultaneousInstances) { TEST(FieldTrialsTest, NonGlobalFieldTrialsSupportSimultaneousInstances) {
std::unique_ptr<FieldTrials> f1 = std::unique_ptr<FieldTrials> f1 =
FieldTrials::CreateNoGlobal("SomeString/Enabled/"); FieldTrials::CreateNoGlobal("SomeString/Enabled/");
std::unique_ptr<FieldTrials> f2 = std::unique_ptr<FieldTrials> f2 =
FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/"); FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/");
ASSERT_THAT(f1, NotNull()); ASSERT_THAT(f1, NotNull());
ASSERT_THAT(f2, NotNull()); ASSERT_THAT(f2, NotNull());
f1->RegisterKeysForTesting({"SomeString", "SomeOtherString"});
f2->RegisterKeysForTesting({"SomeString", "SomeOtherString"});
EXPECT_TRUE(f1->IsEnabled("SomeString")); EXPECT_TRUE(f1->IsEnabled("SomeString"));
EXPECT_FALSE(f1->IsEnabled("SomeOtherString")); EXPECT_FALSE(f1->IsEnabled("SomeOtherString"));
@ -112,11 +122,14 @@ TEST_F(FieldTrialsTest, NonGlobalFieldTrialsSupportSimultaneousInstances) {
EXPECT_TRUE(f2->IsEnabled("SomeOtherString")); EXPECT_TRUE(f2->IsEnabled("SomeOtherString"));
} }
TEST_F(FieldTrialsTest, GlobalAndNonGlobalFieldTrialsAreDisjoint) { TEST(FieldTrialsTest, GlobalAndNonGlobalFieldTrialsAreDisjoint) {
FieldTrialsAllowedInScopeForTesting k({"SomeString", "SomeOtherString"});
FieldTrials f1("SomeString/Enabled/"); FieldTrials f1("SomeString/Enabled/");
std::unique_ptr<FieldTrials> f2 = std::unique_ptr<FieldTrials> f2 =
FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/"); FieldTrials::CreateNoGlobal("SomeOtherString/Enabled/");
ASSERT_THAT(f2, NotNull()); ASSERT_THAT(f2, NotNull());
f1.RegisterKeysForTesting({"SomeString", "SomeOtherString"});
f2->RegisterKeysForTesting({"SomeString", "SomeOtherString"});
EXPECT_TRUE(f1.IsEnabled("SomeString")); EXPECT_TRUE(f1.IsEnabled("SomeString"));
EXPECT_FALSE(f1.IsEnabled("SomeOtherString")); EXPECT_FALSE(f1.IsEnabled("SomeOtherString"));
@ -125,10 +138,12 @@ TEST_F(FieldTrialsTest, GlobalAndNonGlobalFieldTrialsAreDisjoint) {
EXPECT_TRUE(f2->IsEnabled("SomeOtherString")); EXPECT_TRUE(f2->IsEnabled("SomeOtherString"));
} }
TEST_F(FieldTrialsTest, FieldTrialBasedConfigReadsGlobalString) { TEST(FieldTrialsTest, FieldTrialBasedConfigReadsGlobalString) {
static constexpr char s[] = "MyCoolTrial/Enabled/MyUncoolTrial/Disabled/"; FieldTrialsAllowedInScopeForTesting k({"MyCoolTrial", "MyUncoolTrial"});
InitFieldTrialsFromString(s); ScopedFieldTrials g("MyCoolTrial/Enabled/MyUncoolTrial/Disabled/");
FieldTrialBasedConfig f; FieldTrialBasedConfig f;
f.RegisterKeysForTesting({"MyCoolTrial", "MyUncoolTrial"});
EXPECT_TRUE(f.IsEnabled("MyCoolTrial")); EXPECT_TRUE(f.IsEnabled("MyCoolTrial"));
EXPECT_TRUE(f.IsDisabled("MyUncoolTrial")); EXPECT_TRUE(f.IsDisabled("MyUncoolTrial"));
} }

View file

@ -17,15 +17,18 @@
namespace webrtc { namespace webrtc {
// An interface that provides a key-value mapping for configuring internal // An interface that provides the means to access field trials.
// details of WebRTC. Note that there's no guarantess that the meaning of a //
// particular key value mapping will be preserved over time and no announcements // Note that there are no guarantess that the meaning of a particular key-value
// will be made if they are changed. It's up to the library user to ensure that // mapping will be preserved over time and no announcements will be made if they
// the behavior does not break. // are changed. It's up to the library user to ensure that the behavior does not
// break.
class RTC_EXPORT FieldTrialsView { class RTC_EXPORT FieldTrialsView {
public: public:
virtual ~FieldTrialsView() = default; virtual ~FieldTrialsView() = default;
// The configured value for the given key. Defaults to an empty string.
// Returns the configured value for `key` or an empty string if the field
// trial isn't configured.
virtual std::string Lookup(absl::string_view key) const = 0; virtual std::string Lookup(absl::string_view key) const = 0;
bool IsEnabled(absl::string_view key) const { bool IsEnabled(absl::string_view key) const {

View file

@ -0,0 +1,33 @@
/*
* Copyright 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 "api/frame_transformer_factory.h"
#include "modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate.h"
namespace webrtc {
std::unique_ptr<TransformableVideoFrameInterface> CreateVideoSenderFrame() {
RTC_CHECK_NOTREACHED();
return nullptr;
}
std::unique_ptr<TransformableVideoFrameInterface> CreateVideoReceiverFrame() {
RTC_CHECK_NOTREACHED();
return nullptr;
}
std::unique_ptr<TransformableVideoFrameInterface> CloneVideoFrame(
TransformableVideoFrameInterface* original) {
// At the moment, only making sender frames from receiver frames is supported.
return CloneSenderVideoFrame(original);
}
} // namespace webrtc

View file

@ -0,0 +1,39 @@
/*
* Copyright 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.
*/
#ifndef API_FRAME_TRANSFORMER_FACTORY_H_
#define API_FRAME_TRANSFORMER_FACTORY_H_
#include <memory>
#include <vector>
#include "api/frame_transformer_interface.h"
#include "api/scoped_refptr.h"
#include "api/video/encoded_frame.h"
#include "api/video/video_frame_metadata.h"
// This file contains EXPERIMENTAL functions to create video frames from
// either an old video frame or directly from parameters.
// These functions will be used in Chrome functionality to manipulate
// encoded frames from Javascript.
namespace webrtc {
// TODO(bugs.webrtc.org/14708): Add the required parameters to these APIs.
std::unique_ptr<TransformableVideoFrameInterface> CreateVideoSenderFrame();
// TODO(bugs.webrtc.org/14708): Consider whether Receiver frames ever make sense
// to create.
std::unique_ptr<TransformableVideoFrameInterface> CreateVideoReceiverFrame();
// Creates a new frame with the same metadata as the original.
// The original can be a sender or receiver frame.
RTC_EXPORT std::unique_ptr<TransformableVideoFrameInterface> CloneVideoFrame(
TransformableVideoFrameInterface* original);
} // namespace webrtc
#endif // API_FRAME_TRANSFORMER_FACTORY_H_

View file

@ -8,7 +8,7 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "api/stats_types.h" #include "api/legacy_stats_types.h"
#include <string.h> #include <string.h>

View file

@ -11,8 +11,8 @@
// This file contains structures used for retrieving statistics from an ongoing // This file contains structures used for retrieving statistics from an ongoing
// libjingle session. // libjingle session.
#ifndef API_STATS_TYPES_H_ #ifndef API_LEGACY_STATS_TYPES_H_
#define API_STATS_TYPES_H_ #define API_LEGACY_STATS_TYPES_H_
#include <algorithm> #include <algorithm>
#include <list> #include <list>
@ -452,4 +452,4 @@ class StatsCollection {
} // namespace webrtc } // namespace webrtc
#endif // API_STATS_TYPES_H_ #endif // API_LEGACY_STATS_TYPES_H_

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -8,13 +8,12 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h" #include "api/metronome/metronome.h"
#include "modules/audio_coding/codecs/isac/audio_decoder_isac_t_impl.h"
namespace webrtc { namespace webrtc {
// Explicit instantiation: // TODO(crbug.com/1381982): Remove outdated methods.
template class AudioDecoderIsacT<IsacFix>; void Metronome::AddListener(TickListener* listener) {}
void Metronome::RemoveListener(TickListener* listener) {}
} // namespace webrtc } // namespace webrtc

View file

@ -17,44 +17,26 @@
namespace webrtc { namespace webrtc {
// The Metronome posts OnTick() on task queues provided by its listeners' task // The Metronome posts OnTick() calls requested with RequestCallOnNextTick.
// queue periodically. The metronome can be used as an alternative to using // The API is designed to be fully used from a single task queue. Scheduled
// PostDelayedTask on a thread or task queue for coalescing work and reducing // callbacks are executed on the same sequence as they were requested on. There
// the number of idle-wakeups. // are no features implemented for cancellation. When that's needed, use e.g.
// // ScopedTaskSafety from the client.
// Listeners can be added and removed from any sequence, but it is illegal to
// remove a listener from an OnTick invocation.
// //
// The metronome concept is still under experimentation, and may not be availble // The metronome concept is still under experimentation, and may not be availble
// in all platforms or applications. See https://crbug.com/1253787 for more // in all platforms or applications. See https://crbug.com/1253787 for more
// details. // details.
// //
// Metronome implementations must be thread-safe. // Metronome implementations must be thread-compatible.
class RTC_EXPORT Metronome { class RTC_EXPORT Metronome {
public: public:
class RTC_EXPORT TickListener {
public:
virtual ~TickListener() = default;
// OnTick is run on the task queue provided by OnTickTaskQueue each time the
// metronome ticks.
virtual void OnTick() = 0;
// The task queue that OnTick will run on. Must not be null.
virtual TaskQueueBase* OnTickTaskQueue() = 0;
};
virtual ~Metronome() = default; virtual ~Metronome() = default;
// Adds a tick listener to the metronome. Once this method has returned // Requests a call to `callback` on the next tick. Scheduled callbacks are
// OnTick will be invoked on each metronome tick. A listener may // executed on the same sequence as they were requested on. There are no
// only be added to the metronome once. // features for cancellation. When that's needed, use e.g. ScopedTaskSafety
virtual void AddListener(TickListener* listener) = 0; // from the client.
virtual void RequestCallOnNextTick(absl::AnyInvocable<void() &&> callback) {}
// Removes the tick listener from the metronome. Once this method has returned
// OnTick will never be called again. This method must not be called from
// within OnTick.
virtual void RemoveListener(TickListener* listener) = 0;
// Returns the current tick period of the metronome. // Returns the current tick period of the metronome.
virtual TimeDelta TickPeriod() const = 0; virtual TimeDelta TickPeriod() const = 0;

View file

@ -23,6 +23,7 @@ rtc_library("fake_metronome") {
"../../../rtc_base:rtc_task_queue", "../../../rtc_base:rtc_task_queue",
"../../../rtc_base/synchronization:mutex", "../../../rtc_base/synchronization:mutex",
"../../../rtc_base/task_utils:repeating_task", "../../../rtc_base/task_utils:repeating_task",
"../../../test:test_support",
"../../task_queue", "../../task_queue",
"../../units:time_delta", "../../units:time_delta",
] ]

View file

@ -10,8 +10,12 @@
#include "api/metronome/test/fake_metronome.h" #include "api/metronome/test/fake_metronome.h"
#include <utility>
#include <vector>
#include "api/priority.h" #include "api/priority.h"
#include "api/sequence_checker.h" #include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h" #include "api/task_queue/task_queue_factory.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "rtc_base/event.h" #include "rtc_base/event.h"
@ -22,12 +26,9 @@ namespace webrtc::test {
ForcedTickMetronome::ForcedTickMetronome(TimeDelta tick_period) ForcedTickMetronome::ForcedTickMetronome(TimeDelta tick_period)
: tick_period_(tick_period) {} : tick_period_(tick_period) {}
void ForcedTickMetronome::AddListener(TickListener* listener) { void ForcedTickMetronome::RequestCallOnNextTick(
listeners_.insert(listener); absl::AnyInvocable<void() &&> callback) {
} callbacks_.push_back(std::move(callback));
void ForcedTickMetronome::RemoveListener(TickListener* listener) {
listeners_.erase(listener);
} }
TimeDelta ForcedTickMetronome::TickPeriod() const { TimeDelta ForcedTickMetronome::TickPeriod() const {
@ -35,55 +36,35 @@ TimeDelta ForcedTickMetronome::TickPeriod() const {
} }
size_t ForcedTickMetronome::NumListeners() { size_t ForcedTickMetronome::NumListeners() {
return listeners_.size(); return callbacks_.size();
} }
void ForcedTickMetronome::Tick() { void ForcedTickMetronome::Tick() {
for (auto* listener : listeners_) { std::vector<absl::AnyInvocable<void() &&>> callbacks;
listener->OnTickTaskQueue()->PostTask([listener] { listener->OnTick(); }); callbacks_.swap(callbacks);
for (auto& callback : callbacks)
std::move(callback)();
}
FakeMetronome::FakeMetronome(TimeDelta tick_period)
: tick_period_(tick_period) {}
void FakeMetronome::RequestCallOnNextTick(
absl::AnyInvocable<void() &&> callback) {
TaskQueueBase* current = TaskQueueBase::Current();
callbacks_.push_back(std::move(callback));
if (callbacks_.size() == 1) {
current->PostDelayedTask(
[this] {
std::vector<absl::AnyInvocable<void() &&>> callbacks;
callbacks_.swap(callbacks);
for (auto& callback : callbacks)
std::move(callback)();
},
tick_period_);
} }
} }
FakeMetronome::FakeMetronome(TaskQueueFactory* factory, TimeDelta tick_period)
: tick_period_(tick_period),
queue_(factory->CreateTaskQueue("MetronomeQueue",
TaskQueueFactory::Priority::HIGH)) {}
FakeMetronome::~FakeMetronome() {
RTC_DCHECK(listeners_.empty());
}
void FakeMetronome::AddListener(TickListener* listener) {
MutexLock lock(&mutex_);
listeners_.insert(listener);
if (!started_) {
tick_task_ = RepeatingTaskHandle::Start(queue_.Get(), [this] {
MutexLock lock(&mutex_);
// Stop if empty.
if (listeners_.empty())
return TimeDelta::PlusInfinity();
for (auto* listener : listeners_) {
listener->OnTickTaskQueue()->PostTask(
[listener] { listener->OnTick(); });
}
return tick_period_;
});
started_ = true;
}
}
void FakeMetronome::RemoveListener(TickListener* listener) {
MutexLock lock(&mutex_);
listeners_.erase(listener);
}
void FakeMetronome::Stop() {
MutexLock lock(&mutex_);
RTC_DCHECK(listeners_.empty());
if (started_)
queue_.PostTask([this] { tick_task_.Stop(); });
}
TimeDelta FakeMetronome::TickPeriod() const { TimeDelta FakeMetronome::TickPeriod() const {
return tick_period_; return tick_period_;
} }

View file

@ -13,6 +13,7 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include <vector>
#include "api/metronome/metronome.h" #include "api/metronome/metronome.h"
#include "api/task_queue/task_queue_base.h" #include "api/task_queue/task_queue_base.h"
@ -36,13 +37,12 @@ class ForcedTickMetronome : public Metronome {
size_t NumListeners(); size_t NumListeners();
// Metronome implementation. // Metronome implementation.
void AddListener(TickListener* listener) override; void RequestCallOnNextTick(absl::AnyInvocable<void() &&> callback) override;
void RemoveListener(TickListener* listener) override;
TimeDelta TickPeriod() const override; TimeDelta TickPeriod() const override;
private: private:
const TimeDelta tick_period_; const TimeDelta tick_period_;
std::set<TickListener*> listeners_; std::vector<absl::AnyInvocable<void() &&>> callbacks_;
}; };
// FakeMetronome is a metronome that ticks based on a repeating task at the // FakeMetronome is a metronome that ticks based on a repeating task at the
@ -53,23 +53,15 @@ class ForcedTickMetronome : public Metronome {
// on the proper task queue. // on the proper task queue.
class FakeMetronome : public Metronome { class FakeMetronome : public Metronome {
public: public:
FakeMetronome(TaskQueueFactory* factory, TimeDelta tick_period); explicit FakeMetronome(TimeDelta tick_period);
~FakeMetronome() override;
// Metronome implementation. // Metronome implementation.
void AddListener(TickListener* listener) override; void RequestCallOnNextTick(absl::AnyInvocable<void() &&> callback) override;
void RemoveListener(TickListener* listener) override;
TimeDelta TickPeriod() const override; TimeDelta TickPeriod() const override;
void Stop();
private: private:
const TimeDelta tick_period_; const TimeDelta tick_period_;
RepeatingTaskHandle tick_task_; std::vector<absl::AnyInvocable<void() &&>> callbacks_;
bool started_ RTC_GUARDED_BY(mutex_) = false;
std::set<TickListener*> listeners_ RTC_GUARDED_BY(mutex_);
Mutex mutex_;
rtc::TaskQueue queue_;
}; };
} // namespace webrtc::test } // namespace webrtc::test

View file

@ -128,7 +128,7 @@ class NetEq {
std::string ToString() const; std::string ToString() const;
int sample_rate_hz = 16000; // Initial value. Will change with input data. int sample_rate_hz = 48000; // Initial value. Will change with input data.
bool enable_post_decode_vad = false; bool enable_post_decode_vad = false;
size_t max_packets_in_buffer = 200; size_t max_packets_in_buffer = 200;
int max_delay_ms = 0; int max_delay_ms = 0;

View file

@ -95,6 +95,7 @@
#include "api/ice_gatherer_interface.h" #include "api/ice_gatherer_interface.h"
#include "api/ice_transport_interface.h" #include "api/ice_transport_interface.h"
#include "api/jsep.h" #include "api/jsep.h"
#include "api/legacy_stats_types.h"
#include "api/media_stream_interface.h" #include "api/media_stream_interface.h"
#include "api/media_types.h" #include "api/media_types.h"
#include "api/metronome/metronome.h" #include "api/metronome/metronome.h"
@ -113,7 +114,6 @@
#include "api/set_local_description_observer_interface.h" #include "api/set_local_description_observer_interface.h"
#include "api/set_remote_description_observer_interface.h" #include "api/set_remote_description_observer_interface.h"
#include "api/stats/rtc_stats_collector_callback.h" #include "api/stats/rtc_stats_collector_callback.h"
#include "api/stats_types.h"
#include "api/task_queue/task_queue_factory.h" #include "api/task_queue/task_queue_factory.h"
#include "api/transport/bitrate_settings.h" #include "api/transport/bitrate_settings.h"
#include "api/transport/enums.h" #include "api/transport/enums.h"
@ -434,11 +434,6 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface {
// default will be used. // default will be used.
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// If set to true, don't gather IPv6 ICE candidates.
// TODO(https://crbug.com/1315576): Remove the ability to set it in Chromium
// and delete this flag.
bool disable_ipv6 = false;
// If set to true, don't gather IPv6 ICE candidates on Wi-Fi. // If set to true, don't gather IPv6 ICE candidates on Wi-Fi.
// Only intended to be used on specific devices. Certain phones disable IPv6 // Only intended to be used on specific devices. Certain phones disable IPv6
// when the screen is turned off and it would be better to just disable the // when the screen is turned off and it would be better to just disable the
@ -702,6 +697,9 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface {
PortAllocatorConfig port_allocator_config; PortAllocatorConfig port_allocator_config;
// The burst interval of the pacer, see TaskQueuePacedSender constructor.
absl::optional<TimeDelta> pacer_burst_interval;
// //
// Don't forget to update operator== if adding something. // Don't forget to update operator== if adding something.
// //
@ -813,6 +811,16 @@ class RTC_EXPORT PeerConnectionInterface : public rtc::RefCountInterface {
rtc::scoped_refptr<MediaStreamTrackInterface> track, rtc::scoped_refptr<MediaStreamTrackInterface> track,
const std::vector<std::string>& stream_ids) = 0; const std::vector<std::string>& stream_ids) = 0;
// Add a new MediaStreamTrack as above, but with an additional parameter,
// `init_send_encodings` : initial RtpEncodingParameters for RtpSender,
// similar to init_send_encodings in RtpTransceiverInit.
// Note that a new transceiver will always be created.
//
virtual RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> AddTrack(
rtc::scoped_refptr<MediaStreamTrackInterface> track,
const std::vector<std::string>& stream_ids,
const std::vector<RtpEncodingParameters>& init_send_encodings) = 0;
// Removes the connection between a MediaStreamTrack and the PeerConnection. // Removes the connection between a MediaStreamTrack and the PeerConnection.
// Stops sending on the RtpSender and marks the // Stops sending on the RtpSender and marks the
// corresponding RtpTransceiver direction as no longer sending. // corresponding RtpTransceiver direction as no longer sending.

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. * Copyright 2022 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -8,13 +8,15 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h" #include "api/rtp_sender_interface.h"
#include "modules/audio_coding/codecs/isac/audio_encoder_isac_t_impl.h" #include "rtc_base/checks.h"
namespace webrtc { namespace webrtc {
// Explicit instantiation: void RtpSenderInterface::SetParametersAsync(const RtpParameters& parameters,
template class AudioEncoderIsacT<IsacFix>; SetParametersCallback callback) {
RTC_DCHECK_NOTREACHED() << "Default implementation called";
}
} // namespace webrtc } // namespace webrtc

View file

@ -18,6 +18,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "absl/functional/any_invocable.h"
#include "api/crypto/frame_encryptor_interface.h" #include "api/crypto/frame_encryptor_interface.h"
#include "api/dtls_transport_interface.h" #include "api/dtls_transport_interface.h"
#include "api/dtmf_sender_interface.h" #include "api/dtmf_sender_interface.h"
@ -33,6 +34,8 @@
namespace webrtc { namespace webrtc {
using SetParametersCallback = absl::AnyInvocable<void(RTCError) &&>;
class RTC_EXPORT RtpSenderInterface : public rtc::RefCountInterface { class RTC_EXPORT RtpSenderInterface : public rtc::RefCountInterface {
public: public:
// Returns true if successful in setting the track. // Returns true if successful in setting the track.
@ -79,6 +82,8 @@ class RTC_EXPORT RtpSenderInterface : public rtc::RefCountInterface {
// rtpparameters.h // rtpparameters.h
// The encodings are in increasing quality order for simulcast. // The encodings are in increasing quality order for simulcast.
virtual RTCError SetParameters(const RtpParameters& parameters) = 0; virtual RTCError SetParameters(const RtpParameters& parameters) = 0;
virtual void SetParametersAsync(const RtpParameters& parameters,
SetParametersCallback callback);
// Returns null for a video sender. // Returns null for a video sender.
virtual rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const = 0; virtual rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const = 0;
@ -104,6 +109,11 @@ class RTC_EXPORT RtpSenderInterface : public rtc::RefCountInterface {
std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface> std::unique_ptr<VideoEncoderFactory::EncoderSelectorInterface>
encoder_selector) = 0; encoder_selector) = 0;
// TODO(crbug.com/1354101): make pure virtual again after Chrome roll.
virtual RTCError GenerateKeyFrame(const std::vector<std::string>& rids) {
return RTCError::OK();
}
protected: protected:
~RtpSenderInterface() override = default; ~RtpSenderInterface() override = default;
}; };

View file

@ -20,6 +20,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "absl/types/optional.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/system/rtc_export.h" #include "rtc_base/system/rtc_export.h"
#include "rtc_base/system/rtc_export_template.h" #include "rtc_base/system/rtc_export_template.h"
@ -260,7 +261,7 @@ class RTCStatsMemberInterface {
virtual Type type() const = 0; virtual Type type() const = 0;
virtual bool is_sequence() const = 0; virtual bool is_sequence() const = 0;
virtual bool is_string() const = 0; virtual bool is_string() const = 0;
bool is_defined() const { return is_defined_; } virtual bool is_defined() const = 0;
// Is this part of the stats spec? Used so that chromium can easily filter // Is this part of the stats spec? Used so that chromium can easily filter
// out anything unstandardized. // out anything unstandardized.
virtual bool is_standardized() const = 0; virtual bool is_standardized() const = 0;
@ -296,13 +297,11 @@ class RTCStatsMemberInterface {
} }
protected: protected:
RTCStatsMemberInterface(const char* name, bool is_defined) explicit RTCStatsMemberInterface(const char* name) : name_(name) {}
: name_(name), is_defined_(is_defined) {}
virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0; virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0;
const char* const name_; const char* const name_;
bool is_defined_;
}; };
// Template implementation of `RTCStatsMemberInterface`. // Template implementation of `RTCStatsMemberInterface`.
@ -312,70 +311,58 @@ template <typename T>
class RTCStatsMember : public RTCStatsMemberInterface { class RTCStatsMember : public RTCStatsMemberInterface {
public: public:
explicit RTCStatsMember(const char* name) explicit RTCStatsMember(const char* name)
: RTCStatsMemberInterface(name, : RTCStatsMemberInterface(name), value_() {}
/*is_defined=*/false),
value_() {}
RTCStatsMember(const char* name, const T& value) RTCStatsMember(const char* name, const T& value)
: RTCStatsMemberInterface(name, : RTCStatsMemberInterface(name), value_(value) {}
/*is_defined=*/true),
value_(value) {}
RTCStatsMember(const char* name, T&& value) RTCStatsMember(const char* name, T&& value)
: RTCStatsMemberInterface(name, : RTCStatsMemberInterface(name), value_(std::move(value)) {}
/*is_defined=*/true), explicit RTCStatsMember(const RTCStatsMember<T>& other)
value_(std::move(value)) {} : RTCStatsMemberInterface(other.name_), value_(other.value_) {}
RTCStatsMember(const RTCStatsMember<T>& other) explicit RTCStatsMember(RTCStatsMember<T>&& other)
: RTCStatsMemberInterface(other.name_, other.is_defined_), : RTCStatsMemberInterface(other.name_), value_(std::move(other.value_)) {}
value_(other.value_) {}
RTCStatsMember(RTCStatsMember<T>&& other)
: RTCStatsMemberInterface(other.name_, other.is_defined_),
value_(std::move(other.value_)) {}
static Type StaticType(); static Type StaticType();
Type type() const override { return StaticType(); } Type type() const override { return StaticType(); }
bool is_sequence() const override; bool is_sequence() const override;
bool is_string() const override; bool is_string() const override;
bool is_defined() const override { return value_.has_value(); }
bool is_standardized() const override { return true; } bool is_standardized() const override { return true; }
std::string ValueToString() const override; std::string ValueToString() const override;
std::string ValueToJson() const override; std::string ValueToJson() const override;
template <typename U> template <typename U>
inline T ValueOrDefault(U default_value) const { inline T ValueOrDefault(U default_value) const {
if (is_defined()) { return value_.value_or(default_value);
return *(*this);
}
return default_value;
} }
// Assignment operators. // Assignment operators.
T& operator=(const T& value) { T& operator=(const T& value) {
value_ = value; value_ = value;
is_defined_ = true; return value_.value();
return value_;
} }
T& operator=(const T&& value) { T& operator=(const T&& value) {
value_ = std::move(value); value_ = std::move(value);
is_defined_ = true; return value_.value();
return value_;
} }
// Value getters. // Value getters.
T& operator*() { T& operator*() {
RTC_DCHECK(is_defined_); RTC_DCHECK(value_);
return value_; return *value_;
} }
const T& operator*() const { const T& operator*() const {
RTC_DCHECK(is_defined_); RTC_DCHECK(value_);
return value_; return *value_;
} }
// Value getters, arrow operator. // Value getters, arrow operator.
T* operator->() { T* operator->() {
RTC_DCHECK(is_defined_); RTC_DCHECK(value_);
return &value_; return &(*value_);
} }
const T* operator->() const { const T* operator->() const {
RTC_DCHECK(is_defined_); RTC_DCHECK(value_);
return &value_; return &(*value_);
} }
protected: protected:
@ -386,15 +373,11 @@ class RTCStatsMember : public RTCStatsMemberInterface {
return false; return false;
const RTCStatsMember<T>& other_t = const RTCStatsMember<T>& other_t =
static_cast<const RTCStatsMember<T>&>(other); static_cast<const RTCStatsMember<T>&>(other);
if (!is_defined_)
return !other_t.is_defined();
if (!other.is_defined())
return false;
return value_ == other_t.value_; return value_ == other_t.value_;
} }
private: private:
T value_; absl::optional<T> value_;
}; };
namespace rtc_stats_internal { namespace rtc_stats_internal {

View file

@ -222,6 +222,8 @@ class RTC_EXPORT RTCIceCandidatePairStats final : public RTCStats {
RTCStatsMember<uint64_t> consent_requests_sent; RTCStatsMember<uint64_t> consent_requests_sent;
RTCStatsMember<uint64_t> packets_discarded_on_send; RTCStatsMember<uint64_t> packets_discarded_on_send;
RTCStatsMember<uint64_t> bytes_discarded_on_send; RTCStatsMember<uint64_t> bytes_discarded_on_send;
RTCStatsMember<double> last_packet_received_timestamp;
RTCStatsMember<double> last_packet_sent_timestamp;
}; };
// https://w3c.github.io/webrtc-stats/#icecandidate-dict* // https://w3c.github.io/webrtc-stats/#icecandidate-dict*
@ -286,35 +288,36 @@ class RTC_EXPORT RTCRemoteIceCandidateStats final
const char* type() const override; const char* type() const override;
}; };
// https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats // TODO(https://crbug.com/webrtc/14419): Delete this class, it's deprecated.
// TODO(https://crbug.com/webrtc/14172): Deprecate and remove. class RTC_EXPORT DEPRECATED_RTCMediaStreamStats final : public RTCStats {
class RTC_EXPORT RTCMediaStreamStats final : public RTCStats {
public: public:
WEBRTC_RTCSTATS_DECL(); WEBRTC_RTCSTATS_DECL();
RTCMediaStreamStats(const std::string& id, int64_t timestamp_us); DEPRECATED_RTCMediaStreamStats(const std::string& id, int64_t timestamp_us);
RTCMediaStreamStats(std::string&& id, int64_t timestamp_us); DEPRECATED_RTCMediaStreamStats(std::string&& id, int64_t timestamp_us);
RTCMediaStreamStats(const RTCMediaStreamStats& other); DEPRECATED_RTCMediaStreamStats(const DEPRECATED_RTCMediaStreamStats& other);
~RTCMediaStreamStats() override; ~DEPRECATED_RTCMediaStreamStats() override;
RTCStatsMember<std::string> stream_identifier; RTCStatsMember<std::string> stream_identifier;
RTCStatsMember<std::vector<std::string>> track_ids; RTCStatsMember<std::vector<std::string>> track_ids;
}; };
using RTCMediaStreamStats [[deprecated("bugs.webrtc.org/14419")]] =
DEPRECATED_RTCMediaStreamStats;
// TODO(https://crbug.com/webrtc/14175): Deprecate and remove in favor of // TODO(https://crbug.com/webrtc/14175): Delete this class, it's deprecated.
// RTCMediaSourceStats/RTCOutboundRtpStreamStats and RTCInboundRtpStreamStats. class RTC_EXPORT DEPRECATED_RTCMediaStreamTrackStats final : public RTCStats {
class RTC_EXPORT RTCMediaStreamTrackStats final : public RTCStats {
public: public:
WEBRTC_RTCSTATS_DECL(); WEBRTC_RTCSTATS_DECL();
RTCMediaStreamTrackStats(const std::string& id, DEPRECATED_RTCMediaStreamTrackStats(const std::string& id,
int64_t timestamp_us, int64_t timestamp_us,
const char* kind); const char* kind);
RTCMediaStreamTrackStats(std::string&& id, DEPRECATED_RTCMediaStreamTrackStats(std::string&& id,
int64_t timestamp_us, int64_t timestamp_us,
const char* kind); const char* kind);
RTCMediaStreamTrackStats(const RTCMediaStreamTrackStats& other); DEPRECATED_RTCMediaStreamTrackStats(
~RTCMediaStreamTrackStats() override; const DEPRECATED_RTCMediaStreamTrackStats& other);
~DEPRECATED_RTCMediaStreamTrackStats() override;
RTCStatsMember<std::string> track_identifier; RTCStatsMember<std::string> track_identifier;
RTCStatsMember<std::string> media_source_id; RTCStatsMember<std::string> media_source_id;
@ -347,22 +350,9 @@ class RTC_EXPORT RTCMediaStreamTrackStats final : public RTCStats {
RTCStatsMember<uint64_t> concealment_events; RTCStatsMember<uint64_t> concealment_events;
RTCStatsMember<uint64_t> inserted_samples_for_deceleration; RTCStatsMember<uint64_t> inserted_samples_for_deceleration;
RTCStatsMember<uint64_t> removed_samples_for_acceleration; RTCStatsMember<uint64_t> removed_samples_for_acceleration;
// TODO(crbug.com/webrtc/14524): These metrics have been moved, delete them.
RTCNonStandardStatsMember<uint64_t> jitter_buffer_flushes;
RTCNonStandardStatsMember<uint64_t> delayed_packet_outage_samples;
RTCNonStandardStatsMember<double> relative_packet_arrival_delay;
RTCNonStandardStatsMember<uint32_t> interruption_count;
RTCNonStandardStatsMember<double> total_interruption_duration;
// Non-standard video-only members.
// https://w3c.github.io/webrtc-provisional-stats/#dom-rtcvideoreceiverstats
RTCNonStandardStatsMember<double> total_frames_duration;
RTCNonStandardStatsMember<double> sum_squared_frame_durations;
// TODO(crbug.com/webrtc/14521): These metrics have been moved, delete them.
RTCNonStandardStatsMember<uint32_t> freeze_count;
RTCNonStandardStatsMember<uint32_t> pause_count;
RTCNonStandardStatsMember<double> total_freezes_duration;
RTCNonStandardStatsMember<double> total_pauses_duration;
}; };
using RTCMediaStreamTrackStats [[deprecated("bugs.webrtc.org/14175")]] =
DEPRECATED_RTCMediaStreamTrackStats;
// https://w3c.github.io/webrtc-stats/#pcstats-dict* // https://w3c.github.io/webrtc-stats/#pcstats-dict*
class RTC_EXPORT RTCPeerConnectionStats final : public RTCStats { class RTC_EXPORT RTCPeerConnectionStats final : public RTCStats {
@ -479,9 +469,8 @@ class RTC_EXPORT RTCInboundRTPStreamStats final
RTCStatsMember<uint32_t> frames_dropped; RTCStatsMember<uint32_t> frames_dropped;
RTCStatsMember<double> total_decode_time; RTCStatsMember<double> total_decode_time;
RTCStatsMember<double> total_processing_delay; RTCStatsMember<double> total_processing_delay;
// TODO(https://crbug.com/webrtc/13986): standardize RTCStatsMember<double> total_assembly_time;
RTCNonStandardStatsMember<double> total_assembly_time; RTCStatsMember<uint32_t> frames_assembled_from_multiple_packets;
RTCNonStandardStatsMember<uint32_t> frames_assembled_from_multiple_packets;
RTCStatsMember<double> total_inter_frame_delay; RTCStatsMember<double> total_inter_frame_delay;
RTCStatsMember<double> total_squared_inter_frame_delay; RTCStatsMember<double> total_squared_inter_frame_delay;
RTCStatsMember<uint32_t> pause_count; RTCStatsMember<uint32_t> pause_count;
@ -495,7 +484,9 @@ class RTC_EXPORT RTCInboundRTPStreamStats final
RTCStatsMember<double> estimated_playout_timestamp; RTCStatsMember<double> estimated_playout_timestamp;
// Only implemented for video. // Only implemented for video.
// TODO(https://crbug.com/webrtc/14178): Also implement for audio. // TODO(https://crbug.com/webrtc/14178): Also implement for audio.
RTCStatsMember<std::string> decoder_implementation; RTCRestrictedStatsMember<std::string,
StatExposureCriteria::kHardwareCapability>
decoder_implementation;
// FIR and PLI counts are only defined for |kind == "video"|. // FIR and PLI counts are only defined for |kind == "video"|.
RTCStatsMember<uint32_t> fir_count; RTCStatsMember<uint32_t> fir_count;
RTCStatsMember<uint32_t> pli_count; RTCStatsMember<uint32_t> pli_count;
@ -508,6 +499,8 @@ class RTC_EXPORT RTCInboundRTPStreamStats final
// TimingFrameInfo::ToString(). // TimingFrameInfo::ToString().
// TODO(https://crbug.com/webrtc/14586): Unship or standardize this metric. // TODO(https://crbug.com/webrtc/14586): Unship or standardize this metric.
RTCStatsMember<std::string> goog_timing_frame_info; RTCStatsMember<std::string> goog_timing_frame_info;
RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>
power_efficient_decoder;
// Non-standard audio metrics. // Non-standard audio metrics.
RTCNonStandardStatsMember<uint64_t> jitter_buffer_flushes; RTCNonStandardStatsMember<uint64_t> jitter_buffer_flushes;
RTCNonStandardStatsMember<uint64_t> delayed_packet_outage_samples; RTCNonStandardStatsMember<uint64_t> delayed_packet_outage_samples;
@ -548,8 +541,6 @@ class RTC_EXPORT RTCOutboundRTPStreamStats final : public RTCRTPStreamStats {
RTCStatsMember<double> frames_per_second; RTCStatsMember<double> frames_per_second;
RTCStatsMember<uint32_t> frames_sent; RTCStatsMember<uint32_t> frames_sent;
RTCStatsMember<uint32_t> huge_frames_sent; RTCStatsMember<uint32_t> huge_frames_sent;
// TODO(https://crbug.com/webrtc/10635): This is only implemented for video;
// implement it for audio as well.
RTCStatsMember<double> total_packet_send_delay; RTCStatsMember<double> total_packet_send_delay;
// Enum type RTCQualityLimitationReason // Enum type RTCQualityLimitationReason
RTCStatsMember<std::string> quality_limitation_reason; RTCStatsMember<std::string> quality_limitation_reason;
@ -560,13 +551,18 @@ class RTC_EXPORT RTCOutboundRTPStreamStats final : public RTCRTPStreamStats {
RTCStatsMember<std::string> content_type; RTCStatsMember<std::string> content_type;
// Only implemented for video. // Only implemented for video.
// TODO(https://crbug.com/webrtc/14178): Implement for audio as well. // TODO(https://crbug.com/webrtc/14178): Implement for audio as well.
RTCStatsMember<std::string> encoder_implementation; RTCRestrictedStatsMember<std::string,
StatExposureCriteria::kHardwareCapability>
encoder_implementation;
// FIR and PLI counts are only defined for |kind == "video"|. // FIR and PLI counts are only defined for |kind == "video"|.
RTCStatsMember<uint32_t> fir_count; RTCStatsMember<uint32_t> fir_count;
RTCStatsMember<uint32_t> pli_count; RTCStatsMember<uint32_t> pli_count;
RTCStatsMember<uint32_t> nack_count; RTCStatsMember<uint32_t> nack_count;
RTCStatsMember<uint64_t> qp_sum; RTCStatsMember<uint64_t> qp_sum;
RTCStatsMember<bool> active; RTCStatsMember<bool> active;
RTCRestrictedStatsMember<bool, StatExposureCriteria::kHardwareCapability>
power_efficient_encoder;
RTCStatsMember<std::string> scalability_mode;
}; };
// https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict* // https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*

View file

@ -42,6 +42,7 @@
#include "api/test/mock_rtp_transceiver.h" #include "api/test/mock_rtp_transceiver.h"
#include "api/test/mock_rtpreceiver.h" #include "api/test/mock_rtpreceiver.h"
#include "api/test/mock_rtpsender.h" #include "api/test/mock_rtpsender.h"
#include "api/test/mock_session_description_interface.h"
#include "api/test/mock_transformable_video_frame.h" #include "api/test/mock_transformable_video_frame.h"
#include "api/test/mock_video_bitrate_allocator.h" #include "api/test/mock_video_bitrate_allocator.h"
#include "api/test/mock_video_bitrate_allocator_factory.h" #include "api/test/mock_video_bitrate_allocator_factory.h"

View file

@ -18,8 +18,10 @@
namespace webrtc { namespace webrtc {
std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager( std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager(
TimeMode mode) { TimeMode time_mode,
return std::make_unique<test::NetworkEmulationManagerImpl>(mode); EmulatedNetworkStatsGatheringMode stats_gathering_mode) {
return std::make_unique<test::NetworkEmulationManagerImpl>(
time_mode, stats_gathering_mode);
} }
} // namespace webrtc } // namespace webrtc

View file

@ -19,7 +19,9 @@ namespace webrtc {
// Returns a non-null NetworkEmulationManager instance. // Returns a non-null NetworkEmulationManager instance.
std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager( std::unique_ptr<NetworkEmulationManager> CreateNetworkEmulationManager(
TimeMode mode = TimeMode::kRealTime); TimeMode time_mode = TimeMode::kRealTime,
EmulatedNetworkStatsGatheringMode stats_gathering_mode =
EmulatedNetworkStatsGatheringMode::kDefault);
} // namespace webrtc } // namespace webrtc

View file

@ -14,18 +14,13 @@
#include <vector> #include <vector>
#include "api/test/create_frame_generator.h" #include "api/test/create_frame_generator.h"
#include "api/test/peerconnection_quality_test_fixture.h" #include "api/test/pclf/media_configuration.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "test/testsupport/file_utils.h" #include "test/testsupport/file_utils.h"
namespace webrtc { namespace webrtc {
namespace webrtc_pc_e2e { namespace webrtc_pc_e2e {
using VideoConfig =
::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig;
using ScreenShareConfig = ::webrtc::webrtc_pc_e2e::
PeerConnectionE2EQualityTestFixture::ScreenShareConfig;
void ValidateScreenShareConfig(const VideoConfig& video_config, void ValidateScreenShareConfig(const VideoConfig& video_config,
const ScreenShareConfig& screen_share_config) { const ScreenShareConfig& screen_share_config) {
if (screen_share_config.slides_yuv_file_names.empty()) { if (screen_share_config.slides_yuv_file_names.empty()) {

View file

@ -15,7 +15,7 @@
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "api/test/frame_generator_interface.h" #include "api/test/frame_generator_interface.h"
#include "api/test/peerconnection_quality_test_fixture.h" #include "api/test/pclf/media_configuration.h"
namespace webrtc { namespace webrtc {
namespace webrtc_pc_e2e { namespace webrtc_pc_e2e {
@ -25,19 +25,18 @@ namespace webrtc_pc_e2e {
// FrameGeneratorInterface::OutputType::I420. video_config specifies frame // FrameGeneratorInterface::OutputType::I420. video_config specifies frame
// weight and height. // weight and height.
std::unique_ptr<test::FrameGeneratorInterface> CreateSquareFrameGenerator( std::unique_ptr<test::FrameGeneratorInterface> CreateSquareFrameGenerator(
const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config, const VideoConfig& video_config,
absl::optional<test::FrameGeneratorInterface::OutputType> type); absl::optional<test::FrameGeneratorInterface::OutputType> type);
// Creates a frame generator that plays frames from the yuv file. // Creates a frame generator that plays frames from the yuv file.
std::unique_ptr<test::FrameGeneratorInterface> CreateFromYuvFileFrameGenerator( std::unique_ptr<test::FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config, const VideoConfig& video_config,
std::string filename); std::string filename);
// Creates a proper frame generator for testing screen sharing. // Creates a proper frame generator for testing screen sharing.
std::unique_ptr<test::FrameGeneratorInterface> CreateScreenShareFrameGenerator( std::unique_ptr<test::FrameGeneratorInterface> CreateScreenShareFrameGenerator(
const PeerConnectionE2EQualityTestFixture::VideoConfig& video_config, const VideoConfig& video_config,
const PeerConnectionE2EQualityTestFixture::ScreenShareConfig& const ScreenShareConfig& screen_share_config);
screen_share_config);
} // namespace webrtc_pc_e2e } // namespace webrtc_pc_e2e
} // namespace webrtc } // namespace webrtc

View file

@ -0,0 +1,27 @@
/*
* 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 "api/test/create_video_codec_tester.h"
#include <memory>
#include <utility>
#include "api/test/video_codec_tester.h"
#include "modules/video_coding/codecs/test/video_codec_tester_impl.h"
namespace webrtc {
namespace test {
std::unique_ptr<VideoCodecTester> CreateVideoCodecTester() {
return std::make_unique<VideoCodecTesterImpl>();
}
} // namespace test
} // namespace webrtc

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -8,13 +8,19 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h" #ifndef API_TEST_CREATE_VIDEO_CODEC_TESTER_H_
#define API_TEST_CREATE_VIDEO_CODEC_TESTER_H_
#include "modules/audio_coding/codecs/isac/audio_decoder_isac_t_impl.h" #include <memory>
#include "api/test/video_codec_tester.h"
namespace webrtc { namespace webrtc {
namespace test {
// Explicit instantiation: std::unique_ptr<VideoCodecTester> CreateVideoCodecTester();
template class AudioDecoderIsacT<IsacFloat>;
} // namespace test
} // namespace webrtc } // namespace webrtc
#endif // API_TEST_CREATE_VIDEO_CODEC_TESTER_H_

View file

@ -18,7 +18,6 @@ group("metrics") {
":metrics_accumulator", ":metrics_accumulator",
":metrics_exporter", ":metrics_exporter",
":metrics_logger", ":metrics_logger",
":metrics_logger_and_exporter",
":stdout_metrics_exporter", ":stdout_metrics_exporter",
] ]
} }
@ -30,7 +29,6 @@ if (rtc_include_tests) {
deps = [ deps = [
":global_metrics_logger_and_exporter_test", ":global_metrics_logger_and_exporter_test",
":metrics_accumulator_test", ":metrics_accumulator_test",
":metrics_logger_and_exporter_test",
":metrics_logger_test", ":metrics_logger_test",
":print_result_proxy_metrics_exporter_test", ":print_result_proxy_metrics_exporter_test",
":stdout_metrics_exporter_test", ":stdout_metrics_exporter_test",
@ -176,29 +174,6 @@ rtc_library("print_result_proxy_metrics_exporter") {
] ]
} }
rtc_library("metrics_logger_and_exporter") {
visibility = [ "*" ]
sources = [
"metrics_logger_and_exporter.cc",
"metrics_logger_and_exporter.h",
]
deps = [
":metric",
":metrics_exporter",
":metrics_logger",
"../../../rtc_base:checks",
"../../../rtc_base:logging",
"../../../rtc_base/synchronization:mutex",
"../../../system_wrappers",
"../../numerics",
]
absl_deps = [
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("global_metrics_logger_and_exporter") { rtc_library("global_metrics_logger_and_exporter") {
visibility = [ "*" ] visibility = [ "*" ]
sources = [ sources = [
@ -208,7 +183,6 @@ rtc_library("global_metrics_logger_and_exporter") {
deps = [ deps = [
":metrics_exporter", ":metrics_exporter",
":metrics_logger", ":metrics_logger",
":metrics_logger_and_exporter",
"../../../rtc_base:checks", "../../../rtc_base:checks",
"../../../system_wrappers", "../../../system_wrappers",
] ]
@ -262,20 +236,6 @@ if (rtc_include_tests) {
] ]
} }
rtc_library("metrics_logger_and_exporter_test") {
testonly = true
sources = [ "metrics_logger_and_exporter_test.cc" ]
deps = [
":metric",
":metrics_exporter",
":metrics_logger_and_exporter",
"../../../system_wrappers",
"../../../test:test_support",
"../../numerics",
]
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
}
rtc_library("global_metrics_logger_and_exporter_test") { rtc_library("global_metrics_logger_and_exporter_test") {
testonly = true testonly = true
sources = [ "global_metrics_logger_and_exporter_test.cc" ] sources = [ "global_metrics_logger_and_exporter_test.cc" ]
@ -284,7 +244,6 @@ if (rtc_include_tests) {
":metric", ":metric",
":metrics_exporter", ":metrics_exporter",
":metrics_logger", ":metrics_logger",
":metrics_logger_and_exporter",
"../../../system_wrappers", "../../../system_wrappers",
"../../../test:test_support", "../../../test:test_support",
] ]

View file

@ -15,7 +15,6 @@
#include "api/test/metrics/metrics_exporter.h" #include "api/test/metrics/metrics_exporter.h"
#include "api/test/metrics/metrics_logger.h" #include "api/test/metrics/metrics_logger.h"
#include "api/test/metrics/metrics_logger_and_exporter.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "system_wrappers/include/clock.h" #include "system_wrappers/include/clock.h"

View file

@ -15,7 +15,7 @@
#include <vector> #include <vector>
#include "api/test/metrics/metrics_exporter.h" #include "api/test/metrics/metrics_exporter.h"
#include "api/test/metrics/metrics_logger_and_exporter.h" #include "api/test/metrics/metrics_logger.h"
namespace webrtc { namespace webrtc {
namespace test { namespace test {

View file

@ -1,129 +0,0 @@
/*
* 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 "api/test/metrics/metrics_logger_and_exporter.h"
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/numerics/samples_stats_counter.h"
#include "api/test/metrics/metric.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/synchronization/mutex.h"
namespace webrtc {
namespace test {
namespace {
Metric::Stats ToStats(const SamplesStatsCounter& values) {
if (values.IsEmpty()) {
return Metric::Stats();
}
return Metric::Stats{.mean = values.GetAverage(),
.stddev = values.GetStandardDeviation(),
.min = values.GetMin(),
.max = values.GetMax()};
}
} // namespace
MetricsLoggerAndExporter::~MetricsLoggerAndExporter() {
bool export_result = Export();
if (crash_on_export_failure_) {
RTC_CHECK(export_result);
} else {
RTC_LOG(LS_ERROR) << "One of exporters failed to export collected metrics";
}
}
void MetricsLoggerAndExporter::LogSingleValueMetric(
absl::string_view name,
absl::string_view test_case_name,
double value,
Unit unit,
ImprovementDirection improvement_direction,
std::map<std::string, std::string> metadata) {
MutexLock lock(&mutex_);
metrics_.push_back(Metric{
.name = std::string(name),
.unit = unit,
.improvement_direction = improvement_direction,
.test_case = std::string(test_case_name),
.metric_metadata = std::move(metadata),
.time_series =
Metric::TimeSeries{.samples = std::vector{Metric::TimeSeries::Sample{
.timestamp = Now(), .value = value}}},
.stats = Metric::Stats{
.mean = value, .stddev = absl::nullopt, .min = value, .max = value}});
}
void MetricsLoggerAndExporter::LogMetric(
absl::string_view name,
absl::string_view test_case_name,
const SamplesStatsCounter& values,
Unit unit,
ImprovementDirection improvement_direction,
std::map<std::string, std::string> metadata) {
MutexLock lock(&mutex_);
Metric::TimeSeries time_series;
for (const SamplesStatsCounter::StatsSample& sample :
values.GetTimedSamples()) {
time_series.samples.push_back(
Metric::TimeSeries::Sample{.timestamp = sample.time,
.value = sample.value,
.sample_metadata = sample.metadata});
}
metrics_.push_back(Metric{.name = std::string(name),
.unit = unit,
.improvement_direction = improvement_direction,
.test_case = std::string(test_case_name),
.metric_metadata = std::move(metadata),
.time_series = std::move(time_series),
.stats = ToStats(values)});
}
void MetricsLoggerAndExporter::LogMetric(
absl::string_view name,
absl::string_view test_case_name,
const Metric::Stats& metric_stats,
Unit unit,
ImprovementDirection improvement_direction,
std::map<std::string, std::string> metadata) {
MutexLock lock(&mutex_);
metrics_.push_back(Metric{.name = std::string(name),
.unit = unit,
.improvement_direction = improvement_direction,
.test_case = std::string(test_case_name),
.metric_metadata = std::move(metadata),
.time_series = Metric::TimeSeries{.samples = {}},
.stats = std::move(metric_stats)});
}
Timestamp MetricsLoggerAndExporter::Now() {
return clock_->CurrentTime();
}
bool MetricsLoggerAndExporter::Export() {
MutexLock lock(&mutex_);
bool success = true;
for (auto& exporter : exporters_) {
bool export_result = exporter->Export(metrics_);
success = success && export_result;
}
return success;
}
} // namespace test
} // namespace webrtc

View file

@ -1,96 +0,0 @@
/*
* 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.
*/
#ifndef API_TEST_METRICS_METRICS_LOGGER_AND_EXPORTER_H_
#define API_TEST_METRICS_METRICS_LOGGER_AND_EXPORTER_H_
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/numerics/samples_stats_counter.h"
#include "api/test/metrics/metric.h"
#include "api/test/metrics/metrics_exporter.h"
#include "api/test/metrics/metrics_logger.h"
#include "rtc_base/synchronization/mutex.h"
#include "system_wrappers/include/clock.h"
namespace webrtc {
namespace test {
// Combines metrics logging and exporting to provide simple API to automatically
// export metrics at the end of the scope.
class MetricsLoggerAndExporter : public MetricsLogger {
public:
// `crash_on_export_failure` - makes MetricsLoggerAndExporter to crash if
// any of exporters failed to export data.
MetricsLoggerAndExporter(
webrtc::Clock* clock,
std::vector<std::unique_ptr<MetricsExporter>> exporters,
bool crash_on_export_failure = true)
: clock_(clock),
crash_on_export_failure_(crash_on_export_failure),
exporters_(std::move(exporters)) {}
~MetricsLoggerAndExporter() override;
// Adds a metric with a single value.
// `metadata` - metric's level metadata to add.
void LogSingleValueMetric(
absl::string_view name,
absl::string_view test_case_name,
double value,
Unit unit,
ImprovementDirection improvement_direction,
std::map<std::string, std::string> metadata = {}) override;
// Adds metrics with a time series created based on the provided `values`.
// `metadata` - metric's level metadata to add.
void LogMetric(absl::string_view name,
absl::string_view test_case_name,
const SamplesStatsCounter& values,
Unit unit,
ImprovementDirection improvement_direction,
std::map<std::string, std::string> metadata = {}) override;
// Adds metric with a time series with only stats object and without actual
// collected values.
// `metadata` - metric's level metadata to add.
void LogMetric(absl::string_view name,
absl::string_view test_case_name,
const Metric::Stats& metric_stats,
Unit unit,
ImprovementDirection improvement_direction,
std::map<std::string, std::string> metadata = {}) override;
// Returns all metrics collected by this logger.
std::vector<Metric> GetCollectedMetrics() const override {
MutexLock lock(&mutex_);
return metrics_;
}
private:
webrtc::Timestamp Now();
bool Export();
webrtc::Clock* const clock_;
const bool crash_on_export_failure_;
mutable Mutex mutex_;
std::vector<Metric> metrics_ RTC_GUARDED_BY(mutex_);
std::vector<std::unique_ptr<MetricsExporter>> exporters_;
};
} // namespace test
} // namespace webrtc
#endif // API_TEST_METRICS_METRICS_LOGGER_AND_EXPORTER_H_

View file

@ -1,361 +0,0 @@
/*
* 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 "api/test/metrics/metrics_logger_and_exporter.h"
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "absl/types/optional.h"
#include "api/numerics/samples_stats_counter.h"
#include "api/test/metrics/metric.h"
#include "api/test/metrics/metrics_exporter.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
namespace {
using ::testing::Eq;
using ::testing::IsEmpty;
std::map<std::string, std::string> DefaultMetadata() {
return std::map<std::string, std::string>{{"key", "value"}};
}
struct TestMetricsExporterFactory {
public:
std::unique_ptr<MetricsExporter> CreateExporter() {
return std::make_unique<TestMetricsExporter>(this, /*export_result=*/true);
}
std::unique_ptr<MetricsExporter> CreateFailureExporter() {
return std::make_unique<TestMetricsExporter>(this, /*export_result=*/false);
}
std::vector<Metric> exported_metrics;
private:
class TestMetricsExporter : public MetricsExporter {
public:
TestMetricsExporter(TestMetricsExporterFactory* factory, bool export_result)
: factory_(factory), export_result_(export_result) {}
~TestMetricsExporter() override = default;
bool Export(rtc::ArrayView<const Metric> metrics) override {
factory_->exported_metrics =
std::vector<Metric>(metrics.begin(), metrics.end());
return export_result_;
}
TestMetricsExporterFactory* factory_;
bool export_result_;
};
};
TEST(MetricsLoggerAndExporterTest, LogSingleValueMetricRecordsMetric) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
logger.LogSingleValueMetric(
"metric_name", "test_case_name",
/*value=*/10, Unit::kMilliseconds,
ImprovementDirection::kBiggerIsBetter,
std::map<std::string, std::string>{{"key", "value"}});
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(1lu));
const Metric& metric = metrics[0];
EXPECT_THAT(metric.name, Eq("metric_name"));
EXPECT_THAT(metric.test_case, Eq("test_case_name"));
EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
EXPECT_THAT(metric.improvement_direction,
Eq(ImprovementDirection::kBiggerIsBetter));
EXPECT_THAT(metric.metric_metadata,
Eq(std::map<std::string, std::string>{{"key", "value"}}));
ASSERT_THAT(metric.time_series.samples.size(), Eq(1lu));
EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
Eq(std::map<std::string, std::string>{}));
ASSERT_THAT(metric.stats.mean, absl::optional<double>(10.0));
ASSERT_THAT(metric.stats.stddev, absl::nullopt);
ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
ASSERT_THAT(metric.stats.max, absl::optional<double>(10.0));
}
TEST(MetricsLoggerAndExporterTest,
LogMetricWithSamplesStatsCounterRecordsMetric) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
SamplesStatsCounter values;
values.AddSample(SamplesStatsCounter::StatsSample{
.value = 10,
.time = Clock::GetRealTimeClock()->CurrentTime(),
.metadata =
std::map<std::string, std::string>{{"point_key1", "value1"}}});
values.AddSample(SamplesStatsCounter::StatsSample{
.value = 20,
.time = Clock::GetRealTimeClock()->CurrentTime(),
.metadata =
std::map<std::string, std::string>{{"point_key2", "value2"}}});
logger.LogMetric("metric_name", "test_case_name", values,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
std::map<std::string, std::string>{{"key", "value"}});
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(1lu));
const Metric& metric = metrics[0];
EXPECT_THAT(metric.name, Eq("metric_name"));
EXPECT_THAT(metric.test_case, Eq("test_case_name"));
EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
EXPECT_THAT(metric.improvement_direction,
Eq(ImprovementDirection::kBiggerIsBetter));
EXPECT_THAT(metric.metric_metadata,
Eq(std::map<std::string, std::string>{{"key", "value"}}));
ASSERT_THAT(metric.time_series.samples.size(), Eq(2lu));
EXPECT_THAT(metric.time_series.samples[0].value, Eq(10.0));
EXPECT_THAT(metric.time_series.samples[0].sample_metadata,
Eq(std::map<std::string, std::string>{{"point_key1", "value1"}}));
EXPECT_THAT(metric.time_series.samples[1].value, Eq(20.0));
EXPECT_THAT(metric.time_series.samples[1].sample_metadata,
Eq(std::map<std::string, std::string>{{"point_key2", "value2"}}));
ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
}
TEST(MetricsLoggerAndExporterTest,
LogMetricWithEmptySamplesStatsCounterRecordsEmptyMetric) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
SamplesStatsCounter values;
logger.LogMetric("metric_name", "test_case_name", values, Unit::kUnitless,
ImprovementDirection::kBiggerIsBetter, DefaultMetadata());
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(1lu));
EXPECT_THAT(metrics[0].name, Eq("metric_name"));
EXPECT_THAT(metrics[0].test_case, Eq("test_case_name"));
EXPECT_THAT(metrics[0].time_series.samples, IsEmpty());
ASSERT_THAT(metrics[0].stats.mean, Eq(absl::nullopt));
ASSERT_THAT(metrics[0].stats.stddev, Eq(absl::nullopt));
ASSERT_THAT(metrics[0].stats.min, Eq(absl::nullopt));
ASSERT_THAT(metrics[0].stats.max, Eq(absl::nullopt));
}
TEST(MetricsLoggerAndExporterTest, LogMetricWithStatsRecordsMetric) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
Metric::Stats metric_stats{.mean = 15, .stddev = 5, .min = 10, .max = 20};
logger.LogMetric("metric_name", "test_case_name", metric_stats,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
std::map<std::string, std::string>{{"key", "value"}});
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(1lu));
const Metric& metric = metrics[0];
EXPECT_THAT(metric.name, Eq("metric_name"));
EXPECT_THAT(metric.test_case, Eq("test_case_name"));
EXPECT_THAT(metric.unit, Eq(Unit::kMilliseconds));
EXPECT_THAT(metric.improvement_direction,
Eq(ImprovementDirection::kBiggerIsBetter));
EXPECT_THAT(metric.metric_metadata,
Eq(std::map<std::string, std::string>{{"key", "value"}}));
ASSERT_THAT(metric.time_series.samples.size(), Eq(0lu));
ASSERT_THAT(metric.stats.mean, absl::optional<double>(15.0));
ASSERT_THAT(metric.stats.stddev, absl::optional<double>(5.0));
ASSERT_THAT(metric.stats.min, absl::optional<double>(10.0));
ASSERT_THAT(metric.stats.max, absl::optional<double>(20.0));
}
TEST(MetricsLoggerAndExporterTest, LogSingleValueMetricRecordsMultipleMetrics) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
logger.LogSingleValueMetric("metric_name1", "test_case_name1",
/*value=*/10, Unit::kMilliseconds,
ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
logger.LogSingleValueMetric("metric_name2", "test_case_name2",
/*value=*/10, Unit::kMilliseconds,
ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(2lu));
EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
}
TEST(MetricsLoggerAndExporterTest,
LogMetricWithSamplesStatsCounterRecordsMultipleMetrics) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
SamplesStatsCounter values;
values.AddSample(SamplesStatsCounter::StatsSample{
.value = 10,
.time = Clock::GetRealTimeClock()->CurrentTime(),
.metadata = DefaultMetadata()});
values.AddSample(SamplesStatsCounter::StatsSample{
.value = 20,
.time = Clock::GetRealTimeClock()->CurrentTime(),
.metadata = DefaultMetadata()});
logger.LogMetric("metric_name1", "test_case_name1", values,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
logger.LogMetric("metric_name2", "test_case_name2", values,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(2lu));
EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
}
TEST(MetricsLoggerAndExporterTest, LogMetricWithStatsRecordsMultipleMetrics) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
Metric::Stats metric_stats{.mean = 15, .stddev = 5, .min = 10, .max = 20};
logger.LogMetric("metric_name1", "test_case_name1", metric_stats,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
logger.LogMetric("metric_name2", "test_case_name2", metric_stats,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(2lu));
EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
}
TEST(MetricsLoggerAndExporterTest,
LogMetricThroughtAllMethodsAccumulateAllMetrics) {
TestMetricsExporterFactory exporter_factory;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters));
SamplesStatsCounter values;
values.AddSample(SamplesStatsCounter::StatsSample{
.value = 10,
.time = Clock::GetRealTimeClock()->CurrentTime(),
.metadata = DefaultMetadata()});
values.AddSample(SamplesStatsCounter::StatsSample{
.value = 20,
.time = Clock::GetRealTimeClock()->CurrentTime(),
.metadata = DefaultMetadata()});
Metric::Stats metric_stats{.mean = 15, .stddev = 5, .min = 10, .max = 20};
logger.LogSingleValueMetric("metric_name1", "test_case_name1",
/*value=*/10, Unit::kMilliseconds,
ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
logger.LogMetric("metric_name2", "test_case_name2", values,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
logger.LogMetric("metric_name3", "test_case_name3", metric_stats,
Unit::kMilliseconds, ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
}
std::vector<Metric> metrics = exporter_factory.exported_metrics;
ASSERT_THAT(metrics.size(), Eq(3lu));
EXPECT_THAT(metrics[0].name, Eq("metric_name1"));
EXPECT_THAT(metrics[0].test_case, Eq("test_case_name1"));
EXPECT_THAT(metrics[1].name, Eq("metric_name2"));
EXPECT_THAT(metrics[1].test_case, Eq("test_case_name2"));
EXPECT_THAT(metrics[2].name, Eq("metric_name3"));
EXPECT_THAT(metrics[2].test_case, Eq("test_case_name3"));
}
TEST(MetricsLoggerAndExporterTest,
OneFailedExporterDoesNotPreventExportToOthers) {
TestMetricsExporterFactory exporter_factory1;
TestMetricsExporterFactory exporter_factory2;
TestMetricsExporterFactory exporter_factory3;
{
std::vector<std::unique_ptr<MetricsExporter>> exporters;
exporters.push_back(exporter_factory1.CreateExporter());
exporters.push_back(exporter_factory2.CreateFailureExporter());
exporters.push_back(exporter_factory3.CreateExporter());
MetricsLoggerAndExporter logger(Clock::GetRealTimeClock(),
std::move(exporters),
/*crash_on_export_failure=*/false);
logger.LogSingleValueMetric("metric_name", "test_case_name",
/*value=*/10, Unit::kMilliseconds,
ImprovementDirection::kBiggerIsBetter,
DefaultMetadata());
}
std::vector<Metric> metrics1 = exporter_factory1.exported_metrics;
std::vector<Metric> metrics2 = exporter_factory2.exported_metrics;
std::vector<Metric> metrics3 = exporter_factory3.exported_metrics;
ASSERT_THAT(metrics1.size(), Eq(1lu));
EXPECT_THAT(metrics1[0].name, Eq("metric_name"));
ASSERT_THAT(metrics2.size(), Eq(1lu));
EXPECT_THAT(metrics2[0].name, Eq("metric_name"));
ASSERT_THAT(metrics3.size(), Eq(1lu));
EXPECT_THAT(metrics3[0].name, Eq("metric_name"));
}
} // namespace
} // namespace test
} // namespace webrtc

View file

@ -17,7 +17,7 @@
namespace webrtc { namespace webrtc {
class MockAudioSink final : public webrtc::AudioTrackSinkInterface { class MockAudioSink : public webrtc::AudioTrackSinkInterface {
public: public:
MOCK_METHOD(void, MOCK_METHOD(void,
OnData, OnData,

View file

@ -18,7 +18,7 @@
namespace webrtc { namespace webrtc {
class MockDataChannelInterface final class MockDataChannelInterface
: public rtc::RefCountedObject<webrtc::DataChannelInterface> { : public rtc::RefCountedObject<webrtc::DataChannelInterface> {
public: public:
static rtc::scoped_refptr<MockDataChannelInterface> Create() { static rtc::scoped_refptr<MockDataChannelInterface> Create() {

View file

@ -18,8 +18,7 @@
namespace webrtc { namespace webrtc {
class MockAudioSource final class MockAudioSource : public rtc::RefCountedObject<AudioSourceInterface> {
: public rtc::RefCountedObject<AudioSourceInterface> {
public: public:
static rtc::scoped_refptr<MockAudioSource> Create() { static rtc::scoped_refptr<MockAudioSource> Create() {
return rtc::scoped_refptr<MockAudioSource>(new MockAudioSource()); return rtc::scoped_refptr<MockAudioSource>(new MockAudioSource());
@ -52,7 +51,7 @@ class MockAudioSource final
MockAudioSource() = default; MockAudioSource() = default;
}; };
class MockAudioTrack final : public rtc::RefCountedObject<AudioTrackInterface> { class MockAudioTrack : public rtc::RefCountedObject<AudioTrackInterface> {
public: public:
static rtc::scoped_refptr<MockAudioTrack> Create() { static rtc::scoped_refptr<MockAudioTrack> Create() {
return rtc::scoped_refptr<MockAudioTrack>(new MockAudioTrack()); return rtc::scoped_refptr<MockAudioTrack>(new MockAudioTrack());

View file

@ -19,7 +19,7 @@
namespace webrtc { namespace webrtc {
class MockPeerConnectionFactoryInterface final class MockPeerConnectionFactoryInterface
: public rtc::RefCountedObject<webrtc::PeerConnectionFactoryInterface> { : public rtc::RefCountedObject<webrtc::PeerConnectionFactoryInterface> {
public: public:
static rtc::scoped_refptr<MockPeerConnectionFactoryInterface> Create() { static rtc::scoped_refptr<MockPeerConnectionFactoryInterface> Create() {

View file

@ -47,6 +47,12 @@ class MockPeerConnectionInterface : public webrtc::PeerConnectionInterface {
(rtc::scoped_refptr<MediaStreamTrackInterface>, (rtc::scoped_refptr<MediaStreamTrackInterface>,
const std::vector<std::string>&), const std::vector<std::string>&),
(override)); (override));
MOCK_METHOD(RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>>,
AddTrack,
(rtc::scoped_refptr<MediaStreamTrackInterface>,
const std::vector<std::string>&,
const std::vector<RtpEncodingParameters>&),
(override));
MOCK_METHOD(RTCError, MOCK_METHOD(RTCError,
RemoveTrackOrError, RemoveTrackOrError,
(rtc::scoped_refptr<RtpSenderInterface>), (rtc::scoped_refptr<RtpSenderInterface>),

View file

@ -14,6 +14,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "api/crypto/frame_decryptor_interface.h"
#include "api/rtp_receiver_interface.h" #include "api/rtp_receiver_interface.h"
#include "test/gmock.h" #include "test/gmock.h"
@ -32,12 +33,24 @@ class MockRtpReceiver : public rtc::RefCountedObject<RtpReceiverInterface> {
MOCK_METHOD(cricket::MediaType, media_type, (), (const, override)); MOCK_METHOD(cricket::MediaType, media_type, (), (const, override));
MOCK_METHOD(std::string, id, (), (const, override)); MOCK_METHOD(std::string, id, (), (const, override));
MOCK_METHOD(RtpParameters, GetParameters, (), (const, override)); MOCK_METHOD(RtpParameters, GetParameters, (), (const, override));
MOCK_METHOD(bool,
SetParameters,
(const webrtc::RtpParameters& parameters),
(override));
MOCK_METHOD(void, SetObserver, (RtpReceiverObserverInterface*), (override)); MOCK_METHOD(void, SetObserver, (RtpReceiverObserverInterface*), (override));
MOCK_METHOD(void, MOCK_METHOD(void,
SetJitterBufferMinimumDelay, SetJitterBufferMinimumDelay,
(absl::optional<double>), (absl::optional<double>),
(override)); (override));
MOCK_METHOD(std::vector<RtpSource>, GetSources, (), (const, override)); MOCK_METHOD(std::vector<RtpSource>, GetSources, (), (const, override));
MOCK_METHOD(void,
SetFrameDecryptor,
(rtc::scoped_refptr<webrtc::FrameDecryptorInterface>),
(override));
MOCK_METHOD(rtc::scoped_refptr<webrtc::FrameDecryptorInterface>,
GetFrameDecryptor,
(),
(const, override));
}; };
} // namespace webrtc } // namespace webrtc

View file

@ -46,6 +46,10 @@ class MockRtpSender : public RtpSenderInterface {
(const, override)); (const, override));
MOCK_METHOD(RtpParameters, GetParameters, (), (const, override)); MOCK_METHOD(RtpParameters, GetParameters, (), (const, override));
MOCK_METHOD(RTCError, SetParameters, (const RtpParameters&), (override)); MOCK_METHOD(RTCError, SetParameters, (const RtpParameters&), (override));
MOCK_METHOD(void,
SetParametersAsync,
(const RtpParameters&, SetParametersCallback),
(override));
MOCK_METHOD(rtc::scoped_refptr<DtmfSenderInterface>, MOCK_METHOD(rtc::scoped_refptr<DtmfSenderInterface>,
GetDtmfSender, GetDtmfSender,
(), (),

View file

@ -0,0 +1,56 @@
/*
* Copyright 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.
*/
#ifndef API_TEST_MOCK_SESSION_DESCRIPTION_INTERFACE_H_
#define API_TEST_MOCK_SESSION_DESCRIPTION_INTERFACE_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "api/jsep.h"
#include "test/gmock.h"
namespace webrtc {
class MockSessionDescriptionInterface : public SessionDescriptionInterface {
public:
MOCK_METHOD(std::unique_ptr<SessionDescriptionInterface>,
Clone,
(),
(const, override));
MOCK_METHOD(cricket::SessionDescription*, description, (), (override));
MOCK_METHOD(const cricket::SessionDescription*,
description,
(),
(const, override));
MOCK_METHOD(std::string, session_id, (), (const, override));
MOCK_METHOD(std::string, session_version, (), (const, override));
MOCK_METHOD(SdpType, GetType, (), (const, override));
MOCK_METHOD(std::string, type, (), (const, override));
MOCK_METHOD(bool, AddCandidate, (const IceCandidateInterface*), (override));
MOCK_METHOD(size_t,
RemoveCandidates,
(const std::vector<cricket::Candidate>&),
(override));
MOCK_METHOD(size_t, number_of_mediasections, (), (const, override));
MOCK_METHOD(const IceCandidateCollection*,
candidates,
(size_t),
(const, override));
MOCK_METHOD(bool, ToString, (std::string*), (const, override));
};
static_assert(!std::is_abstract_v<MockSessionDescriptionInterface>);
} // namespace webrtc
#endif // API_TEST_MOCK_SESSION_DESCRIPTION_INTERFACE_H_

View file

@ -20,7 +20,7 @@
namespace webrtc { namespace webrtc {
class MockVideoTrack final class MockVideoTrack
: public rtc::RefCountedObject<webrtc::VideoTrackInterface> { : public rtc::RefCountedObject<webrtc::VideoTrackInterface> {
public: public:
static rtc::scoped_refptr<MockVideoTrack> Create() { static rtc::scoped_refptr<MockVideoTrack> Create() {

View file

@ -12,6 +12,7 @@
#include "rtc_base/net_helper.h" #include "rtc_base/net_helper.h"
namespace webrtc { namespace webrtc {
EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from, EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
const rtc::SocketAddress& to, const rtc::SocketAddress& to,
rtc::CopyOnWriteBuffer data, rtc::CopyOnWriteBuffer data,
@ -26,4 +27,20 @@ EmulatedIpPacket::EmulatedIpPacket(const rtc::SocketAddress& from,
RTC_DCHECK(to.family() == AF_INET || to.family() == AF_INET6); RTC_DCHECK(to.family() == AF_INET || to.family() == AF_INET6);
} }
DataRate EmulatedNetworkOutgoingStats::AverageSendRate() const {
RTC_DCHECK_GE(packets_sent, 2);
RTC_DCHECK(first_packet_sent_time.IsFinite());
RTC_DCHECK(last_packet_sent_time.IsFinite());
return (bytes_sent - first_sent_packet_size) /
(last_packet_sent_time - first_packet_sent_time);
}
DataRate EmulatedNetworkIncomingStats::AverageReceiveRate() const {
RTC_DCHECK_GE(packets_received, 2);
RTC_DCHECK(first_packet_received_time.IsFinite());
RTC_DCHECK(last_packet_received_time.IsFinite());
return (bytes_received - first_received_packet_size) /
(last_packet_received_time - first_packet_received_time);
}
} // namespace webrtc } // namespace webrtc

View file

@ -62,140 +62,182 @@ class EmulatedNetworkReceiverInterface {
virtual void OnPacketReceived(EmulatedIpPacket packet) = 0; virtual void OnPacketReceived(EmulatedIpPacket packet) = 0;
}; };
class EmulatedNetworkOutgoingStats { struct EmulatedNetworkOutgoingStats {
public: int64_t packets_sent = 0;
virtual ~EmulatedNetworkOutgoingStats() = default;
virtual int64_t PacketsSent() const = 0; DataSize bytes_sent = DataSize::Zero();
virtual DataSize BytesSent() const = 0; // Sizes of all sent packets.
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
SamplesStatsCounter sent_packets_size;
// Returns the timestamped sizes of all sent packets if DataSize first_sent_packet_size = DataSize::Zero();
// EmulatedEndpointConfig::stats_gatherming_mode was set to
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty. // Time of the first packet sent or infinite value if no packets were sent.
Timestamp first_packet_sent_time = Timestamp::PlusInfinity();
// Time of the last packet sent or infinite value if no packets were sent.
Timestamp last_packet_sent_time = Timestamp::MinusInfinity();
// Returns average send rate. Requires that at least 2 packets were sent.
DataRate AverageSendRate() const;
};
struct EmulatedNetworkIncomingStats {
// Total amount of packets received with or without destination.
int64_t packets_received = 0;
// Total amount of bytes in received packets.
DataSize bytes_received = DataSize::Zero();
// Sizes of all received packets.
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
SamplesStatsCounter received_packets_size;
// Total amount of packets that were received, but no destination was found.
int64_t packets_discarded_no_receiver = 0;
// Total amount of bytes in discarded packets.
DataSize bytes_discarded_no_receiver = DataSize::Zero();
// Sizes of all packets that were received, but no destination was found.
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
SamplesStatsCounter packets_discarded_no_receiver_size;
DataSize first_received_packet_size = DataSize::Zero();
// Time of the first packet received or infinite value if no packets were
// received.
Timestamp first_packet_received_time = Timestamp::PlusInfinity();
// Time of the last packet received or infinite value if no packets were
// received.
Timestamp last_packet_received_time = Timestamp::MinusInfinity();
DataRate AverageReceiveRate() const;
};
struct EmulatedNetworkStats {
int64_t PacketsSent() const { return overall_outgoing_stats.packets_sent; }
DataSize BytesSent() const { return overall_outgoing_stats.bytes_sent; }
// Returns the timestamped sizes of all sent packets.
// Returned reference is valid until the next call to a non-const method. // Returned reference is valid until the next call to a non-const method.
virtual const SamplesStatsCounter& SentPacketsSizeCounter() const = 0; // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
const SamplesStatsCounter& SentPacketsSizeCounter() const {
return overall_outgoing_stats.sent_packets_size;
}
virtual DataSize FirstSentPacketSize() const = 0; DataSize FirstSentPacketSize() const {
return overall_outgoing_stats.first_sent_packet_size;
}
// Returns time of the first packet sent or infinite value if no packets were // Returns time of the first packet sent or infinite value if no packets were
// sent. // sent.
virtual Timestamp FirstPacketSentTime() const = 0; Timestamp FirstPacketSentTime() const {
return overall_outgoing_stats.first_packet_sent_time;
}
// Returns time of the last packet sent or infinite value if no packets were // Returns time of the last packet sent or infinite value if no packets were
// sent. // sent.
virtual Timestamp LastPacketSentTime() const = 0; Timestamp LastPacketSentTime() const {
return overall_outgoing_stats.last_packet_sent_time;
}
// Returns average send rate. Requires that at least 2 packets were sent. DataRate AverageSendRate() const {
virtual DataRate AverageSendRate() const = 0; return overall_outgoing_stats.AverageSendRate();
}; }
class EmulatedNetworkIncomingStats { // Total amount of packets received regardless of the destination address.
public: int64_t PacketsReceived() const {
virtual ~EmulatedNetworkIncomingStats() = default; return overall_incoming_stats.packets_received;
}
// Total amount of packets received with or without destination.
virtual int64_t PacketsReceived() const = 0;
// Total amount of bytes in received packets. // Total amount of bytes in received packets.
virtual DataSize BytesReceived() const = 0; DataSize BytesReceived() const {
// Returns the timestamped sizes of all received packets if return overall_incoming_stats.bytes_received;
// EmulatedEndpointConfig::stats_gatherming_mode was set to }
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
// Returned reference is valid until the next call to a non-const method.
virtual const SamplesStatsCounter& ReceivedPacketsSizeCounter() const = 0;
// Total amount of packets that were received, but no destination was found.
virtual int64_t PacketsDropped() const = 0;
// Total amount of bytes in dropped packets.
virtual DataSize BytesDropped() const = 0;
// Returns the timestamped sizes of all packets that were received,
// but no destination was found if
// EmulatedEndpointConfig::stats_gatherming_mode was set to
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
// Returned reference is valid until the next call to a non-const method.
virtual const SamplesStatsCounter& DroppedPacketsSizeCounter() const = 0;
virtual DataSize FirstReceivedPacketSize() const = 0; // Returns the timestamped sizes of all received packets.
// Returned reference is valid until the next call to a non-const method.
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
const SamplesStatsCounter& ReceivedPacketsSizeCounter() const {
return overall_incoming_stats.received_packets_size;
}
// Total amount of packets that were received, but no destination was found.
int64_t PacketsDiscardedNoReceiver() const {
return overall_incoming_stats.packets_discarded_no_receiver;
}
// Total amount of bytes in dropped packets.
DataSize BytesDiscardedNoReceiver() const {
return overall_incoming_stats.bytes_discarded_no_receiver;
}
// Returns counter with timestamped sizes of all packets that were received,
// but no destination was found.
// Returned reference is valid until the next call to a non-const method.
// Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
const SamplesStatsCounter& PacketsDiscardedNoReceiverSizeCounter() const {
return overall_incoming_stats.packets_discarded_no_receiver_size;
}
DataSize FirstReceivedPacketSize() const {
return overall_incoming_stats.first_received_packet_size;
}
// Returns time of the first packet received or infinite value if no packets // Returns time of the first packet received or infinite value if no packets
// were received. // were received.
virtual Timestamp FirstPacketReceivedTime() const = 0; Timestamp FirstPacketReceivedTime() const {
return overall_incoming_stats.first_packet_received_time;
}
// Returns time of the last packet received or infinite value if no packets // Returns time of the last packet received or infinite value if no packets
// were received. // were received.
virtual Timestamp LastPacketReceivedTime() const = 0; Timestamp LastPacketReceivedTime() const {
return overall_incoming_stats.last_packet_received_time;
}
virtual DataRate AverageReceiveRate() const = 0; DataRate AverageReceiveRate() const {
}; return overall_incoming_stats.AverageReceiveRate();
}
class EmulatedNetworkStats {
public:
virtual ~EmulatedNetworkStats() = default;
// List of IP addresses that were used to send data considered in this stats // List of IP addresses that were used to send data considered in this stats
// object. // object.
virtual std::vector<rtc::IPAddress> LocalAddresses() const = 0; std::vector<rtc::IPAddress> local_addresses;
virtual int64_t PacketsSent() const = 0; // Overall outgoing stats for all IP addresses which were requested.
EmulatedNetworkOutgoingStats overall_outgoing_stats;
virtual DataSize BytesSent() const = 0; // Overall incoming stats for all IP addresses from which data was received
// Returns the timestamped sizes of all sent packets if // on requested interfaces.
// EmulatedEndpointConfig::stats_gatherming_mode was set to EmulatedNetworkIncomingStats overall_incoming_stats;
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
// Returned reference is valid until the next call to a non-const method.
virtual const SamplesStatsCounter& SentPacketsSizeCounter() const = 0;
// Returns the timestamped duration between packet was received on
// network interface and was dispatched to the network in microseconds if
// EmulatedEndpointConfig::stats_gatherming_mode was set to
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
// Returned reference is valid until the next call to a non-const method.
virtual const SamplesStatsCounter& SentPacketsQueueWaitTimeUs() const = 0;
virtual DataSize FirstSentPacketSize() const = 0; std::map<rtc::IPAddress, EmulatedNetworkOutgoingStats>
// Returns time of the first packet sent or infinite value if no packets were outgoing_stats_per_destination;
// sent. std::map<rtc::IPAddress, EmulatedNetworkIncomingStats>
virtual Timestamp FirstPacketSentTime() const = 0; incoming_stats_per_source;
// Returns time of the last packet sent or infinite value if no packets were
// sent.
virtual Timestamp LastPacketSentTime() const = 0;
virtual DataRate AverageSendRate() const = 0; // Duration between packet was received on network interface and was
// Total amount of packets received regardless of the destination address. // dispatched to the network in microseconds.
virtual int64_t PacketsReceived() const = 0; // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
// Total amount of bytes in received packets. SamplesStatsCounter sent_packets_queue_wait_time_us;
virtual DataSize BytesReceived() const = 0; };
// Returns the timestamped sizes of all received packets if
// EmulatedEndpointConfig::stats_gatherming_mode was set to
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
// Returned reference is valid until the next call to a non-const method.
virtual const SamplesStatsCounter& ReceivedPacketsSizeCounter() const = 0;
// Total amount of packets that were received, but no destination was found.
virtual int64_t PacketsDropped() const = 0;
// Total amount of bytes in dropped packets.
virtual DataSize BytesDropped() const = 0;
// Returns counter with timestamped sizes of all packets that were received,
// but no destination was found if
// EmulatedEndpointConfig::stats_gatherming_mode was set to
// StatsGatheringMode::kDebug; otherwise, the returned value will be empty.
// Returned reference is valid until the next call to a non-const method.
virtual const SamplesStatsCounter& DroppedPacketsSizeCounter() const = 0;
virtual DataSize FirstReceivedPacketSize() const = 0; struct EmulatedNetworkNodeStats {
// Returns time of the first packet received or infinite value if no packets // Amount of time each packet spent in the emulated network node for which
// were received. // stats were collected.
virtual Timestamp FirstPacketReceivedTime() const = 0; //
// Returns time of the last packet received or infinite value if no packets // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
// were received. SamplesStatsCounter packet_transport_time;
virtual Timestamp LastPacketReceivedTime() const = 0;
virtual DataRate AverageReceiveRate() const = 0; // For each packet contains its size divided on the amount of time which it
// spent in the emulated network node for which stats were collected.
virtual std::map<rtc::IPAddress, //
std::unique_ptr<EmulatedNetworkOutgoingStats>> // Collected iff EmulatedNetworkStatsGatheringMode::kDebug is enabled.
OutgoingStatsPerDestination() const = 0; SamplesStatsCounter size_to_packet_transport_time;
virtual std::map<rtc::IPAddress,
std::unique_ptr<EmulatedNetworkIncomingStats>>
IncomingStatsPerSource() const = 0;
}; };
// EmulatedEndpoint is an abstraction for network interface on device. Instances // EmulatedEndpoint is an abstraction for network interface on device. Instances

View file

@ -49,15 +49,18 @@ class EmulatedNetworkNode;
// peer device to another network interface on another peer device. // peer device to another network interface on another peer device.
class EmulatedRoute; class EmulatedRoute;
enum class EmulatedNetworkStatsGatheringMode {
// Gather main network stats counters. See more details on which particular
// metrics are collected in the `EmulatedNetworkStats` and
// `EmulatedNetworkNodeStats` documentation.
kDefault,
// kDefault + also gather per packet statistics. In this mode more memory
// will be used.
kDebug
};
struct EmulatedEndpointConfig { struct EmulatedEndpointConfig {
enum class IpAddressFamily { kIpv4, kIpv6 }; enum class IpAddressFamily { kIpv4, kIpv6 };
enum class StatsGatheringMode {
// Gather main network stats counters.
kDefault,
// kDefault + also gather per packet statistics. In this mode more memory
// will be used.
kDebug
};
// If specified will be used to name endpoint for logging purposes. // If specified will be used to name endpoint for logging purposes.
absl::optional<std::string> name = absl::nullopt; absl::optional<std::string> name = absl::nullopt;
@ -70,7 +73,6 @@ struct EmulatedEndpointConfig {
bool start_as_enabled = true; bool start_as_enabled = true;
// Network type which will be used to represent endpoint to WebRTC. // Network type which will be used to represent endpoint to WebRTC.
rtc::AdapterType type = rtc::AdapterType::ADAPTER_TYPE_UNKNOWN; rtc::AdapterType type = rtc::AdapterType::ADAPTER_TYPE_UNKNOWN;
StatsGatheringMode stats_gathering_mode = StatsGatheringMode::kDefault;
// Allow endpoint to send packets specifying source IP address different to // Allow endpoint to send packets specifying source IP address different to
// the current endpoint IP address. If false endpoint will crash if attempt // the current endpoint IP address. If false endpoint will crash if attempt
// to send such packet will be done. // to send such packet will be done.
@ -143,8 +145,7 @@ class EmulatedNetworkManagerInterface {
// specified `stats_callback`. Callback will be executed on network emulation // specified `stats_callback`. Callback will be executed on network emulation
// internal task queue. // internal task queue.
virtual void GetStats( virtual void GetStats(
std::function<void(std::unique_ptr<EmulatedNetworkStats>)> stats_callback) std::function<void(EmulatedNetworkStats)> stats_callback) const = 0;
const = 0;
}; };
enum class TimeMode { kRealTime, kSimulated }; enum class TimeMode { kRealTime, kSimulated };
@ -324,13 +325,19 @@ class NetworkEmulationManager {
CreateEmulatedNetworkManagerInterface( CreateEmulatedNetworkManagerInterface(
const std::vector<EmulatedEndpoint*>& endpoints) = 0; const std::vector<EmulatedEndpoint*>& endpoints) = 0;
// Passes summarized network stats for specified `endpoints` into specified // Passes combined network stats for all specified `endpoints` into specified
// `stats_callback`. Callback will be executed on network emulation // `stats_callback`. Callback will be executed on network emulation
// internal task queue. // internal task queue.
virtual void GetStats( virtual void GetStats(
rtc::ArrayView<EmulatedEndpoint* const> endpoints, rtc::ArrayView<EmulatedEndpoint* const> endpoints,
std::function<void(std::unique_ptr<EmulatedNetworkStats>)> std::function<void(EmulatedNetworkStats)> stats_callback) = 0;
stats_callback) = 0;
// Passes combined network stats for all specified `nodes` into specified
// `stats_callback`. Callback will be executed on network emulation
// internal task queue.
virtual void GetStats(
rtc::ArrayView<EmulatedNetworkNode* const> nodes,
std::function<void(EmulatedNetworkNodeStats)> stats_callback) = 0;
// Create a EmulatedTURNServer. // Create a EmulatedTURNServer.
// The TURN server has 2 endpoints that need to be connected with routes, // The TURN server has 2 endpoints that need to be connected with routes,

108
api/test/pclf/BUILD.gn Normal file
View file

@ -0,0 +1,108 @@
# 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.
import("../../../webrtc.gni")
rtc_source_set("media_configuration") {
visibility = [ "*" ]
testonly = true
sources = [
"media_configuration.cc",
"media_configuration.h",
]
deps = [
"../..:array_view",
"../..:audio_options_api",
"../..:audio_quality_analyzer_api",
"../..:callfactory_api",
"../..:fec_controller_api",
"../..:frame_generator_api",
"../..:function_view",
"../..:libjingle_peerconnection_api",
"../..:media_stream_interface",
"../..:packet_socket_factory",
"../..:peer_network_dependencies",
"../..:rtp_parameters",
"../..:simulated_network_api",
"../..:stats_observer_interface",
"../..:track_id_stream_info_map",
"../..:video_quality_analyzer_api",
"../../../modules/audio_processing:api",
"../../../rtc_base:checks",
"../../../rtc_base:rtc_base",
"../../../rtc_base:stringutils",
"../../../rtc_base:threading",
"../../../test:fileutils",
"../../../test:video_test_support",
"../../../test/pc/e2e/analyzer/video:video_dumping",
"../../audio:audio_mixer_api",
"../../rtc_event_log",
"../../task_queue",
"../../transport:network_control",
"../../units:time_delta",
"../../video_codecs:video_codecs_api",
"../video:video_frame_writer",
]
absl_deps = [
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("media_quality_test_params") {
visibility = [ "*" ]
testonly = true
sources = [ "media_quality_test_params.h" ]
deps = [
":media_configuration",
"../../../api:callfactory_api",
"../../../api:fec_controller_api",
"../../../api:field_trials_view",
"../../../api:libjingle_peerconnection_api",
"../../../api:packet_socket_factory",
"../../../api/audio:audio_mixer_api",
"../../../api/rtc_event_log",
"../../../api/task_queue",
"../../../api/transport:network_control",
"../../../api/video_codecs:video_codecs_api",
"../../../modules/audio_processing:api",
"../../../p2p:rtc_p2p",
"../../../rtc_base",
"../../../rtc_base:threading",
]
}
rtc_library("peer_configurer") {
visibility = [ "*" ]
testonly = true
sources = [
"peer_configurer.cc",
"peer_configurer.h",
]
deps = [
":media_configuration",
":media_quality_test_params",
"../../../api:callfactory_api",
"../../../api:create_peer_connection_quality_test_frame_generator",
"../../../api:fec_controller_api",
"../../../api:packet_socket_factory",
"../../../api:peer_network_dependencies",
"../../../api/audio:audio_mixer_api",
"../../../api/rtc_event_log",
"../../../api/task_queue",
"../../../api/transport:network_control",
"../../../api/video_codecs:video_codecs_api",
"../../../modules/audio_processing:api",
"../../../rtc_base",
"../../../rtc_base:threading",
]
absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]
}

13
api/test/pclf/DEPS Normal file
View file

@ -0,0 +1,13 @@
specific_include_rules = {
".*": [
"+modules/audio_processing/include/audio_processing.h",
"+rtc_base/checks.h",
"+rtc_base/network.h",
"+rtc_base/rtc_certificate_generator.h",
"+rtc_base/ssl_certificate.h",
"+rtc_base/thread.h",
],
"media_quality_test_params\.h": [
"+p2p/base/port_allocator.h",
],
}

View file

@ -0,0 +1,314 @@
/*
* Copyright 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 "api/test/pclf/media_configuration.h"
#include <string>
#include <utility>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/test/video/video_frame_writer.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
#include "test/pc/e2e/analyzer/video/video_dumping.h"
#include "test/testsupport/file_utils.h"
#include "test/testsupport/video_frame_writer.h"
namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
std::string SpecToString(VideoResolution::Spec spec) {
switch (spec) {
case VideoResolution::Spec::kNone:
return "None";
case VideoResolution::Spec::kMaxFromSender:
return "MaxFromSender";
}
}
void AppendResolution(const VideoResolution& resolution,
rtc::StringBuilder& builder) {
builder << "_" << resolution.width() << "x" << resolution.height() << "_"
<< resolution.fps();
}
} // namespace
ScreenShareConfig::ScreenShareConfig(TimeDelta slide_change_interval)
: slide_change_interval(slide_change_interval) {
RTC_CHECK_GT(slide_change_interval.ms(), 0);
}
VideoSimulcastConfig::VideoSimulcastConfig(int simulcast_streams_count)
: simulcast_streams_count(simulcast_streams_count) {
RTC_CHECK_GT(simulcast_streams_count, 1);
}
EmulatedSFUConfig::EmulatedSFUConfig(int target_layer_index)
: target_layer_index(target_layer_index) {
RTC_CHECK_GE(target_layer_index, 0);
}
EmulatedSFUConfig::EmulatedSFUConfig(absl::optional<int> target_layer_index,
absl::optional<int> target_temporal_index)
: target_layer_index(target_layer_index),
target_temporal_index(target_temporal_index) {
RTC_CHECK_GE(target_temporal_index.value_or(0), 0);
if (target_temporal_index)
RTC_CHECK_GE(*target_temporal_index, 0);
}
VideoResolution::VideoResolution(size_t width, size_t height, int32_t fps)
: width_(width), height_(height), fps_(fps), spec_(Spec::kNone) {}
VideoResolution::VideoResolution(Spec spec)
: width_(0), height_(0), fps_(0), spec_(spec) {}
bool VideoResolution::operator==(const VideoResolution& other) const {
if (spec_ != Spec::kNone && spec_ == other.spec_) {
// If there is some particular spec set, then it doesn't matter what
// values we have in other fields.
return true;
}
return width_ == other.width_ && height_ == other.height_ &&
fps_ == other.fps_ && spec_ == other.spec_;
}
bool VideoResolution::operator!=(const VideoResolution& other) const {
return !(*this == other);
}
bool VideoResolution::IsRegular() const {
return spec_ == Spec::kNone;
}
std::string VideoResolution::ToString() const {
rtc::StringBuilder out;
out << "{ width=" << width_ << ", height=" << height_ << ", fps=" << fps_
<< ", spec=" << SpecToString(spec_) << " }";
return out.Release();
}
VideoDumpOptions::VideoDumpOptions(
absl::string_view output_directory,
int sampling_modulo,
bool export_frame_ids,
std::function<std::unique_ptr<test::VideoFrameWriter>(
absl::string_view file_name_prefix,
const VideoResolution& resolution)> video_frame_writer_factory)
: output_directory_(output_directory),
sampling_modulo_(sampling_modulo),
export_frame_ids_(export_frame_ids),
video_frame_writer_factory_(video_frame_writer_factory) {
RTC_CHECK_GT(sampling_modulo, 0);
}
VideoDumpOptions::VideoDumpOptions(absl::string_view output_directory,
bool export_frame_ids)
: VideoDumpOptions(output_directory,
kDefaultSamplingModulo,
export_frame_ids) {}
std::unique_ptr<test::VideoFrameWriter>
VideoDumpOptions::CreateInputDumpVideoFrameWriter(
absl::string_view stream_label,
const VideoResolution& resolution) const {
std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
GetInputDumpFileName(stream_label, resolution), resolution);
absl::optional<std::string> frame_ids_file =
GetInputFrameIdsDumpFileName(stream_label, resolution);
if (frame_ids_file.has_value()) {
writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
}
return writer;
}
std::unique_ptr<test::VideoFrameWriter>
VideoDumpOptions::CreateOutputDumpVideoFrameWriter(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const {
std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
GetOutputDumpFileName(stream_label, receiver, resolution), resolution);
absl::optional<std::string> frame_ids_file =
GetOutputFrameIdsDumpFileName(stream_label, receiver, resolution);
if (frame_ids_file.has_value()) {
writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
}
return writer;
}
std::unique_ptr<test::VideoFrameWriter>
VideoDumpOptions::Y4mVideoFrameWriterFactory(
absl::string_view file_name_prefix,
const VideoResolution& resolution) {
return std::make_unique<test::Y4mVideoFrameWriterImpl>(
std::string(file_name_prefix) + ".y4m", resolution.width(),
resolution.height(), resolution.fps());
}
std::string VideoDumpOptions::GetInputDumpFileName(
absl::string_view stream_label,
const VideoResolution& resolution) const {
rtc::StringBuilder file_name;
file_name << stream_label;
AppendResolution(resolution, file_name);
return test::JoinFilename(output_directory_, file_name.Release());
}
absl::optional<std::string> VideoDumpOptions::GetInputFrameIdsDumpFileName(
absl::string_view stream_label,
const VideoResolution& resolution) const {
if (!export_frame_ids_) {
return absl::nullopt;
}
return GetInputDumpFileName(stream_label, resolution) + ".frame_ids.txt";
}
std::string VideoDumpOptions::GetOutputDumpFileName(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const {
rtc::StringBuilder file_name;
file_name << stream_label << "_" << receiver;
AppendResolution(resolution, file_name);
return test::JoinFilename(output_directory_, file_name.Release());
}
absl::optional<std::string> VideoDumpOptions::GetOutputFrameIdsDumpFileName(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const {
if (!export_frame_ids_) {
return absl::nullopt;
}
return GetOutputDumpFileName(stream_label, receiver, resolution) +
".frame_ids.txt";
}
std::string VideoDumpOptions::ToString() const {
rtc::StringBuilder out;
out << "{ output_directory_=" << output_directory_
<< ", sampling_modulo_=" << sampling_modulo_
<< ", export_frame_ids_=" << export_frame_ids_ << " }";
return out.Release();
}
VideoConfig::VideoConfig(const VideoResolution& resolution)
: width(resolution.width()),
height(resolution.height()),
fps(resolution.fps()) {
RTC_CHECK(resolution.IsRegular());
}
VideoConfig::VideoConfig(size_t width, size_t height, int32_t fps)
: width(width), height(height), fps(fps) {}
VideoConfig::VideoConfig(std::string stream_label,
size_t width,
size_t height,
int32_t fps)
: width(width),
height(height),
fps(fps),
stream_label(std::move(stream_label)) {}
AudioConfig::AudioConfig(std::string stream_label)
: stream_label(std::move(stream_label)) {}
VideoCodecConfig::VideoCodecConfig(std::string name)
: name(std::move(name)), required_params() {}
VideoCodecConfig::VideoCodecConfig(
std::string name,
std::map<std::string, std::string> required_params)
: name(std::move(name)), required_params(std::move(required_params)) {}
absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
rtc::ArrayView<const VideoConfig> video_configs) {
std::vector<VideoResolution> resolutions;
for (const auto& video_config : video_configs) {
resolutions.push_back(video_config.GetResolution());
}
return GetMaxResolution(resolutions);
}
absl::optional<VideoResolution> VideoSubscription::GetMaxResolution(
rtc::ArrayView<const VideoResolution> resolutions) {
if (resolutions.empty()) {
return absl::nullopt;
}
VideoResolution max_resolution;
for (const VideoResolution& resolution : resolutions) {
if (max_resolution.width() < resolution.width()) {
max_resolution.set_width(resolution.width());
}
if (max_resolution.height() < resolution.height()) {
max_resolution.set_height(resolution.height());
}
if (max_resolution.fps() < resolution.fps()) {
max_resolution.set_fps(resolution.fps());
}
}
return max_resolution;
}
bool VideoSubscription::operator==(const VideoSubscription& other) const {
return default_resolution_ == other.default_resolution_ &&
peers_resolution_ == other.peers_resolution_;
}
bool VideoSubscription::operator!=(const VideoSubscription& other) const {
return !(*this == other);
}
VideoSubscription& VideoSubscription::SubscribeToPeer(
absl::string_view peer_name,
VideoResolution resolution) {
peers_resolution_[std::string(peer_name)] = resolution;
return *this;
}
VideoSubscription& VideoSubscription::SubscribeToAllPeers(
VideoResolution resolution) {
default_resolution_ = resolution;
return *this;
}
absl::optional<VideoResolution> VideoSubscription::GetResolutionForPeer(
absl::string_view peer_name) const {
auto it = peers_resolution_.find(std::string(peer_name));
if (it == peers_resolution_.end()) {
return default_resolution_;
}
return it->second;
}
std::vector<std::string> VideoSubscription::GetSubscribedPeers() const {
std::vector<std::string> subscribed_streams;
subscribed_streams.reserve(peers_resolution_.size());
for (const auto& entry : peers_resolution_) {
subscribed_streams.push_back(entry.first);
}
return subscribed_streams;
}
std::string VideoSubscription::ToString() const {
rtc::StringBuilder out;
out << "{ default_resolution_=[";
if (default_resolution_.has_value()) {
out << default_resolution_->ToString();
} else {
out << "undefined";
}
out << "], {";
for (const auto& [peer_name, resolution] : peers_resolution_) {
out << "[" << peer_name << ": " << resolution.ToString() << "], ";
}
out << "} }";
return out.Release();
}
} // namespace webrtc_pc_e2e
} // namespace webrtc

View file

@ -0,0 +1,484 @@
/*
* 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.
*/
#ifndef API_TEST_PCLF_MEDIA_CONFIGURATION_H_
#define API_TEST_PCLF_MEDIA_CONFIGURATION_H_
#include <stddef.h>
#include <stdint.h>
#include <functional>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/async_resolver_factory.h"
#include "api/audio/audio_mixer.h"
#include "api/audio_options.h"
#include "api/call/call_factory_interface.h"
#include "api/fec_controller.h"
#include "api/function_view.h"
#include "api/media_stream_interface.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
#include "api/rtp_parameters.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/test/audio_quality_analyzer_interface.h"
#include "api/test/frame_generator_interface.h"
#include "api/test/peer_network_dependencies.h"
#include "api/test/simulated_network.h"
#include "api/test/stats_observer_interface.h"
#include "api/test/track_id_stream_info_map.h"
#include "api/test/video/video_frame_writer.h"
#include "api/test/video_quality_analyzer_interface.h"
#include "api/transport/network_control.h"
#include "api/units/time_delta.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/checks.h"
#include "rtc_base/network.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/thread.h"
namespace webrtc {
namespace webrtc_pc_e2e {
constexpr size_t kDefaultSlidesWidth = 1850;
constexpr size_t kDefaultSlidesHeight = 1110;
// The index of required capturing device in OS provided list of video
// devices. On Linux and Windows the list will be obtained via
// webrtc::VideoCaptureModule::DeviceInfo, on Mac OS via
// [RTCCameraVideoCapturer captureDevices].
enum class CapturingDeviceIndex : size_t {};
// Contains parameters for screen share scrolling.
//
// If scrolling is enabled, then it will be done by putting sliding window
// on source video and moving this window from top left corner to the
// bottom right corner of the picture.
//
// In such case source dimensions must be greater or equal to the sliding
// window dimensions. So `source_width` and `source_height` are the dimensions
// of the source frame, while `VideoConfig::width` and `VideoConfig::height`
// are the dimensions of the sliding window.
//
// Because `source_width` and `source_height` are dimensions of the source
// frame, they have to be width and height of videos from
// `ScreenShareConfig::slides_yuv_file_names`.
//
// Because scrolling have to be done on single slide it also requires, that
// `duration` must be less or equal to
// `ScreenShareConfig::slide_change_interval`.
struct ScrollingParams {
// Duration of scrolling.
TimeDelta duration;
// Width of source slides video.
size_t source_width = kDefaultSlidesWidth;
// Height of source slides video.
size_t source_height = kDefaultSlidesHeight;
};
// Contains screen share video stream properties.
struct ScreenShareConfig {
explicit ScreenShareConfig(TimeDelta slide_change_interval);
// Shows how long one slide should be presented on the screen during
// slide generation.
TimeDelta slide_change_interval;
// If true, slides will be generated programmatically. No scrolling params
// will be applied in such case.
bool generate_slides = false;
// If present scrolling will be applied. Please read extra requirement on
// `slides_yuv_file_names` for scrolling.
absl::optional<ScrollingParams> scrolling_params;
// Contains list of yuv files with slides.
//
// If empty, default set of slides will be used. In such case
// `VideoConfig::width` must be equal to `kDefaultSlidesWidth` and
// `VideoConfig::height` must be equal to `kDefaultSlidesHeight` or if
// `scrolling_params` are specified, then `ScrollingParams::source_width`
// must be equal to `kDefaultSlidesWidth` and
// `ScrollingParams::source_height` must be equal to `kDefaultSlidesHeight`.
std::vector<std::string> slides_yuv_file_names;
};
// Config for Vp8 simulcast or non-standard Vp9 SVC testing.
//
// To configure standard SVC setting, use `scalability_mode` in the
// `encoding_params` array.
// This configures Vp9 SVC by requesting simulcast layers, the request is
// internally converted to a request for SVC layers.
//
// SVC support is limited:
// During SVC testing there is no SFU, so framework will try to emulate SFU
// behavior in regular p2p call. Because of it there are such limitations:
// * if `target_spatial_index` is not equal to the highest spatial layer
// then no packet/frame drops are allowed.
//
// If there will be any drops, that will affect requested layer, then
// WebRTC SVC implementation will continue decoding only the highest
// available layer and won't restore lower layers, so analyzer won't
// receive required data which will cause wrong results or test failures.
struct VideoSimulcastConfig {
explicit VideoSimulcastConfig(int simulcast_streams_count);
// Specified amount of simulcast streams/SVC layers, depending on which
// encoder is used.
int simulcast_streams_count;
};
// Configuration for the emulated Selective Forward Unit (SFU)
//
// The framework can optionally filter out frames that are decoded
// using an emulated SFU.
// When using simulcast or SVC, it's not always desirable to receive
// all frames. In a real world call, a SFU will only forward a subset
// of the frames.
// The emulated SFU is not able to change its configuration dynamically,
// if adaptation happens during the call, layers may be dropped and the
// analyzer won't receive the required data which will cause wrong results or
// test failures.
struct EmulatedSFUConfig {
EmulatedSFUConfig() = default;
explicit EmulatedSFUConfig(int target_layer_index);
EmulatedSFUConfig(absl::optional<int> target_layer_index,
absl::optional<int> target_temporal_index);
// Specifies simulcast or spatial index of the video stream to analyze.
// There are 2 cases:
// 1. simulcast encoding is used:
// in such case `target_layer_index` will specify the index of
// simulcast stream, that should be analyzed. Other streams will be
// dropped.
// 2. SVC encoding is used:
// in such case `target_layer_index` will specify the top interesting
// spatial layer and all layers below, including target one will be
// processed. All layers above target one will be dropped.
// If not specified then all streams will be received and analyzed.
// When set, it instructs the framework to create an emulated Selective
// Forwarding Unit (SFU) that will propagate only the requested layers.
absl::optional<int> target_layer_index;
// Specifies the index of the maximum temporal unit to keep.
// If not specified then all temporal layers will be received and analyzed.
// When set, it instructs the framework to create an emulated Selective
// Forwarding Unit (SFU) that will propagate only up to the requested layer.
absl::optional<int> target_temporal_index;
};
class VideoResolution {
public:
// Determines special resolutions, which can't be expressed in terms of
// width, height and fps.
enum class Spec {
// No extra spec set. It describes a regular resolution described by
// width, height and fps.
kNone,
// Describes resolution which contains max value among all sender's
// video streams in each dimension (width, height, fps).
kMaxFromSender
};
VideoResolution(size_t width, size_t height, int32_t fps);
explicit VideoResolution(Spec spec = Spec::kNone);
bool operator==(const VideoResolution& other) const;
bool operator!=(const VideoResolution& other) const;
size_t width() const { return width_; }
void set_width(size_t width) { width_ = width; }
size_t height() const { return height_; }
void set_height(size_t height) { height_ = height; }
int32_t fps() const { return fps_; }
void set_fps(int32_t fps) { fps_ = fps; }
// Returns if it is a regular resolution or not. The resolution is regular
// if it's spec is `Spec::kNone`.
bool IsRegular() const;
std::string ToString() const;
private:
size_t width_ = 0;
size_t height_ = 0;
int32_t fps_ = 0;
Spec spec_ = Spec::kNone;
};
class VideoDumpOptions {
public:
static constexpr int kDefaultSamplingModulo = 1;
// output_directory - the output directory where stream will be dumped. The
// output files' names will be constructed as
// <stream_name>_<receiver_name>_<resolution>.<extension> for output dumps
// and <stream_name>_<resolution>.<extension> for input dumps.
// By default <extension> is "y4m". Resolution is in the format
// <width>x<height>_<fps>.
// sampling_modulo - the module for the video frames to be dumped. Modulo
// equals X means every Xth frame will be written to the dump file. The
// value must be greater than 0. (Default: 1)
// export_frame_ids - specifies if frame ids should be exported together
// with content of the stream. If true, an output file with the same name as
// video dump and suffix ".frame_ids.txt" will be created. It will contain
// the frame ids in the same order as original frames in the output
// file with stream content. File will contain one frame id per line.
// (Default: false)
// `video_frame_writer_factory` - factory function to create a video frame
// writer for input and output video files. (Default: Y4M video writer
// factory).
explicit VideoDumpOptions(
absl::string_view output_directory,
int sampling_modulo = kDefaultSamplingModulo,
bool export_frame_ids = false,
std::function<std::unique_ptr<test::VideoFrameWriter>(
absl::string_view file_name_prefix,
const VideoResolution& resolution)> video_frame_writer_factory =
Y4mVideoFrameWriterFactory);
VideoDumpOptions(absl::string_view output_directory, bool export_frame_ids);
VideoDumpOptions(const VideoDumpOptions&) = default;
VideoDumpOptions& operator=(const VideoDumpOptions&) = default;
VideoDumpOptions(VideoDumpOptions&&) = default;
VideoDumpOptions& operator=(VideoDumpOptions&&) = default;
std::string output_directory() const { return output_directory_; }
int sampling_modulo() const { return sampling_modulo_; }
bool export_frame_ids() const { return export_frame_ids_; }
std::unique_ptr<test::VideoFrameWriter> CreateInputDumpVideoFrameWriter(
absl::string_view stream_label,
const VideoResolution& resolution) const;
std::unique_ptr<test::VideoFrameWriter> CreateOutputDumpVideoFrameWriter(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const;
std::string ToString() const;
private:
static std::unique_ptr<test::VideoFrameWriter> Y4mVideoFrameWriterFactory(
absl::string_view file_name_prefix,
const VideoResolution& resolution);
std::string GetInputDumpFileName(absl::string_view stream_label,
const VideoResolution& resolution) const;
// Returns file name for input frame ids dump if `export_frame_ids()` is
// true, absl::nullopt otherwise.
absl::optional<std::string> GetInputFrameIdsDumpFileName(
absl::string_view stream_label,
const VideoResolution& resolution) const;
std::string GetOutputDumpFileName(absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const;
// Returns file name for output frame ids dump if `export_frame_ids()` is
// true, absl::nullopt otherwise.
absl::optional<std::string> GetOutputFrameIdsDumpFileName(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const;
std::string output_directory_;
int sampling_modulo_ = 1;
bool export_frame_ids_ = false;
std::function<std::unique_ptr<test::VideoFrameWriter>(
absl::string_view file_name_prefix,
const VideoResolution& resolution)>
video_frame_writer_factory_;
};
// Contains properties of single video stream.
struct VideoConfig {
explicit VideoConfig(const VideoResolution& resolution);
VideoConfig(size_t width, size_t height, int32_t fps);
VideoConfig(std::string stream_label,
size_t width,
size_t height,
int32_t fps);
// Video stream width.
size_t width;
// Video stream height.
size_t height;
int32_t fps;
VideoResolution GetResolution() const {
return VideoResolution(width, height, fps);
}
// Have to be unique among all specified configs for all peers in the call.
// Will be auto generated if omitted.
absl::optional<std::string> stream_label;
// Will be set for current video track. If equals to kText or kDetailed -
// screencast in on.
absl::optional<VideoTrackInterface::ContentHint> content_hint;
// If presented video will be transfered in simulcast/SVC mode depending on
// which encoder is used.
//
// Simulcast is supported only from 1st added peer. For VP8 simulcast only
// without RTX is supported so it will be automatically disabled for all
// simulcast tracks. For VP9 simulcast enables VP9 SVC mode and support RTX,
// but only on non-lossy networks. See more in documentation to
// VideoSimulcastConfig.
absl::optional<VideoSimulcastConfig> simulcast_config;
// Configuration for the emulated Selective Forward Unit (SFU).
absl::optional<EmulatedSFUConfig> emulated_sfu_config;
// Encoding parameters for both singlecast and per simulcast layer.
// If singlecast is used, if not empty, a single value can be provided.
// If simulcast is used, if not empty, `encoding_params` size have to be
// equal to `simulcast_config.simulcast_streams_count`. Will be used to set
// transceiver send encoding params for each layer.
// RtpEncodingParameters::rid may be changed by fixture implementation to
// ensure signaling correctness.
std::vector<RtpEncodingParameters> encoding_params;
// Count of temporal layers for video stream. This value will be set into
// each RtpEncodingParameters of RtpParameters of corresponding
// RtpSenderInterface for this video stream.
absl::optional<int> temporal_layers_count;
// If specified defines how input should be dumped. It is actually one of
// the test's output file, which contains copy of what was captured during
// the test for this video stream on sender side. It is useful when
// generator is used as input.
absl::optional<VideoDumpOptions> input_dump_options;
// If specified defines how output should be dumped on the receiver side for
// this stream. The produced files contain what was rendered for this video
// stream on receiver side per each receiver.
absl::optional<VideoDumpOptions> output_dump_options;
// If set to true uses fixed frame rate while dumping output video to the
// file. Requested `VideoSubscription::fps()` will be used as frame rate.
bool output_dump_use_fixed_framerate = false;
// If true will display input and output video on the user's screen.
bool show_on_screen = false;
// If specified, determines a sync group to which this video stream belongs.
// According to bugs.webrtc.org/4762 WebRTC supports synchronization only
// for pair of single audio and single video stream.
absl::optional<std::string> sync_group;
// If specified, it will be set into RtpParameters of corresponding
// RtpSenderInterface for this video stream.
// Note that this setting takes precedence over `content_hint`.
absl::optional<DegradationPreference> degradation_preference;
};
// Contains properties for audio in the call.
struct AudioConfig {
enum Mode {
kGenerated,
kFile,
};
AudioConfig() = default;
explicit AudioConfig(std::string stream_label);
// Have to be unique among all specified configs for all peers in the call.
// Will be auto generated if omitted.
absl::optional<std::string> stream_label;
Mode mode = kGenerated;
// Have to be specified only if mode = kFile
absl::optional<std::string> input_file_name;
// If specified the input stream will be also copied to specified file.
absl::optional<std::string> input_dump_file_name;
// If specified the output stream will be copied to specified file.
absl::optional<std::string> output_dump_file_name;
// Audio options to use.
cricket::AudioOptions audio_options;
// Sampling frequency of input audio data (from file or generated).
int sampling_frequency_in_hz = 48000;
// If specified, determines a sync group to which this audio stream belongs.
// According to bugs.webrtc.org/4762 WebRTC supports synchronization only
// for pair of single audio and single video stream.
absl::optional<std::string> sync_group;
};
struct VideoCodecConfig {
explicit VideoCodecConfig(std::string name);
VideoCodecConfig(std::string name,
std::map<std::string, std::string> required_params);
// Next two fields are used to specify concrete video codec, that should be
// used in the test. Video code will be negotiated in SDP during offer/
// answer exchange.
// Video codec name. You can find valid names in
// media/base/media_constants.h
std::string name;
// Map of parameters, that have to be specified on SDP codec. Each parameter
// is described by key and value. Codec parameters will match the specified
// map if and only if for each key from `required_params` there will be
// a parameter with name equal to this key and parameter value will be equal
// to the value from `required_params` for this key.
// If empty then only name will be used to match the codec.
std::map<std::string, std::string> required_params;
};
// Subscription to the remote video streams. It declares which remote stream
// peer should receive and in which resolution (width x height x fps).
class VideoSubscription {
public:
// Returns the resolution constructed as maximum from all resolution
// dimensions: width, height and fps.
static absl::optional<VideoResolution> GetMaxResolution(
rtc::ArrayView<const VideoConfig> video_configs);
static absl::optional<VideoResolution> GetMaxResolution(
rtc::ArrayView<const VideoResolution> resolutions);
bool operator==(const VideoSubscription& other) const;
bool operator!=(const VideoSubscription& other) const;
// Subscribes receiver to all streams sent by the specified peer with
// specified resolution. It will override any resolution that was used in
// `SubscribeToAll` independently from methods call order.
VideoSubscription& SubscribeToPeer(
absl::string_view peer_name,
VideoResolution resolution =
VideoResolution(VideoResolution::Spec::kMaxFromSender));
// Subscribes receiver to the all sent streams with specified resolution.
// If any stream was subscribed to with `SubscribeTo` method that will
// override resolution passed to this function independently from methods
// call order.
VideoSubscription& SubscribeToAllPeers(
VideoResolution resolution =
VideoResolution(VideoResolution::Spec::kMaxFromSender));
// Returns resolution for specific sender. If no specific resolution was
// set for this sender, then will return resolution used for all streams.
// If subscription doesn't subscribe to all streams, `absl::nullopt` will be
// returned.
absl::optional<VideoResolution> GetResolutionForPeer(
absl::string_view peer_name) const;
// Returns a maybe empty list of senders for which peer explicitly
// subscribed to with specific resolution.
std::vector<std::string> GetSubscribedPeers() const;
std::string ToString() const;
private:
absl::optional<VideoResolution> default_resolution_ = absl::nullopt;
std::map<std::string, VideoResolution> peers_resolution_;
};
// Contains configuration for echo emulator.
struct EchoEmulationConfig {
// Delay which represents the echo path delay, i.e. how soon rendered signal
// should reach capturer.
TimeDelta echo_delay = TimeDelta::Millis(50);
};
} // namespace webrtc_pc_e2e
} // namespace webrtc
#endif // API_TEST_PCLF_MEDIA_CONFIGURATION_H_

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -7,8 +7,8 @@
* in the file PATENTS. All contributing project authors may * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#ifndef TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_PARAMS_H_ #ifndef API_TEST_PCLF_MEDIA_QUALITY_TEST_PARAMS_H_
#define TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_PARAMS_H_ #define API_TEST_PCLF_MEDIA_QUALITY_TEST_PARAMS_H_
#include <cstddef> #include <cstddef>
#include <memory> #include <memory>
@ -22,7 +22,7 @@
#include "api/field_trials_view.h" #include "api/field_trials_view.h"
#include "api/rtc_event_log/rtc_event_log_factory_interface.h" #include "api/rtc_event_log/rtc_event_log_factory_interface.h"
#include "api/task_queue/task_queue_factory.h" #include "api/task_queue/task_queue_factory.h"
#include "api/test/peerconnection_quality_test_fixture.h" #include "api/test/pclf/media_configuration.h"
#include "api/transport/network_control.h" #include "api/transport/network_control.h"
#include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h" #include "api/video_codecs/video_encoder_factory.h"
@ -118,7 +118,7 @@ struct Params {
// Peer name. If empty - default one will be set by the fixture. // Peer name. If empty - default one will be set by the fixture.
absl::optional<std::string> name; absl::optional<std::string> name;
// If `audio_config` is set audio stream will be configured // If `audio_config` is set audio stream will be configured
absl::optional<PeerConnectionE2EQualityTestFixture::AudioConfig> audio_config; absl::optional<AudioConfig> audio_config;
// Flags to set on `cricket::PortAllocator`. These flags will be added // Flags to set on `cricket::PortAllocator`. These flags will be added
// to the default ones that are presented on the port allocator. // to the default ones that are presented on the port allocator.
uint32_t port_allocator_extra_flags = cricket::kDefaultPortAllocatorFlags; uint32_t port_allocator_extra_flags = cricket::kDefaultPortAllocatorFlags;
@ -142,21 +142,41 @@ struct Params {
PeerConnectionInterface::RTCConfiguration rtc_configuration; PeerConnectionInterface::RTCConfiguration rtc_configuration;
PeerConnectionInterface::RTCOfferAnswerOptions rtc_offer_answer_options; PeerConnectionInterface::RTCOfferAnswerOptions rtc_offer_answer_options;
BitrateSettings bitrate_settings; BitrateSettings bitrate_settings;
std::vector<PeerConnectionE2EQualityTestFixture::VideoCodecConfig> std::vector<VideoCodecConfig> video_codecs;
video_codecs;
}; };
// Contains parameters that maybe changed by test writer during the test call. // Contains parameters that maybe changed by test writer during the test call.
struct ConfigurableParams { struct ConfigurableParams {
// If `video_configs` is empty - no video should be added to the test call. // If `video_configs` is empty - no video should be added to the test call.
std::vector<PeerConnectionE2EQualityTestFixture::VideoConfig> video_configs; std::vector<VideoConfig> video_configs;
PeerConnectionE2EQualityTestFixture::VideoSubscription video_subscription = VideoSubscription video_subscription =
PeerConnectionE2EQualityTestFixture::VideoSubscription() VideoSubscription().SubscribeToAllPeers();
.SubscribeToAllPeers(); };
// Contains parameters, that describe how long framework should run quality
// test.
struct RunParams {
explicit RunParams(TimeDelta run_duration) : run_duration(run_duration) {}
// Specifies how long the test should be run. This time shows how long
// the media should flow after connection was established and before
// it will be shut downed.
TimeDelta run_duration;
// If set to true peers will be able to use Flex FEC, otherwise they won't
// be able to negotiate it even if it's enabled on per peer level.
bool enable_flex_fec_support = false;
// If true will set conference mode in SDP media section for all video
// tracks for all peers.
bool use_conference_mode = false;
// If specified echo emulation will be done, by mixing the render audio into
// the capture signal. In such case input signal will be reduced by half to
// avoid saturation or compression in the echo path simulation.
absl::optional<EchoEmulationConfig> echo_emulation_config;
}; };
} // namespace webrtc_pc_e2e } // namespace webrtc_pc_e2e
} // namespace webrtc } // namespace webrtc
#endif // TEST_PC_E2E_PEER_CONNECTION_QUALITY_TEST_PARAMS_H_ #endif // API_TEST_PCLF_MEDIA_QUALITY_TEST_PARAMS_H_

View file

@ -0,0 +1,235 @@
/*
* 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 "api/test/pclf/peer_configurer.h"
#include <set>
#include "absl/strings/string_view.h"
#include "api/test/pclf/media_configuration.h"
#include "api/test/pclf/media_quality_test_params.h"
#include "api/test/peer_network_dependencies.h"
namespace webrtc {
namespace webrtc_pc_e2e {
PeerConfigurer::PeerConfigurer(
const PeerNetworkDependencies& network_dependencies)
: components_(std::make_unique<InjectableComponents>(
network_dependencies.network_thread,
network_dependencies.network_manager,
network_dependencies.packet_socket_factory)),
params_(std::make_unique<Params>()),
configurable_params_(std::make_unique<ConfigurableParams>()) {}
PeerConfigurer* PeerConfigurer::SetName(absl::string_view name) {
params_->name = std::string(name);
return this;
}
PeerConfigurer* PeerConfigurer::SetTaskQueueFactory(
std::unique_ptr<TaskQueueFactory> task_queue_factory) {
components_->pcf_dependencies->task_queue_factory =
std::move(task_queue_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetCallFactory(
std::unique_ptr<CallFactoryInterface> call_factory) {
components_->pcf_dependencies->call_factory = std::move(call_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetEventLogFactory(
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) {
components_->pcf_dependencies->event_log_factory =
std::move(event_log_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetFecControllerFactory(
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory) {
components_->pcf_dependencies->fec_controller_factory =
std::move(fec_controller_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetNetworkControllerFactory(
std::unique_ptr<NetworkControllerFactoryInterface>
network_controller_factory) {
components_->pcf_dependencies->network_controller_factory =
std::move(network_controller_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetVideoEncoderFactory(
std::unique_ptr<VideoEncoderFactory> video_encoder_factory) {
components_->pcf_dependencies->video_encoder_factory =
std::move(video_encoder_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetVideoDecoderFactory(
std::unique_ptr<VideoDecoderFactory> video_decoder_factory) {
components_->pcf_dependencies->video_decoder_factory =
std::move(video_decoder_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetAsyncResolverFactory(
std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory) {
components_->pc_dependencies->async_resolver_factory =
std::move(async_resolver_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetRTCCertificateGenerator(
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) {
components_->pc_dependencies->cert_generator = std::move(cert_generator);
return this;
}
PeerConfigurer* PeerConfigurer::SetSSLCertificateVerifier(
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier) {
components_->pc_dependencies->tls_cert_verifier =
std::move(tls_cert_verifier);
return this;
}
PeerConfigurer* PeerConfigurer::AddVideoConfig(VideoConfig config) {
video_sources_.push_back(
CreateSquareFrameGenerator(config, /*type=*/absl::nullopt));
configurable_params_->video_configs.push_back(std::move(config));
return this;
}
PeerConfigurer* PeerConfigurer::AddVideoConfig(
VideoConfig config,
std::unique_ptr<test::FrameGeneratorInterface> generator) {
configurable_params_->video_configs.push_back(std::move(config));
video_sources_.push_back(std::move(generator));
return this;
}
PeerConfigurer* PeerConfigurer::AddVideoConfig(VideoConfig config,
CapturingDeviceIndex index) {
configurable_params_->video_configs.push_back(std::move(config));
video_sources_.push_back(index);
return this;
}
PeerConfigurer* PeerConfigurer::SetVideoSubscription(
VideoSubscription subscription) {
configurable_params_->video_subscription = std::move(subscription);
return this;
}
PeerConfigurer* PeerConfigurer::SetAudioConfig(AudioConfig config) {
params_->audio_config = std::move(config);
return this;
}
PeerConfigurer* PeerConfigurer::SetUseUlpFEC(bool value) {
params_->use_ulp_fec = value;
return this;
}
PeerConfigurer* PeerConfigurer::SetUseFlexFEC(bool value) {
params_->use_flex_fec = value;
return this;
}
PeerConfigurer* PeerConfigurer::SetVideoEncoderBitrateMultiplier(
double multiplier) {
params_->video_encoder_bitrate_multiplier = multiplier;
return this;
}
PeerConfigurer* PeerConfigurer::SetNetEqFactory(
std::unique_ptr<NetEqFactory> neteq_factory) {
components_->pcf_dependencies->neteq_factory = std::move(neteq_factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetAudioProcessing(
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) {
components_->pcf_dependencies->audio_processing = audio_processing;
return this;
}
PeerConfigurer* PeerConfigurer::SetAudioMixer(
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) {
components_->pcf_dependencies->audio_mixer = audio_mixer;
return this;
}
PeerConfigurer* PeerConfigurer::SetUseNetworkThreadAsWorkerThread() {
components_->worker_thread = components_->network_thread;
return this;
}
PeerConfigurer* PeerConfigurer::SetRtcEventLogPath(std::string path) {
params_->rtc_event_log_path = std::move(path);
return this;
}
PeerConfigurer* PeerConfigurer::SetAecDumpPath(std::string path) {
params_->aec_dump_path = std::move(path);
return this;
}
PeerConfigurer* PeerConfigurer::SetRTCConfiguration(
PeerConnectionInterface::RTCConfiguration configuration) {
params_->rtc_configuration = std::move(configuration);
return this;
}
PeerConfigurer* PeerConfigurer::SetRTCOfferAnswerOptions(
PeerConnectionInterface::RTCOfferAnswerOptions options) {
params_->rtc_offer_answer_options = std::move(options);
return this;
}
PeerConfigurer* PeerConfigurer::SetBitrateSettings(
BitrateSettings bitrate_settings) {
params_->bitrate_settings = bitrate_settings;
return this;
}
PeerConfigurer* PeerConfigurer::SetVideoCodecs(
std::vector<VideoCodecConfig> video_codecs) {
params_->video_codecs = std::move(video_codecs);
return this;
}
PeerConfigurer* PeerConfigurer::SetIceTransportFactory(
std::unique_ptr<IceTransportFactory> factory) {
components_->pc_dependencies->ice_transport_factory = std::move(factory);
return this;
}
PeerConfigurer* PeerConfigurer::SetPortAllocatorExtraFlags(
uint32_t extra_flags) {
params_->port_allocator_extra_flags = extra_flags;
return this;
}
std::unique_ptr<InjectableComponents> PeerConfigurer::ReleaseComponents() {
RTC_CHECK(components_);
auto components = std::move(components_);
components_ = nullptr;
return components;
}
// Returns Params and transfer ownership to the caller.
// Can be called once.
std::unique_ptr<Params> PeerConfigurer::ReleaseParams() {
RTC_CHECK(params_);
auto params = std::move(params_);
params_ = nullptr;
return params;
}
// Returns ConfigurableParams and transfer ownership to the caller.
// Can be called once.
std::unique_ptr<ConfigurableParams>
PeerConfigurer::ReleaseConfigurableParams() {
RTC_CHECK(configurable_params_);
auto configurable_params = std::move(configurable_params_);
configurable_params_ = nullptr;
return configurable_params;
}
// Returns video sources and transfer frame generators ownership to the
// caller. Can be called once.
std::vector<PeerConfigurer::VideoSource> PeerConfigurer::ReleaseVideoSources() {
auto video_sources = std::move(video_sources_);
video_sources_.clear();
return video_sources;
}
} // namespace webrtc_pc_e2e
} // namespace webrtc

View file

@ -0,0 +1,192 @@
/*
* 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.
*/
#ifndef API_TEST_PCLF_PEER_CONFIGURER_H_
#define API_TEST_PCLF_PEER_CONFIGURER_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/strings/string_view.h"
#include "api/async_resolver_factory.h"
#include "api/audio/audio_mixer.h"
#include "api/call/call_factory_interface.h"
#include "api/fec_controller.h"
#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/test/create_peer_connection_quality_test_frame_generator.h"
#include "api/test/pclf/media_configuration.h"
#include "api/test/pclf/media_quality_test_params.h"
#include "api/test/peer_network_dependencies.h"
#include "api/transport/network_control.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/network.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/thread.h"
namespace webrtc {
namespace webrtc_pc_e2e {
// This class is used to fully configure one peer inside a call.
class PeerConfigurer {
public:
using VideoSource =
absl::variant<std::unique_ptr<test::FrameGeneratorInterface>,
CapturingDeviceIndex>;
explicit PeerConfigurer(const PeerNetworkDependencies& network_dependencies);
// Sets peer name that will be used to report metrics related to this peer.
// If not set, some default name will be assigned. All names have to be
// unique.
PeerConfigurer* SetName(absl::string_view name);
// The parameters of the following 9 methods will be passed to the
// PeerConnectionFactoryInterface implementation that will be created for
// this peer.
PeerConfigurer* SetTaskQueueFactory(
std::unique_ptr<TaskQueueFactory> task_queue_factory);
PeerConfigurer* SetCallFactory(
std::unique_ptr<CallFactoryInterface> call_factory);
PeerConfigurer* SetEventLogFactory(
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory);
PeerConfigurer* SetFecControllerFactory(
std::unique_ptr<FecControllerFactoryInterface> fec_controller_factory);
PeerConfigurer* SetNetworkControllerFactory(
std::unique_ptr<NetworkControllerFactoryInterface>
network_controller_factory);
PeerConfigurer* SetVideoEncoderFactory(
std::unique_ptr<VideoEncoderFactory> video_encoder_factory);
PeerConfigurer* SetVideoDecoderFactory(
std::unique_ptr<VideoDecoderFactory> video_decoder_factory);
// Set a custom NetEqFactory to be used in the call.
PeerConfigurer* SetNetEqFactory(std::unique_ptr<NetEqFactory> neteq_factory);
PeerConfigurer* SetAudioProcessing(
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing);
PeerConfigurer* SetAudioMixer(
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer);
// Forces the Peerconnection to use the network thread as the worker thread.
// Ie, worker thread and the network thread is the same thread.
PeerConfigurer* SetUseNetworkThreadAsWorkerThread();
// The parameters of the following 4 methods will be passed to the
// PeerConnectionInterface implementation that will be created for this
// peer.
PeerConfigurer* SetAsyncResolverFactory(
std::unique_ptr<webrtc::AsyncResolverFactory> async_resolver_factory);
PeerConfigurer* SetRTCCertificateGenerator(
std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator);
PeerConfigurer* SetSSLCertificateVerifier(
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier);
PeerConfigurer* SetIceTransportFactory(
std::unique_ptr<IceTransportFactory> factory);
// Flags to set on `cricket::PortAllocator`. These flags will be added
// to the default ones that are presented on the port allocator.
// For possible values check p2p/base/port_allocator.h.
PeerConfigurer* SetPortAllocatorExtraFlags(uint32_t extra_flags);
// Add new video stream to the call that will be sent from this peer.
// Default implementation of video frames generator will be used.
PeerConfigurer* AddVideoConfig(VideoConfig config);
// Add new video stream to the call that will be sent from this peer with
// provided own implementation of video frames generator.
PeerConfigurer* AddVideoConfig(
VideoConfig config,
std::unique_ptr<test::FrameGeneratorInterface> generator);
// Add new video stream to the call that will be sent from this peer.
// Capturing device with specified index will be used to get input video.
PeerConfigurer* AddVideoConfig(VideoConfig config,
CapturingDeviceIndex capturing_device_index);
// Sets video subscription for the peer. By default subscription will
// include all streams with `VideoSubscription::kSameAsSendStream`
// resolution. To this behavior use this method.
PeerConfigurer* SetVideoSubscription(VideoSubscription subscription);
// Set the list of video codecs used by the peer during the test. These
// codecs will be negotiated in SDP during offer/answer exchange. The order
// of these codecs during negotiation will be the same as in `video_codecs`.
// Codecs have to be available in codecs list provided by peer connection to
// be negotiated. If some of specified codecs won't be found, the test will
// crash.
PeerConfigurer* SetVideoCodecs(std::vector<VideoCodecConfig> video_codecs);
// Set the audio stream for the call from this peer. If this method won't
// be invoked, this peer will send no audio.
PeerConfigurer* SetAudioConfig(AudioConfig config);
// Set if ULP FEC should be used or not. False by default.
PeerConfigurer* SetUseUlpFEC(bool value);
// Set if Flex FEC should be used or not. False by default.
// Client also must enable `enable_flex_fec_support` in the `RunParams` to
// be able to use this feature.
PeerConfigurer* SetUseFlexFEC(bool value);
// Specifies how much video encoder target bitrate should be different than
// target bitrate, provided by WebRTC stack. Must be greater than 0. Can be
// used to emulate overshooting of video encoders. This multiplier will
// be applied for all video encoder on both sides for all layers. Bitrate
// estimated by WebRTC stack will be multiplied by this multiplier and then
// provided into VideoEncoder::SetRates(...). 1.0 by default.
PeerConfigurer* SetVideoEncoderBitrateMultiplier(double multiplier);
// If is set, an RTCEventLog will be saved in that location and it will be
// available for further analysis.
PeerConfigurer* SetRtcEventLogPath(std::string path);
// If is set, an AEC dump will be saved in that location and it will be
// available for further analysis.
PeerConfigurer* SetAecDumpPath(std::string path);
PeerConfigurer* SetRTCConfiguration(
PeerConnectionInterface::RTCConfiguration configuration);
PeerConfigurer* SetRTCOfferAnswerOptions(
PeerConnectionInterface::RTCOfferAnswerOptions options);
// Set bitrate parameters on PeerConnection. This constraints will be
// applied to all summed RTP streams for this peer.
PeerConfigurer* SetBitrateSettings(BitrateSettings bitrate_settings);
// Returns InjectableComponents and transfer ownership to the caller.
// Can be called once.
std::unique_ptr<InjectableComponents> ReleaseComponents();
// Returns Params and transfer ownership to the caller.
// Can be called once.
std::unique_ptr<Params> ReleaseParams();
// Returns ConfigurableParams and transfer ownership to the caller.
// Can be called once.
std::unique_ptr<ConfigurableParams> ReleaseConfigurableParams();
// Returns video sources and transfer frame generators ownership to the
// caller. Can be called once.
std::vector<VideoSource> ReleaseVideoSources();
InjectableComponents* components() { return components_.get(); }
Params* params() { return params_.get(); }
ConfigurableParams* configurable_params() {
return configurable_params_.get();
}
const Params& params() const { return *params_; }
const ConfigurableParams& configurable_params() const {
return *configurable_params_;
}
std::vector<VideoSource>* video_sources() { return &video_sources_; }
private:
std::unique_ptr<InjectableComponents> components_;
std::unique_ptr<Params> params_;
std::unique_ptr<ConfigurableParams> configurable_params_;
std::vector<VideoSource> video_sources_;
};
} // namespace webrtc_pc_e2e
} // namespace webrtc
#endif // API_TEST_PCLF_PEER_CONFIGURER_H_

View file

@ -1,240 +0,0 @@
/*
* Copyright 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 "api/test/peerconnection_quality_test_fixture.h"
#include <string>
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/test/video/video_frame_writer.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
#include "test/pc/e2e/analyzer/video/video_dumping.h"
#include "test/testsupport/file_utils.h"
namespace webrtc {
namespace webrtc_pc_e2e {
namespace {
using VideoCodecConfig = ::webrtc::webrtc_pc_e2e::
PeerConnectionE2EQualityTestFixture::VideoCodecConfig;
using VideoSubscription = ::webrtc::webrtc_pc_e2e::
PeerConnectionE2EQualityTestFixture::VideoSubscription;
std::string SpecToString(
PeerConnectionE2EQualityTestFixture::VideoResolution::VideoResolution::Spec
spec) {
switch (spec) {
case PeerConnectionE2EQualityTestFixture::VideoResolution::Spec::kNone:
return "None";
case PeerConnectionE2EQualityTestFixture::VideoResolution::Spec::
kMaxFromSender:
return "MaxFromSender";
}
}
} // namespace
PeerConnectionE2EQualityTestFixture::VideoResolution::VideoResolution(
size_t width,
size_t height,
int32_t fps)
: width_(width), height_(height), fps_(fps), spec_(Spec::kNone) {}
PeerConnectionE2EQualityTestFixture::VideoResolution::VideoResolution(Spec spec)
: width_(0), height_(0), fps_(0), spec_(spec) {}
bool PeerConnectionE2EQualityTestFixture::VideoResolution::operator==(
const VideoResolution& other) const {
if (spec_ != Spec::kNone && spec_ == other.spec_) {
// If there is some particular spec set, then it doesn't matter what
// values we have in other fields.
return true;
}
return width_ == other.width_ && height_ == other.height_ &&
fps_ == other.fps_ && spec_ == other.spec_;
}
std::string PeerConnectionE2EQualityTestFixture::VideoResolution::ToString()
const {
rtc::StringBuilder out;
out << "{ width=" << width_ << ", height=" << height_ << ", fps=" << fps_
<< ", spec=" << SpecToString(spec_) << " }";
return out.Release();
}
bool PeerConnectionE2EQualityTestFixture::VideoSubscription::operator==(
const VideoSubscription& other) const {
return default_resolution_ == other.default_resolution_ &&
peers_resolution_ == other.peers_resolution_;
}
absl::optional<PeerConnectionE2EQualityTestFixture::VideoResolution>
PeerConnectionE2EQualityTestFixture::VideoSubscription::GetMaxResolution(
rtc::ArrayView<const VideoConfig> video_configs) {
std::vector<VideoResolution> resolutions;
for (const auto& video_config : video_configs) {
resolutions.push_back(video_config.GetResolution());
}
return GetMaxResolution(resolutions);
}
absl::optional<PeerConnectionE2EQualityTestFixture::VideoResolution>
PeerConnectionE2EQualityTestFixture::VideoSubscription::GetMaxResolution(
rtc::ArrayView<const VideoResolution> resolutions) {
if (resolutions.empty()) {
return absl::nullopt;
}
VideoResolution max_resolution;
for (const VideoResolution& resolution : resolutions) {
if (max_resolution.width() < resolution.width()) {
max_resolution.set_width(resolution.width());
}
if (max_resolution.height() < resolution.height()) {
max_resolution.set_height(resolution.height());
}
if (max_resolution.fps() < resolution.fps()) {
max_resolution.set_fps(resolution.fps());
}
}
return max_resolution;
}
std::string PeerConnectionE2EQualityTestFixture::VideoSubscription::ToString()
const {
rtc::StringBuilder out;
out << "{ default_resolution_=[";
if (default_resolution_.has_value()) {
out << default_resolution_->ToString();
} else {
out << "undefined";
}
out << "], {";
for (const auto& [peer_name, resolution] : peers_resolution_) {
out << "[" << peer_name << ": " << resolution.ToString() << "], ";
}
out << "} }";
return out.Release();
}
PeerConnectionE2EQualityTestFixture::VideoDumpOptions::VideoDumpOptions(
absl::string_view output_directory,
int sampling_modulo,
bool export_frame_ids,
std::function<std::unique_ptr<test::VideoFrameWriter>(
absl::string_view file_name_prefix,
const VideoResolution& resolution)> video_frame_writer_factory)
: output_directory_(output_directory),
sampling_modulo_(sampling_modulo),
export_frame_ids_(export_frame_ids),
video_frame_writer_factory_(video_frame_writer_factory) {
RTC_CHECK_GT(sampling_modulo, 0);
}
PeerConnectionE2EQualityTestFixture::VideoDumpOptions::VideoDumpOptions(
absl::string_view output_directory,
bool export_frame_ids)
: VideoDumpOptions(output_directory,
kDefaultSamplingModulo,
export_frame_ids) {}
std::unique_ptr<test::VideoFrameWriter> PeerConnectionE2EQualityTestFixture::
VideoDumpOptions::CreateInputDumpVideoFrameWriter(
absl::string_view stream_label,
const VideoResolution& resolution) const {
std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
GetInputDumpFileName(stream_label), resolution);
absl::optional<std::string> frame_ids_file =
GetInputFrameIdsDumpFileName(stream_label);
if (frame_ids_file.has_value()) {
writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
}
return writer;
}
std::unique_ptr<test::VideoFrameWriter> PeerConnectionE2EQualityTestFixture::
VideoDumpOptions::CreateOutputDumpVideoFrameWriter(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const {
std::unique_ptr<test::VideoFrameWriter> writer = video_frame_writer_factory_(
GetOutputDumpFileName(stream_label, receiver), resolution);
absl::optional<std::string> frame_ids_file =
GetOutputFrameIdsDumpFileName(stream_label, receiver);
if (frame_ids_file.has_value()) {
writer = CreateVideoFrameWithIdsWriter(std::move(writer), *frame_ids_file);
}
return writer;
}
std::unique_ptr<test::VideoFrameWriter> PeerConnectionE2EQualityTestFixture::
VideoDumpOptions::Y4mVideoFrameWriterFactory(
absl::string_view file_name_prefix,
const VideoResolution& resolution) {
return std::make_unique<test::Y4mVideoFrameWriterImpl>(
std::string(file_name_prefix) + ".y4m", resolution.width(),
resolution.height(), resolution.fps());
}
std::string
PeerConnectionE2EQualityTestFixture::VideoDumpOptions::GetInputDumpFileName(
absl::string_view stream_label) const {
return test::JoinFilename(output_directory_, stream_label);
}
absl::optional<std::string> PeerConnectionE2EQualityTestFixture::
VideoDumpOptions::GetInputFrameIdsDumpFileName(
absl::string_view stream_label) const {
if (!export_frame_ids_) {
return absl::nullopt;
}
return GetInputDumpFileName(stream_label) + ".frame_ids.txt";
}
std::string
PeerConnectionE2EQualityTestFixture::VideoDumpOptions::GetOutputDumpFileName(
absl::string_view stream_label,
absl::string_view receiver) const {
rtc::StringBuilder file_name;
file_name << stream_label << "_" << receiver;
return test::JoinFilename(output_directory_, file_name.Release());
}
absl::optional<std::string> PeerConnectionE2EQualityTestFixture::
VideoDumpOptions::GetOutputFrameIdsDumpFileName(
absl::string_view stream_label,
absl::string_view receiver) const {
if (!export_frame_ids_) {
return absl::nullopt;
}
return GetOutputDumpFileName(stream_label, receiver) + ".frame_ids.txt";
}
std::string PeerConnectionE2EQualityTestFixture::VideoDumpOptions::ToString()
const {
rtc::StringBuilder out;
out << "{ output_directory_=" << output_directory_
<< ", sampling_modulo_=" << sampling_modulo_
<< ", export_frame_ids_=" << export_frame_ids_ << " }";
return out.Release();
}
PeerConnectionE2EQualityTestFixture::VideoConfig::VideoConfig(
const VideoResolution& resolution)
: width(resolution.width()),
height(resolution.height()),
fps(resolution.fps()) {
RTC_CHECK(resolution.IsRegular());
}
} // namespace webrtc_pc_e2e
} // namespace webrtc

View file

@ -10,12 +10,17 @@
#ifndef API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_ #ifndef API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
#define API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_ #define API_TEST_PEERCONNECTION_QUALITY_TEST_FIXTURE_H_
#include <stddef.h>
#include <stdint.h>
#include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "absl/base/macros.h"
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/optional.h" #include "absl/types/optional.h"
@ -32,6 +37,9 @@
#include "api/task_queue/task_queue_factory.h" #include "api/task_queue/task_queue_factory.h"
#include "api/test/audio_quality_analyzer_interface.h" #include "api/test/audio_quality_analyzer_interface.h"
#include "api/test/frame_generator_interface.h" #include "api/test/frame_generator_interface.h"
#include "api/test/pclf/media_configuration.h"
#include "api/test/pclf/media_quality_test_params.h"
#include "api/test/pclf/peer_configurer.h"
#include "api/test/peer_network_dependencies.h" #include "api/test/peer_network_dependencies.h"
#include "api/test/simulated_network.h" #include "api/test/simulated_network.h"
#include "api/test/stats_observer_interface.h" #include "api/test/stats_observer_interface.h"
@ -45,6 +53,7 @@
#include "api/video_codecs/video_encoder_factory.h" #include "api/video_codecs/video_encoder_factory.h"
#include "media/base/media_constants.h" #include "media/base/media_constants.h"
#include "modules/audio_processing/include/audio_processing.h" #include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/checks.h"
#include "rtc_base/network.h" #include "rtc_base/network.h"
#include "rtc_base/rtc_certificate_generator.h" #include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/ssl_certificate.h" #include "rtc_base/ssl_certificate.h"
@ -53,623 +62,9 @@
namespace webrtc { namespace webrtc {
namespace webrtc_pc_e2e { namespace webrtc_pc_e2e {
constexpr size_t kDefaultSlidesWidth = 1850;
constexpr size_t kDefaultSlidesHeight = 1110;
// API is in development. Can be changed/removed without notice. // API is in development. Can be changed/removed without notice.
class PeerConnectionE2EQualityTestFixture { class PeerConnectionE2EQualityTestFixture {
public: public:
// The index of required capturing device in OS provided list of video
// devices. On Linux and Windows the list will be obtained via
// webrtc::VideoCaptureModule::DeviceInfo, on Mac OS via
// [RTCCameraVideoCapturer captureDevices].
enum class CapturingDeviceIndex : size_t {};
// Contains parameters for screen share scrolling.
//
// If scrolling is enabled, then it will be done by putting sliding window
// on source video and moving this window from top left corner to the
// bottom right corner of the picture.
//
// In such case source dimensions must be greater or equal to the sliding
// window dimensions. So `source_width` and `source_height` are the dimensions
// of the source frame, while `VideoConfig::width` and `VideoConfig::height`
// are the dimensions of the sliding window.
//
// Because `source_width` and `source_height` are dimensions of the source
// frame, they have to be width and height of videos from
// `ScreenShareConfig::slides_yuv_file_names`.
//
// Because scrolling have to be done on single slide it also requires, that
// `duration` must be less or equal to
// `ScreenShareConfig::slide_change_interval`.
struct ScrollingParams {
ScrollingParams(TimeDelta duration,
size_t source_width,
size_t source_height)
: duration(duration),
source_width(source_width),
source_height(source_height) {
RTC_CHECK_GT(duration.ms(), 0);
}
// Duration of scrolling.
TimeDelta duration;
// Width of source slides video.
size_t source_width;
// Height of source slides video.
size_t source_height;
};
// Contains screen share video stream properties.
struct ScreenShareConfig {
explicit ScreenShareConfig(TimeDelta slide_change_interval)
: slide_change_interval(slide_change_interval) {
RTC_CHECK_GT(slide_change_interval.ms(), 0);
}
// Shows how long one slide should be presented on the screen during
// slide generation.
TimeDelta slide_change_interval;
// If true, slides will be generated programmatically. No scrolling params
// will be applied in such case.
bool generate_slides = false;
// If present scrolling will be applied. Please read extra requirement on
// `slides_yuv_file_names` for scrolling.
absl::optional<ScrollingParams> scrolling_params;
// Contains list of yuv files with slides.
//
// If empty, default set of slides will be used. In such case
// `VideoConfig::width` must be equal to `kDefaultSlidesWidth` and
// `VideoConfig::height` must be equal to `kDefaultSlidesHeight` or if
// `scrolling_params` are specified, then `ScrollingParams::source_width`
// must be equal to `kDefaultSlidesWidth` and
// `ScrollingParams::source_height` must be equal to `kDefaultSlidesHeight`.
std::vector<std::string> slides_yuv_file_names;
};
// Config for Vp8 simulcast or non-standard Vp9 SVC testing.
//
// To configure standard SVC setting, use `scalability_mode` in the
// `encoding_params` array.
// This configures Vp9 SVC by requesting simulcast layers, the request is
// internally converted to a request for SVC layers.
//
// SVC support is limited:
// During SVC testing there is no SFU, so framework will try to emulate SFU
// behavior in regular p2p call. Because of it there are such limitations:
// * if `target_spatial_index` is not equal to the highest spatial layer
// then no packet/frame drops are allowed.
//
// If there will be any drops, that will affect requested layer, then
// WebRTC SVC implementation will continue decoding only the highest
// available layer and won't restore lower layers, so analyzer won't
// receive required data which will cause wrong results or test failures.
struct VideoSimulcastConfig {
explicit VideoSimulcastConfig(int simulcast_streams_count)
: simulcast_streams_count(simulcast_streams_count) {
RTC_CHECK_GT(simulcast_streams_count, 1);
}
// Specified amount of simulcast streams/SVC layers, depending on which
// encoder is used.
int simulcast_streams_count;
};
// Configuration for the emulated Selective Forward Unit (SFU)
//
// The framework can optionally filter out frames that are decoded
// using an emulated SFU.
// When using simulcast or SVC, it's not always desirable to receive
// all frames. In a real world call, a SFU will only forward a subset
// of the frames.
// The emulated SFU is not able to change its configuration dynamically,
// if adaptation happens during the call, layers may be dropped and the
// analyzer won't receive the required data which will cause wrong results or
// test failures.
struct EmulatedSFUConfig {
EmulatedSFUConfig() {}
explicit EmulatedSFUConfig(int target_layer_index)
: target_layer_index(target_layer_index) {
RTC_CHECK_GE(target_layer_index, 0);
}
EmulatedSFUConfig(absl::optional<int> target_layer_index,
absl::optional<int> target_temporal_index)
: target_layer_index(target_layer_index),
target_temporal_index(target_temporal_index) {
RTC_CHECK_GE(target_temporal_index.value_or(0), 0);
if (target_temporal_index)
RTC_CHECK_GE(*target_temporal_index, 0);
}
// Specifies simulcast or spatial index of the video stream to analyze.
// There are 2 cases:
// 1. simulcast encoding is used:
// in such case `target_layer_index` will specify the index of
// simulcast stream, that should be analyzed. Other streams will be
// dropped.
// 2. SVC encoding is used:
// in such case `target_layer_index` will specify the top interesting
// spatial layer and all layers below, including target one will be
// processed. All layers above target one will be dropped.
// If not specified then all streams will be received and analyzed.
// When set, it instructs the framework to create an emulated Selective
// Forwarding Unit (SFU) that will propagate only the requested layers.
absl::optional<int> target_layer_index;
// Specifies the index of the maximum temporal unit to keep.
// If not specified then all temporal layers will be received and analyzed.
// When set, it instructs the framework to create an emulated Selective
// Forwarding Unit (SFU) that will propagate only up to the requested layer.
absl::optional<int> target_temporal_index;
};
class VideoResolution {
public:
// Determines special resolutions, which can't be expressed in terms of
// width, height and fps.
enum class Spec {
// No extra spec set. It describes a regular resolution described by
// width, height and fps.
kNone,
// Describes resolution which contains max value among all sender's
// video streams in each dimension (width, height, fps).
kMaxFromSender
};
VideoResolution(size_t width, size_t height, int32_t fps);
explicit VideoResolution(Spec spec = Spec::kNone);
bool operator==(const VideoResolution& other) const;
bool operator!=(const VideoResolution& other) const {
return !(*this == other);
}
size_t width() const { return width_; }
void set_width(size_t width) { width_ = width; }
size_t height() const { return height_; }
void set_height(size_t height) { height_ = height; }
int32_t fps() const { return fps_; }
void set_fps(int32_t fps) { fps_ = fps; }
// Returns if it is a regular resolution or not. The resolution is regular
// if it's spec is `Spec::kNone`.
bool IsRegular() const { return spec_ == Spec::kNone; }
std::string ToString() const;
private:
size_t width_ = 0;
size_t height_ = 0;
int32_t fps_ = 0;
Spec spec_ = Spec::kNone;
};
class VideoDumpOptions {
public:
static constexpr int kDefaultSamplingModulo = 1;
// output_directory - the output directory where stream will be dumped. The
// output files' names will be constructed as
// <stream_name>_<receiver_name>.<extension> for output dumps and
// <stream_name>.<extension> for input dumps. By default <extension> is
// "y4m".
// sampling_modulo - the module for the video frames to be dumped. Modulo
// equals X means every Xth frame will be written to the dump file. The
// value must be greater than 0. (Default: 1)
// export_frame_ids - specifies if frame ids should be exported together
// with content of the stream. If true, an output file with the same name as
// video dump and suffix ".frame_ids.txt" will be created. It will contain
// the frame ids in the same order as original frames in the output
// file with stream content. File will contain one frame id per line.
// (Default: false)
// `video_frame_writer_factory` - factory function to create a video frame
// writer for input and output video files. (Default: Y4M video writer
// factory).
explicit VideoDumpOptions(
absl::string_view output_directory,
int sampling_modulo = kDefaultSamplingModulo,
bool export_frame_ids = false,
std::function<std::unique_ptr<test::VideoFrameWriter>(
absl::string_view file_name_prefix,
const VideoResolution& resolution)> video_frame_writer_factory =
Y4mVideoFrameWriterFactory);
VideoDumpOptions(absl::string_view output_directory, bool export_frame_ids);
VideoDumpOptions(const VideoDumpOptions&) = default;
VideoDumpOptions& operator=(const VideoDumpOptions&) = default;
VideoDumpOptions(VideoDumpOptions&&) = default;
VideoDumpOptions& operator=(VideoDumpOptions&&) = default;
std::string output_directory() const { return output_directory_; }
int sampling_modulo() const { return sampling_modulo_; }
bool export_frame_ids() const { return export_frame_ids_; }
std::unique_ptr<test::VideoFrameWriter> CreateInputDumpVideoFrameWriter(
absl::string_view stream_label,
const VideoResolution& resolution) const;
std::unique_ptr<test::VideoFrameWriter> CreateOutputDumpVideoFrameWriter(
absl::string_view stream_label,
absl::string_view receiver,
const VideoResolution& resolution) const;
std::string ToString() const;
private:
static std::unique_ptr<test::VideoFrameWriter> Y4mVideoFrameWriterFactory(
absl::string_view file_name_prefix,
const VideoResolution& resolution);
std::string GetInputDumpFileName(absl::string_view stream_label) const;
// Returns file name for input frame ids dump if `export_frame_ids()` is
// true, absl::nullopt otherwise.
absl::optional<std::string> GetInputFrameIdsDumpFileName(
absl::string_view stream_label) const;
std::string GetOutputDumpFileName(absl::string_view stream_label,
absl::string_view receiver) const;
// Returns file name for output frame ids dump if `export_frame_ids()` is
// true, absl::nullopt otherwise.
absl::optional<std::string> GetOutputFrameIdsDumpFileName(
absl::string_view stream_label,
absl::string_view receiver) const;
std::string output_directory_;
int sampling_modulo_ = 1;
bool export_frame_ids_ = false;
std::function<std::unique_ptr<test::VideoFrameWriter>(
absl::string_view file_name_prefix,
const VideoResolution& resolution)>
video_frame_writer_factory_;
};
// Contains properties of single video stream.
struct VideoConfig {
explicit VideoConfig(const VideoResolution& resolution);
VideoConfig(size_t width, size_t height, int32_t fps)
: width(width), height(height), fps(fps) {}
VideoConfig(std::string stream_label,
size_t width,
size_t height,
int32_t fps)
: width(width),
height(height),
fps(fps),
stream_label(std::move(stream_label)) {}
// Video stream width.
size_t width;
// Video stream height.
size_t height;
int32_t fps;
VideoResolution GetResolution() const {
return VideoResolution(width, height, fps);
}
// Have to be unique among all specified configs for all peers in the call.
// Will be auto generated if omitted.
absl::optional<std::string> stream_label;
// Will be set for current video track. If equals to kText or kDetailed -
// screencast in on.
absl::optional<VideoTrackInterface::ContentHint> content_hint;
// If presented video will be transfered in simulcast/SVC mode depending on
// which encoder is used.
//
// Simulcast is supported only from 1st added peer. For VP8 simulcast only
// without RTX is supported so it will be automatically disabled for all
// simulcast tracks. For VP9 simulcast enables VP9 SVC mode and support RTX,
// but only on non-lossy networks. See more in documentation to
// VideoSimulcastConfig.
absl::optional<VideoSimulcastConfig> simulcast_config;
// Configuration for the emulated Selective Forward Unit (SFU).
absl::optional<EmulatedSFUConfig> emulated_sfu_config;
// Encoding parameters for both singlecast and per simulcast layer.
// If singlecast is used, if not empty, a single value can be provided.
// If simulcast is used, if not empty, `encoding_params` size have to be
// equal to `simulcast_config.simulcast_streams_count`. Will be used to set
// transceiver send encoding params for each layer.
// RtpEncodingParameters::rid may be changed by fixture implementation to
// ensure signaling correctness.
std::vector<RtpEncodingParameters> encoding_params;
// Count of temporal layers for video stream. This value will be set into
// each RtpEncodingParameters of RtpParameters of corresponding
// RtpSenderInterface for this video stream.
absl::optional<int> temporal_layers_count;
// If specified defines how input should be dumped. It is actually one of
// the test's output file, which contains copy of what was captured during
// the test for this video stream on sender side. It is useful when
// generator is used as input.
absl::optional<VideoDumpOptions> input_dump_options;
// If specified defines how output should be dumped on the receiver side for
// this stream. The produced files contain what was rendered for this video
// stream on receiver side per each receiver.
absl::optional<VideoDumpOptions> output_dump_options;
// If set to true uses fixed frame rate while dumping output video to the
// file. `fps` will be used as frame rate.
bool output_dump_use_fixed_framerate = false;
// If true will display input and output video on the user's screen.
bool show_on_screen = false;
// If specified, determines a sync group to which this video stream belongs.
// According to bugs.webrtc.org/4762 WebRTC supports synchronization only
// for pair of single audio and single video stream.
absl::optional<std::string> sync_group;
// If specified, it will be set into RtpParameters of corresponding
// RtpSenderInterface for this video stream.
// Note that this setting takes precedence over `content_hint`.
absl::optional<DegradationPreference> degradation_preference;
};
// Contains properties for audio in the call.
struct AudioConfig {
enum Mode {
kGenerated,
kFile,
};
AudioConfig() = default;
explicit AudioConfig(std::string stream_label)
: stream_label(std::move(stream_label)) {}
// Have to be unique among all specified configs for all peers in the call.
// Will be auto generated if omitted.
absl::optional<std::string> stream_label;
Mode mode = kGenerated;
// Have to be specified only if mode = kFile
absl::optional<std::string> input_file_name;
// If specified the input stream will be also copied to specified file.
absl::optional<std::string> input_dump_file_name;
// If specified the output stream will be copied to specified file.
absl::optional<std::string> output_dump_file_name;
// Audio options to use.
cricket::AudioOptions audio_options;
// Sampling frequency of input audio data (from file or generated).
int sampling_frequency_in_hz = 48000;
// If specified, determines a sync group to which this audio stream belongs.
// According to bugs.webrtc.org/4762 WebRTC supports synchronization only
// for pair of single audio and single video stream.
absl::optional<std::string> sync_group;
};
struct VideoCodecConfig {
explicit VideoCodecConfig(std::string name)
: name(std::move(name)), required_params() {}
VideoCodecConfig(std::string name,
std::map<std::string, std::string> required_params)
: name(std::move(name)), required_params(std::move(required_params)) {}
// Next two fields are used to specify concrete video codec, that should be
// used in the test. Video code will be negotiated in SDP during offer/
// answer exchange.
// Video codec name. You can find valid names in
// media/base/media_constants.h
std::string name = cricket::kVp8CodecName;
// Map of parameters, that have to be specified on SDP codec. Each parameter
// is described by key and value. Codec parameters will match the specified
// map if and only if for each key from `required_params` there will be
// a parameter with name equal to this key and parameter value will be equal
// to the value from `required_params` for this key.
// If empty then only name will be used to match the codec.
std::map<std::string, std::string> required_params;
};
// Subscription to the remote video streams. It declares which remote stream
// peer should receive and in which resolution (width x height x fps).
class VideoSubscription {
public:
// Returns the resolution constructed as maximum from all resolution
// dimensions: width, height and fps.
static absl::optional<VideoResolution> GetMaxResolution(
rtc::ArrayView<const VideoConfig> video_configs);
static absl::optional<VideoResolution> GetMaxResolution(
rtc::ArrayView<const VideoResolution> resolutions);
bool operator==(const VideoSubscription& other) const;
bool operator!=(const VideoSubscription& other) const {
return !(*this == other);
}
// Subscribes receiver to all streams sent by the specified peer with
// specified resolution. It will override any resolution that was used in
// `SubscribeToAll` independently from methods call order.
VideoSubscription& SubscribeToPeer(
absl::string_view peer_name,
VideoResolution resolution =
VideoResolution(VideoResolution::Spec::kMaxFromSender)) {
peers_resolution_[std::string(peer_name)] = resolution;
return *this;
}
// Subscribes receiver to the all sent streams with specified resolution.
// If any stream was subscribed to with `SubscribeTo` method that will
// override resolution passed to this function independently from methods
// call order.
VideoSubscription& SubscribeToAllPeers(
VideoResolution resolution =
VideoResolution(VideoResolution::Spec::kMaxFromSender)) {
default_resolution_ = resolution;
return *this;
}
// Returns resolution for specific sender. If no specific resolution was
// set for this sender, then will return resolution used for all streams.
// If subscription doesn't subscribe to all streams, `absl::nullopt` will be
// returned.
absl::optional<VideoResolution> GetResolutionForPeer(
absl::string_view peer_name) const {
auto it = peers_resolution_.find(std::string(peer_name));
if (it == peers_resolution_.end()) {
return default_resolution_;
}
return it->second;
}
// Returns a maybe empty list of senders for which peer explicitly
// subscribed to with specific resolution.
std::vector<std::string> GetSubscribedPeers() const {
std::vector<std::string> subscribed_streams;
subscribed_streams.reserve(peers_resolution_.size());
for (const auto& entry : peers_resolution_) {
subscribed_streams.push_back(entry.first);
}
return subscribed_streams;
}
std::string ToString() const;
private:
absl::optional<VideoResolution> default_resolution_ = absl::nullopt;
std::map<std::string, VideoResolution> peers_resolution_;
};
// This class is used to fully configure one peer inside the call.
class PeerConfigurer {
public:
virtual ~PeerConfigurer() = default;
// Sets peer name that will be used to report metrics related to this peer.
// If not set, some default name will be assigned. All names have to be
// unique.
virtual PeerConfigurer* SetName(absl::string_view name) = 0;
// The parameters of the following 9 methods will be passed to the
// PeerConnectionFactoryInterface implementation that will be created for
// this peer.
virtual PeerConfigurer* SetTaskQueueFactory(
std::unique_ptr<TaskQueueFactory> task_queue_factory) = 0;
virtual PeerConfigurer* SetCallFactory(
std::unique_ptr<CallFactoryInterface> call_factory) = 0;
virtual PeerConfigurer* SetEventLogFactory(
std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory) = 0;
virtual PeerConfigurer* SetFecControllerFactory(
std::unique_ptr<FecControllerFactoryInterface>
fec_controller_factory) = 0;
virtual PeerConfigurer* SetNetworkControllerFactory(
std::unique_ptr<NetworkControllerFactoryInterface>
network_controller_factory) = 0;
virtual PeerConfigurer* SetVideoEncoderFactory(
std::unique_ptr<VideoEncoderFactory> video_encoder_factory) = 0;
virtual PeerConfigurer* SetVideoDecoderFactory(
std::unique_ptr<VideoDecoderFactory> video_decoder_factory) = 0;
// Set a custom NetEqFactory to be used in the call.
virtual PeerConfigurer* SetNetEqFactory(
std::unique_ptr<NetEqFactory> neteq_factory) = 0;
virtual PeerConfigurer* SetAudioProcessing(
rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing) = 0;
virtual PeerConfigurer* SetAudioMixer(
rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer) = 0;
// Forces the Peerconnection to use the network thread as the worker thread.
// Ie, worker thread and the network thread is the same thread.
virtual PeerConfigurer* SetUseNetworkThreadAsWorkerThread() = 0;
// The parameters of the following 4 methods will be passed to the
// PeerConnectionInterface implementation that will be created for this
// peer.
virtual PeerConfigurer* SetAsyncResolverFactory(
std::unique_ptr<webrtc::AsyncResolverFactory>
async_resolver_factory) = 0;
virtual PeerConfigurer* SetRTCCertificateGenerator(
std::unique_ptr<rtc::RTCCertificateGeneratorInterface>
cert_generator) = 0;
virtual PeerConfigurer* SetSSLCertificateVerifier(
std::unique_ptr<rtc::SSLCertificateVerifier> tls_cert_verifier) = 0;
virtual PeerConfigurer* SetIceTransportFactory(
std::unique_ptr<IceTransportFactory> factory) = 0;
// Flags to set on `cricket::PortAllocator`. These flags will be added
// to the default ones that are presented on the port allocator.
// For possible values check p2p/base/port_allocator.h.
virtual PeerConfigurer* SetPortAllocatorExtraFlags(
uint32_t extra_flags) = 0;
// Add new video stream to the call that will be sent from this peer.
// Default implementation of video frames generator will be used.
virtual PeerConfigurer* AddVideoConfig(VideoConfig config) = 0;
// Add new video stream to the call that will be sent from this peer with
// provided own implementation of video frames generator.
virtual PeerConfigurer* AddVideoConfig(
VideoConfig config,
std::unique_ptr<test::FrameGeneratorInterface> generator) = 0;
// Add new video stream to the call that will be sent from this peer.
// Capturing device with specified index will be used to get input video.
virtual PeerConfigurer* AddVideoConfig(
VideoConfig config,
CapturingDeviceIndex capturing_device_index) = 0;
// Sets video subscription for the peer. By default subscription will
// include all streams with `VideoSubscription::kSameAsSendStream`
// resolution. To override this behavior use this method.
virtual PeerConfigurer* SetVideoSubscription(
VideoSubscription subscription) = 0;
// Set the list of video codecs used by the peer during the test. These
// codecs will be negotiated in SDP during offer/answer exchange. The order
// of these codecs during negotiation will be the same as in `video_codecs`.
// Codecs have to be available in codecs list provided by peer connection to
// be negotiated. If some of specified codecs won't be found, the test will
// crash.
virtual PeerConfigurer* SetVideoCodecs(
std::vector<VideoCodecConfig> video_codecs) = 0;
// Set the audio stream for the call from this peer. If this method won't
// be invoked, this peer will send no audio.
virtual PeerConfigurer* SetAudioConfig(AudioConfig config) = 0;
// Set if ULP FEC should be used or not. False by default.
virtual PeerConfigurer* SetUseUlpFEC(bool value) = 0;
// Set if Flex FEC should be used or not. False by default.
// Client also must enable `enable_flex_fec_support` in the `RunParams` to
// be able to use this feature.
virtual PeerConfigurer* SetUseFlexFEC(bool value) = 0;
// Specifies how much video encoder target bitrate should be different than
// target bitrate, provided by WebRTC stack. Must be greater than 0. Can be
// used to emulate overshooting of video encoders. This multiplier will
// be applied for all video encoder on both sides for all layers. Bitrate
// estimated by WebRTC stack will be multiplied by this multiplier and then
// provided into VideoEncoder::SetRates(...). 1.0 by default.
virtual PeerConfigurer* SetVideoEncoderBitrateMultiplier(
double multiplier) = 0;
// If is set, an RTCEventLog will be saved in that location and it will be
// available for further analysis.
virtual PeerConfigurer* SetRtcEventLogPath(std::string path) = 0;
// If is set, an AEC dump will be saved in that location and it will be
// available for further analysis.
virtual PeerConfigurer* SetAecDumpPath(std::string path) = 0;
virtual PeerConfigurer* SetRTCConfiguration(
PeerConnectionInterface::RTCConfiguration configuration) = 0;
virtual PeerConfigurer* SetRTCOfferAnswerOptions(
PeerConnectionInterface::RTCOfferAnswerOptions options) = 0;
// Set bitrate parameters on PeerConnection. This constraints will be
// applied to all summed RTP streams for this peer.
virtual PeerConfigurer* SetBitrateSettings(
BitrateSettings bitrate_settings) = 0;
};
// Contains configuration for echo emulator.
struct EchoEmulationConfig {
// Delay which represents the echo path delay, i.e. how soon rendered signal
// should reach capturer.
TimeDelta echo_delay = TimeDelta::Millis(50);
};
// Contains parameters, that describe how long framework should run quality
// test.
struct RunParams {
explicit RunParams(TimeDelta run_duration) : run_duration(run_duration) {}
// Specifies how long the test should be run. This time shows how long
// the media should flow after connection was established and before
// it will be shut downed.
TimeDelta run_duration;
// If set to true peers will be able to use Flex FEC, otherwise they won't
// be able to negotiate it even if it's enabled on per peer level.
bool enable_flex_fec_support = false;
// If true will set conference mode in SDP media section for all video
// tracks for all peers.
bool use_conference_mode = false;
// If specified echo emulation will be done, by mixing the render audio into
// the capture signal. In such case input signal will be reduced by half to
// avoid saturation or compression in the echo path simulation.
absl::optional<EchoEmulationConfig> echo_emulation_config;
};
// Represent an entity that will report quality metrics after test. // Represent an entity that will report quality metrics after test.
class QualityMetricsReporter : public StatsObserverInterface { class QualityMetricsReporter : public StatsObserverInterface {
public: public:
@ -723,9 +118,7 @@ class PeerConnectionE2EQualityTestFixture {
// `network_dependencies` are used to provide networking for peer's peer // `network_dependencies` are used to provide networking for peer's peer
// connection. Members must be non-null. // connection. Members must be non-null.
// `configurer` function will be used to configure peer in the call. // `configurer` function will be used to configure peer in the call.
virtual PeerHandle* AddPeer( virtual PeerHandle* AddPeer(std::unique_ptr<PeerConfigurer> configurer) = 0;
const PeerNetworkDependencies& network_dependencies,
rtc::FunctionView<void(PeerConfigurer*)> configurer) = 0;
// Runs the media quality test, which includes setting up the call with // Runs the media quality test, which includes setting up the call with
// configured participants, running it according to provided `run_params` and // configured participants, running it according to provided `run_params` and

View file

@ -13,19 +13,17 @@
#include <vector> #include <vector>
#include "absl/types/optional.h" #include "absl/types/optional.h"
#include "api/test/pclf/media_configuration.h"
#include "api/test/video/video_frame_writer.h"
#include "rtc_base/gunit.h" #include "rtc_base/gunit.h"
#include "test/gmock.h" #include "test/gmock.h"
#include "test/testsupport/file_utils.h"
namespace webrtc { namespace webrtc {
namespace webrtc_pc_e2e { namespace webrtc_pc_e2e {
namespace { namespace {
using VideoResolution = ::webrtc::webrtc_pc_e2e:: using ::testing::Eq;
PeerConnectionE2EQualityTestFixture::VideoResolution;
using VideoConfig =
::webrtc::webrtc_pc_e2e::PeerConnectionE2EQualityTestFixture::VideoConfig;
using VideoSubscription = ::webrtc::webrtc_pc_e2e::
PeerConnectionE2EQualityTestFixture::VideoSubscription;
TEST(PclfVideoSubscriptionTest, TEST(PclfVideoSubscriptionTest,
MaxFromSenderSpecEqualIndependentOfOtherFields) { MaxFromSenderSpecEqualIndependentOfOtherFields) {
@ -78,6 +76,67 @@ TEST(PclfVideoSubscriptionTest, GetMaxResolutionSelectMaxForEachDimention) {
EXPECT_EQ(resolution->fps(), 10); EXPECT_EQ(resolution->fps(), 10);
} }
struct TestVideoFrameWriter : public test::VideoFrameWriter {
public:
TestVideoFrameWriter(absl::string_view file_name_prefix,
const VideoResolution& resolution)
: file_name_prefix(file_name_prefix), resolution(resolution) {}
bool WriteFrame(const VideoFrame& frame) override { return true; }
void Close() override {}
std::string file_name_prefix;
VideoResolution resolution;
};
TEST(VideoDumpOptionsTest, InputVideoWriterHasCorrectFileName) {
VideoResolution resolution(/*width=*/1280, /*height=*/720, /*fps=*/30);
TestVideoFrameWriter* writer = nullptr;
VideoDumpOptions options("foo", /*sampling_modulo=*/1,
/*export_frame_ids=*/false,
/*video_frame_writer_factory=*/
[&](absl::string_view file_name_prefix,
const VideoResolution& resolution) {
auto out = std::make_unique<TestVideoFrameWriter>(
file_name_prefix, resolution);
writer = out.get();
return out;
});
std::unique_ptr<test::VideoFrameWriter> created_writer =
options.CreateInputDumpVideoFrameWriter("alice-video", resolution);
ASSERT_TRUE(writer != nullptr);
ASSERT_THAT(writer->file_name_prefix,
Eq(test::JoinFilename("foo", "alice-video_1280x720_30")));
ASSERT_THAT(writer->resolution, Eq(resolution));
}
TEST(VideoDumpOptionsTest, OutputVideoWriterHasCorrectFileName) {
VideoResolution resolution(/*width=*/1280, /*height=*/720, /*fps=*/30);
TestVideoFrameWriter* writer = nullptr;
VideoDumpOptions options("foo", /*sampling_modulo=*/1,
/*export_frame_ids=*/false,
/*video_frame_writer_factory=*/
[&](absl::string_view file_name_prefix,
const VideoResolution& resolution) {
auto out = std::make_unique<TestVideoFrameWriter>(
file_name_prefix, resolution);
writer = out.get();
return out;
});
std::unique_ptr<test::VideoFrameWriter> created_writer =
options.CreateOutputDumpVideoFrameWriter("alice-video", "bob",
resolution);
ASSERT_TRUE(writer != nullptr);
ASSERT_THAT(writer->file_name_prefix,
Eq(test::JoinFilename("foo", "alice-video_bob_1280x720_30")));
ASSERT_THAT(writer->resolution, Eq(resolution));
}
} // namespace } // namespace
} // namespace webrtc_pc_e2e } // namespace webrtc_pc_e2e
} // namespace webrtc } // namespace webrtc

View file

@ -38,6 +38,12 @@ struct PacketDeliveryInfo {
static constexpr int kNotReceived = -1; static constexpr int kNotReceived = -1;
PacketDeliveryInfo(PacketInFlightInfo source, int64_t receive_time_us) PacketDeliveryInfo(PacketInFlightInfo source, int64_t receive_time_us)
: receive_time_us(receive_time_us), packet_id(source.packet_id) {} : receive_time_us(receive_time_us), packet_id(source.packet_id) {}
bool operator==(const PacketDeliveryInfo& other) const {
return receive_time_us == other.receive_time_us &&
packet_id == other.packet_id;
}
int64_t receive_time_us; int64_t receive_time_us;
uint64_t packet_id; uint64_t packet_id;
}; };
@ -64,14 +70,50 @@ struct BuiltInNetworkBehaviorConfig {
int packet_overhead = 0; int packet_overhead = 0;
}; };
// Interface that represents a Network behaviour.
//
// It is clients of this interface responsibility to enqueue and dequeue
// packets (based on the estimated delivery time expressed by
// NextDeliveryTimeUs).
//
// To enqueue packets, call EnqueuePacket:
// EXPECT_TRUE(network.EnqueuePacket(
// PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/1)));
//
// To know when to call DequeueDeliverablePackets to pull packets out of the
// network, call NextDeliveryTimeUs and schedule a task to invoke
// DequeueDeliverablePackets (if not already scheduled).
//
// DequeueDeliverablePackets will return a vector of delivered packets, but this
// vector can be empty in case of extra delay. In such case, make sure to invoke
// NextDeliveryTimeUs and schedule a task to call DequeueDeliverablePackets for
// the next estimated delivery of packets.
//
// std::vector<PacketDeliveryInfo> delivered_packets =
// network.DequeueDeliverablePackets(/*receive_time_us=*/1000000);
class NetworkBehaviorInterface { class NetworkBehaviorInterface {
public: public:
// Enqueues a packet in the network and returns true if the action was
// successful, false otherwise (for example, because the network capacity has
// been saturated). If the return value is false, the packet should be
// considered as dropped and it will not be returned by future calls
// to DequeueDeliverablePackets.
// Packets enqueued will exit the network when DequeueDeliverablePackets is
// called and enough time has passed (see NextDeliveryTimeUs).
virtual bool EnqueuePacket(PacketInFlightInfo packet_info) = 0; virtual bool EnqueuePacket(PacketInFlightInfo packet_info) = 0;
// Retrieves all packets that should be delivered by the given receive time. // Retrieves all packets that should be delivered by the given receive time.
// Not all the packets in the returned std::vector are actually delivered.
// In order to know the state of each packet it is necessary to check the
// `receive_time_us` field of each packet. If that is set to
// PacketDeliveryInfo::kNotReceived then the packet is considered lost in the
// network.
virtual std::vector<PacketDeliveryInfo> DequeueDeliverablePackets( virtual std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
int64_t receive_time_us) = 0; int64_t receive_time_us) = 0;
// Returns time in microseconds when caller should call // Returns time in microseconds when caller should call
// DequeueDeliverablePackets to get next set of packets to deliver. // DequeueDeliverablePackets to get the next set of delivered packets. It is
// possible that no packet will be delivered by that time (e.g. in case of
// random extra delay), in such case this method should be called again to get
// the updated estimated delivery time.
virtual absl::optional<int64_t> NextDeliveryTimeUs() const = 0; virtual absl::optional<int64_t> NextDeliveryTimeUs() const = 0;
virtual ~NetworkBehaviorInterface() = default; virtual ~NetworkBehaviorInterface() = default;
}; };
@ -81,10 +123,14 @@ class NetworkBehaviorInterface {
// capacity introduced delay. // capacity introduced delay.
class SimulatedNetworkInterface : public NetworkBehaviorInterface { class SimulatedNetworkInterface : public NetworkBehaviorInterface {
public: public:
// Sets a new configuration. This won't affect packets already in the pipe. // Sets a new configuration.
virtual void SetConfig(const BuiltInNetworkBehaviorConfig& config) = 0; virtual void SetConfig(const BuiltInNetworkBehaviorConfig& config) = 0;
virtual void UpdateConfig( virtual void UpdateConfig(
std::function<void(BuiltInNetworkBehaviorConfig*)> config_modifier) = 0; std::function<void(BuiltInNetworkBehaviorConfig*)> config_modifier) = 0;
// Pauses the network until `until_us`. This affects both delivery (calling
// DequeueDeliverablePackets before `until_us` results in an empty std::vector
// of packets) and capacity (the network is paused, so packets are not
// flowing and they will restart flowing at `until_us`).
virtual void PauseTransmissionUntil(int64_t until_us) = 0; virtual void PauseTransmissionUntil(int64_t until_us) = 0;
}; };

View file

@ -19,6 +19,7 @@ class SimulcastTestFixture {
virtual ~SimulcastTestFixture() = default; virtual ~SimulcastTestFixture() = default;
virtual void TestKeyFrameRequestsOnAllStreams() = 0; virtual void TestKeyFrameRequestsOnAllStreams() = 0;
virtual void TestKeyFrameRequestsOnSpecificStreams() = 0;
virtual void TestPaddingAllStreams() = 0; virtual void TestPaddingAllStreams() = 0;
virtual void TestPaddingTwoStreams() = 0; virtual void TestPaddingTwoStreams() = 0;
virtual void TestPaddingTwoStreamsOneMaxedOut() = 0; virtual void TestPaddingTwoStreamsOneMaxedOut() = 0;

View file

@ -11,6 +11,8 @@
#ifndef API_TEST_TRACK_ID_STREAM_INFO_MAP_H_ #ifndef API_TEST_TRACK_ID_STREAM_INFO_MAP_H_
#define API_TEST_TRACK_ID_STREAM_INFO_MAP_H_ #define API_TEST_TRACK_ID_STREAM_INFO_MAP_H_
#include <string>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
namespace webrtc { namespace webrtc {
@ -20,19 +22,19 @@ namespace webrtc_pc_e2e {
// are useful to associate stats reports track_ids to the remote stream info. // are useful to associate stats reports track_ids to the remote stream info.
class TrackIdStreamInfoMap { class TrackIdStreamInfoMap {
public: public:
struct StreamInfo {
std::string receiver_peer;
std::string stream_label;
std::string sync_group;
};
virtual ~TrackIdStreamInfoMap() = default; virtual ~TrackIdStreamInfoMap() = default;
// These methods must be called on the same thread where // These methods must be called on the same thread where
// StatsObserverInterface::OnStatsReports is invoked. // StatsObserverInterface::OnStatsReports is invoked.
// Returns a reference to a stream label owned by the TrackIdStreamInfoMap. // Precondition: `track_id` must be already mapped to stream info.
// Precondition: `track_id` must be already mapped to stream label. virtual StreamInfo GetStreamInfoFromTrackId(
virtual absl::string_view GetStreamLabelFromTrackId(
absl::string_view track_id) const = 0;
// Returns a reference to a sync group name owned by the TrackIdStreamInfoMap.
// Precondition: `track_id` must be already mapped to sync group.
virtual absl::string_view GetSyncGroupLabelFromTrackId(
absl::string_view track_id) const = 0; absl::string_view track_id) const = 0;
}; };

View file

@ -0,0 +1,134 @@
/*
* 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.
*/
#ifndef API_TEST_VIDEO_CODEC_TESTER_H_
#define API_TEST_VIDEO_CODEC_TESTER_H_
#include <memory>
#include "absl/functional/any_invocable.h"
#include "api/test/videocodec_test_stats.h"
#include "api/video/encoded_image.h"
#include "api/video/resolution.h"
#include "api/video/video_frame.h"
namespace webrtc {
namespace test {
// Interface for a video codec tester. The interface provides minimalistic set
// of data structures that enables implementation of decode-only, encode-only
// and encode-decode tests.
class VideoCodecTester {
public:
// Pacing settings for codec input.
struct PacingSettings {
enum PacingMode {
// Pacing is not used. Frames are sent to codec back-to-back.
kNoPacing,
// Pace with the rate equal to the target video frame rate. Pacing time is
// derived from RTP timestamp.
kRealTime,
// Pace with the explicitly provided rate.
kConstantRate,
};
PacingMode mode = PacingMode::kNoPacing;
// Pacing rate for `kConstantRate` mode.
Frequency constant_rate = Frequency::Zero();
};
struct DecoderSettings {
PacingSettings pacing;
};
struct EncoderSettings {
PacingSettings pacing;
};
virtual ~VideoCodecTester() = default;
// Interface for a raw video frames source.
class RawVideoSource {
public:
virtual ~RawVideoSource() = default;
// Returns next frame. If no more frames to pull, returns `absl::nullopt`.
// For analysis and pacing purposes, frame must have RTP timestamp set. The
// timestamp must represent the target video frame rate and be unique.
virtual absl::optional<VideoFrame> PullFrame() = 0;
// Returns early pulled frame with RTP timestamp equal to `timestamp_rtp`.
virtual VideoFrame GetFrame(uint32_t timestamp_rtp,
Resolution resolution) = 0;
};
// Interface for a coded video frames source.
class CodedVideoSource {
public:
virtual ~CodedVideoSource() = default;
// Returns next frame. If no more frames to pull, returns `absl::nullopt`.
// For analysis and pacing purposes, frame must have RTP timestamp set. The
// timestamp must represent the target video frame rate and be unique.
virtual absl::optional<EncodedImage> PullFrame() = 0;
};
// Interface for a video encoder.
class Encoder {
public:
using EncodeCallback =
absl::AnyInvocable<void(const EncodedImage& encoded_frame)>;
virtual ~Encoder() = default;
virtual void Encode(const VideoFrame& frame, EncodeCallback callback) = 0;
};
// Interface for a video decoder.
class Decoder {
public:
using DecodeCallback =
absl::AnyInvocable<void(const VideoFrame& decoded_frame)>;
virtual ~Decoder() = default;
virtual void Decode(const EncodedImage& frame, DecodeCallback callback) = 0;
};
// Pulls coded video frames from `video_source` and passes them to `decoder`.
// Returns `VideoCodecTestStats` object that contains collected per-frame
// metrics.
virtual std::unique_ptr<VideoCodecTestStats> RunDecodeTest(
std::unique_ptr<CodedVideoSource> video_source,
std::unique_ptr<Decoder> decoder,
const DecoderSettings& decoder_settings) = 0;
// Pulls raw video frames from `video_source` and passes them to `encoder`.
// Returns `VideoCodecTestStats` object that contains collected per-frame
// metrics.
virtual std::unique_ptr<VideoCodecTestStats> RunEncodeTest(
std::unique_ptr<RawVideoSource> video_source,
std::unique_ptr<Encoder> encoder,
const EncoderSettings& encoder_settings) = 0;
// Pulls raw video frames from `video_source`, passes them to `encoder` and
// then passes encoded frames to `decoder`. Returns `VideoCodecTestStats`
// object that contains collected per-frame metrics.
virtual std::unique_ptr<VideoCodecTestStats> RunEncodeDecodeTest(
std::unique_ptr<RawVideoSource> video_source,
std::unique_ptr<Encoder> encoder,
std::unique_ptr<Decoder> decoder,
const EncoderSettings& encoder_settings,
const DecoderSettings& decoder_settings) = 0;
};
} // namespace test
} // namespace webrtc
#endif // API_TEST_VIDEO_CODEC_TESTER_H_

View file

@ -62,6 +62,8 @@ class VideoQualityAnalyzerInterface
// https://crbug.com/webrtc/11443: improve stats API to make available // https://crbug.com/webrtc/11443: improve stats API to make available
// there. // there.
uint32_t target_encode_bitrate = 0; uint32_t target_encode_bitrate = 0;
// Encoder quantizer value.
int qp = -1;
}; };
// Contains extra statistic provided by video decoder. // Contains extra statistic provided by video decoder.
struct DecoderStats { struct DecoderStats {

View file

@ -18,6 +18,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "absl/types/optional.h"
#include "api/units/data_rate.h"
#include "api/units/frequency.h"
#include "api/video/video_frame_type.h" #include "api/video/video_frame_type.h"
namespace webrtc { namespace webrtc {
@ -135,11 +138,16 @@ class VideoCodecTestStats {
virtual ~VideoCodecTestStats() = default; virtual ~VideoCodecTestStats() = default;
virtual std::vector<FrameStatistics> GetFrameStatistics() = 0; virtual std::vector<FrameStatistics> GetFrameStatistics() const = 0;
virtual std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic( virtual std::vector<VideoStatistics> SliceAndCalcLayerVideoStatistic(
size_t first_frame_num, size_t first_frame_num,
size_t last_frame_num) = 0; size_t last_frame_num) = 0;
virtual VideoStatistics CalcVideoStatistic(size_t first_frame,
size_t last_frame,
DataRate target_bitrate,
Frequency target_framerate) = 0;
}; };
} // namespace test } // namespace test

View file

@ -52,7 +52,7 @@ rtc_library("field_trial_based_config") {
"field_trial_based_config.h", "field_trial_based_config.h",
] ]
deps = [ deps = [
"../../api:field_trials_view", "../../api:field_trials_registry",
"../../system_wrappers:field_trial", "../../system_wrappers:field_trial",
] ]
absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] absl_deps = [ "//third_party/abseil-cpp/absl/strings" ]

View file

@ -12,7 +12,7 @@
#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/field_trial.h"
namespace webrtc { namespace webrtc {
std::string FieldTrialBasedConfig::Lookup(absl::string_view key) const { std::string FieldTrialBasedConfig::GetValue(absl::string_view key) const {
return webrtc::field_trial::FindFullName(std::string(key)); return webrtc::field_trial::FindFullName(std::string(key));
} }
} // namespace webrtc } // namespace webrtc

View file

@ -13,13 +13,13 @@
#include <string> #include <string>
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "api/field_trials_view.h" #include "api/field_trials_registry.h"
namespace webrtc { namespace webrtc {
// Implementation using the field trial API fo the key value lookup. // Implementation using the field trial API fo the key value lookup.
class FieldTrialBasedConfig : public FieldTrialsView { class FieldTrialBasedConfig : public FieldTrialsRegistry {
public: private:
std::string Lookup(absl::string_view key) const override; std::string GetValue(absl::string_view key) const override;
}; };
} // namespace webrtc } // namespace webrtc

View file

@ -23,7 +23,7 @@
#include "api/units/frequency.h" #include "api/units/frequency.h"
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/units/unit_base.h" #include "rtc_base/units/unit_base.h" // IWYU pragma: export
namespace webrtc { namespace webrtc {
// DataRate is a class that represents a given data rate. This can be used to // DataRate is a class that represents a given data rate. This can be used to

View file

@ -18,7 +18,7 @@
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include "rtc_base/units/unit_base.h" #include "rtc_base/units/unit_base.h" // IWYU pragma: export
namespace webrtc { namespace webrtc {
// DataSize is a class represeting a count of bytes. // DataSize is a class represeting a count of bytes.

View file

@ -20,7 +20,7 @@
#include <type_traits> #include <type_traits>
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "rtc_base/units/unit_base.h" #include "rtc_base/units/unit_base.h" // IWYU pragma: export
namespace webrtc { namespace webrtc {

View file

@ -19,7 +19,7 @@
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include "rtc_base/units/unit_base.h" #include "rtc_base/units/unit_base.h" // IWYU pragma: export
namespace webrtc { namespace webrtc {

View file

@ -20,6 +20,7 @@
#include "api/units/time_delta.h" #include "api/units/time_delta.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/units/unit_base.h" // IWYU pragma: export
namespace webrtc { namespace webrtc {
// Timestamp represents the time that has passed since some unspecified epoch. // Timestamp represents the time that has passed since some unspecified epoch.

View file

@ -332,8 +332,11 @@ rtc_source_set("video_frame_metadata") {
"video_frame_metadata.h", "video_frame_metadata.h",
] ]
deps = [ deps = [
":video_frame",
":video_frame_type",
":video_rtp_headers",
"..:array_view", "..:array_view",
"../../modules/rtp_rtcp:rtp_video_header", "../../rtc_base/system:rtc_export",
"../transport/rtp:dependency_descriptor", "../transport/rtp:dependency_descriptor",
] ]
absl_deps = [ absl_deps = [
@ -363,6 +366,7 @@ rtc_library("builtin_video_bitrate_allocator_factory") {
} }
rtc_library("frame_buffer") { rtc_library("frame_buffer") {
visibility = [ "*" ]
sources = [ sources = [
"frame_buffer.cc", "frame_buffer.cc",
"frame_buffer.h", "frame_buffer.h",
@ -399,12 +403,10 @@ rtc_library("frame_buffer_unittest") {
if (rtc_include_tests) { if (rtc_include_tests) {
rtc_library("video_unittests") { rtc_library("video_unittests") {
testonly = true testonly = true
sources = [ sources = [ "video_stream_decoder_create_unittest.cc" ]
"video_frame_metadata_unittest.cc",
"video_stream_decoder_create_unittest.cc",
]
deps = [ deps = [
":video_frame_metadata", ":video_frame_metadata",
":video_frame_type",
":video_stream_decoder_create", ":video_stream_decoder_create",
"../../modules/rtp_rtcp:rtp_video_header", "../../modules/rtp_rtcp:rtp_video_header",
"../../test:test_support", "../../test:test_support",

Some files were not shown because too many files have changed in this diff Show more