From 25b29829ddee4724e051baef175e4a2e43f9fe64 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 22 Jan 2024 10:01:44 -0800 Subject: [PATCH 001/170] Roll chromium_revision e1fb84c37d..cf886b3ada (1250109:1250272) Change log: https://chromium.googlesource.com/chromium/src/+log/e1fb84c37d..cf886b3ada Full diff: https://chromium.googlesource.com/chromium/src/+/e1fb84c37d..cf886b3ada Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/36ecc8e397..515107a79c * src/build: https://chromium.googlesource.com/chromium/src/build/+log/28cd6ea727..5b6a44ceba * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/aadc2aa5f7..797a5979e6 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/e18cc47f93..165d473065 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/450bfd79ee..7ecc2765e4 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/692fab5c00..b4357120e9 * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/46cb7d0aca..c341d58921 * src/third_party/libc++/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git/+log/28aa23ffb4..24cb5545a9 * src/third_party/libc++abi/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git/+log/ea028d4d2b..9986707a5f * src/third_party/libunwindstack: https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git/+log/4dbfa0e8c8..a3bb4cd02e * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/d6af17fef2..30666f946a * src/third_party/turbine: ABguU2WKErRBdXX1LMt0zqZListLS_05X0Rp_V7pwAYC..KfCqNpZ5XxbfuKiIsjeMWFX-6aJc5WN37x9weHyVDIkC * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/51d5368f22..949b7e6342 DEPS diff: https://chromium.googlesource.com/chromium/src/+/e1fb84c37d..cf886b3ada/DEPS No update to Clang. BUG=None Change-Id: I5cc0ea67c0f16966596ffda3161847b739bfed27 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335722 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41597} --- DEPS | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/DEPS b/DEPS index 9f5cd9fd1f..22ca235dc5 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'e1fb84c37d20b7b85bfdd24e4ab19967ce1b77df', + 'chromium_revision': 'cf886b3ada97beff0d89d9a3d96c0d7ca96441ed', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@36ecc8e397422620def3bb19a7ba392810ca2442', + 'https://chromium.googlesource.com/chromium/src/base@515107a79caeb828608252f764728c65ad0ebe78', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@28cd6ea727d171ec990e6174308451d4178d7f8e', + 'https://chromium.googlesource.com/chromium/src/build@5b6a44ceba681ccb85a38846fff19be0bb011167', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@aadc2aa5f7382cdb5bc8e9309971356cf7722773', + 'https://chromium.googlesource.com/chromium/src/buildtools@797a5979e6215c6a2ffd84e22bb873d89d573594', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@e18cc47f9334d9dcf911c724467795542a472b51', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@165d473065c84624a718ffb29936dfeee688922d', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@450bfd79ee0369ac1a5465a12820b5d94a5956be', + 'https://chromium.googlesource.com/chromium/src/testing@7ecc2765e4d3b4224c00d3dee556daa937b667ba', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@692fab5c0074bc6fa486dce1a4aa7b2cc5609928', + 'https://chromium.googlesource.com/chromium/src/third_party@b4357120e9be1fbb8d6377115bde87bce745382e', 'src/buildtools/linux64': { 'packages': [ @@ -115,9 +115,9 @@ deps = { 'src/third_party/clang-format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@e5337933f2951cacd3aeacd238ce4578163ca0b9', 'src/third_party/libc++/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@28aa23ffb4c7344914a5b4ac7169f12e5a12333f', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@24cb5545a9a648f580ef7ce7b758689578f0a2a7', 'src/third_party/libc++abi/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@ea028d4d2b8a901f6302f5371c68a24480766e2b', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@9986707a5f2fc6d5d1ffa7f224a032bdd45c95fd', 'src/third_party/libunwind/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@f400fdb561d4416b59b8f8a33d8ec8b79da60495', @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@46cb7d0aca592cd20ddc2f6cb16ee386b2abbf0d', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@c341d58921ab188e4edacce04a221559bce86e8d', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@17525de887d54b970ffdd421a0879c1db1952307', 'src/third_party/flatbuffers/src': @@ -298,11 +298,11 @@ deps = { 'src/third_party/libaom/source/libaom': 'https://aomedia.googlesource.com/aom.git@646f28605eed1076d784451faa05a4e91e46ff6e', 'src/third_party/libunwindstack': { - 'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@4dbfa0e8c844c8e243b297bc185e54a99ff94f9e', + 'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@a3bb4cd02e0e984a235069f812cbef2b37c389e5', 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@d6af17fef257af28ee2417216ef87d5c5b743a1b', + 'https://android.googlesource.com/platform/external/perfetto.git@30666f946a71e4e05cb789cc391472b6c21c7741', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@b95d17572629c676bdcfd535fb3990b9f6f8fb11', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@51d5368f2225c34a47d1be4feafebba3b6d19579', + 'https://chromium.googlesource.com/chromium/src/tools@949b7e63427db605f268538821e5f94e64229079', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -498,7 +498,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/turbine', - 'version': 'ABguU2WKErRBdXX1LMt0zqZListLS_05X0Rp_V7pwAYC', + 'version': 'KfCqNpZ5XxbfuKiIsjeMWFX-6aJc5WN37x9weHyVDIkC', }, ], 'condition': 'checkout_android', From eb76f193f37363a5644a9079733f2ef01a1cb1cb Mon Sep 17 00:00:00 2001 From: Byoungchan Lee Date: Tue, 23 Jan 2024 01:55:14 +0900 Subject: [PATCH 002/170] Implement Newline Check in the Presubmit This will prevent committing source files with CRLF newlines. Bug: None Change-Id: I43c1d9a192a445a27f75b336e9ff6e45e012866b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335760 Auto-Submit: Daniel.L (Byoungchan) Lee Reviewed-by: Mirko Bonadei Commit-Queue: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41598} --- PRESUBMIT.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/PRESUBMIT.py b/PRESUBMIT.py index e5f28b70d1..5c9c88dc8b 100755 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -1067,6 +1067,8 @@ def CommonChecks(input_api, output_api): results.extend( CheckNewlineAtTheEndOfProtoFiles( input_api, output_api, source_file_filter=non_third_party_sources)) + results.extend( + CheckLFNewline(input_api, output_api, non_third_party_sources)) results.extend( CheckNoStreamUsageIsAdded(input_api, output_api, non_third_party_sources)) @@ -1322,6 +1324,20 @@ def CheckNewlineAtTheEndOfProtoFiles(input_api, output_api, return results +def CheckLFNewline(input_api, output_api, source_file_filter): + """Checks that all files have LF newlines.""" + error_msg = 'File {} must use LF newlines.' + results = [] + file_filter = lambda x: input_api.FilterSourceFile( + x, files_to_check=(r'.+', )) and source_file_filter(x) + for f in input_api.AffectedSourceFiles(file_filter): + file_path = f.LocalPath() + with open(file_path, 'rb') as f: + if b'\r\n' in f.read(): + results.append( + output_api.PresubmitError(error_msg.format(file_path))) + return results + def _ExtractAddRulesFromParsedDeps(parsed_deps): """Extract the rules that add dependencies from a parsed DEPS file. From 340d6c02369502456610ddad924e3b95e5464463 Mon Sep 17 00:00:00 2001 From: Jakob Ivarsson Date: Mon, 22 Jan 2024 14:49:15 +0100 Subject: [PATCH 003/170] Remove packet overhead lock and cached bitrate constraints. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are no longer needed since the RTP transport runs on the worker thread now. Some tests that were too strict on ordering needed change. Bug: none Change-Id: I4265cb1a4fd3355208f19aefdbb7abeb45b6cadf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335700 Reviewed-by: Tomas Lundqvist Commit-Queue: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41599} --- audio/audio_send_stream.cc | 105 ++++++++-------------------- audio/audio_send_stream.h | 25 ++----- audio/audio_send_stream_unittest.cc | 6 +- 3 files changed, 38 insertions(+), 98 deletions(-) diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index 3701eafd6f..ba6cde8e79 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -171,7 +171,6 @@ AudioSendStream::AudioSendStream( RTC_DCHECK_RUN_ON(&worker_thread_checker_); ConfigureStream(config, true, nullptr); - UpdateCachedTargetAudioBitrateConstraints(); } AudioSendStream::~AudioSendStream() { @@ -324,10 +323,7 @@ void AudioSendStream::ConfigureStream( } // Set currently known overhead (used in ANA, opus only). - { - MutexLock lock(&overhead_per_packet_lock_); - UpdateOverheadForEncoder(); - } + UpdateOverheadPerPacket(); channel_send_->CallEncoder([this](AudioEncoder* encoder) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); @@ -335,7 +331,6 @@ void AudioSendStream::ConfigureStream( return; } frame_length_range_ = encoder->GetFrameLengthRange(); - UpdateCachedTargetAudioBitrateConstraints(); }); if (sending_) { @@ -343,9 +338,6 @@ void AudioSendStream::ConfigureStream( } config_ = new_config; - if (!first_time) { - UpdateCachedTargetAudioBitrateConstraints(); - } webrtc::InvokeSetParametersCallback(callback, webrtc::RTCError::OK()); } @@ -488,30 +480,23 @@ webrtc::AudioSendStream::Stats AudioSendStream::GetStats( void AudioSendStream::DeliverRtcp(const uint8_t* packet, size_t length) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); channel_send_->ReceivedRTCPPacket(packet, length); - - { - // Poll if overhead has changed, which it can do if ack triggers us to stop - // sending mid/rid. - MutexLock lock(&overhead_per_packet_lock_); - UpdateOverheadForEncoder(); - } - UpdateCachedTargetAudioBitrateConstraints(); + // Poll if overhead has changed, which it can do if ack triggers us to stop + // sending mid/rid. + UpdateOverheadPerPacket(); } uint32_t AudioSendStream::OnBitrateUpdated(BitrateAllocationUpdate update) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); - // Pick a target bitrate between the constraints. Overrules the allocator if // it 1) allocated a bitrate of zero to disable the stream or 2) allocated a // higher than max to allow for e.g. extra FEC. - RTC_DCHECK(cached_constraints_.has_value()); - update.target_bitrate.Clamp(cached_constraints_->min, - cached_constraints_->max); - update.stable_target_bitrate.Clamp(cached_constraints_->min, - cached_constraints_->max); - + absl::optional constraints = + GetMinMaxBitrateConstraints(); + if (constraints) { + update.target_bitrate.Clamp(constraints->min, constraints->max); + update.stable_target_bitrate.Clamp(constraints->min, constraints->max); + } channel_send_->OnBitrateAllocation(update); - // The amount of audio protection is not exposed by the encoder, hence // always returning 0. return 0; @@ -520,41 +505,30 @@ uint32_t AudioSendStream::OnBitrateUpdated(BitrateAllocationUpdate update) { void AudioSendStream::SetTransportOverhead( int transport_overhead_per_packet_bytes) { RTC_DCHECK_RUN_ON(&worker_thread_checker_); - { - MutexLock lock(&overhead_per_packet_lock_); - transport_overhead_per_packet_bytes_ = transport_overhead_per_packet_bytes; - UpdateOverheadForEncoder(); - } - UpdateCachedTargetAudioBitrateConstraints(); + transport_overhead_per_packet_bytes_ = transport_overhead_per_packet_bytes; + UpdateOverheadPerPacket(); } -void AudioSendStream::UpdateOverheadForEncoder() { +void AudioSendStream::UpdateOverheadPerPacket() { RTC_DCHECK_RUN_ON(&worker_thread_checker_); - size_t overhead_per_packet_bytes = GetPerPacketOverheadBytes(); + size_t overhead_per_packet_bytes = + transport_overhead_per_packet_bytes_ + + rtp_rtcp_module_->ExpectedPerPacketOverhead(); if (overhead_per_packet_ == overhead_per_packet_bytes) { return; } overhead_per_packet_ = overhead_per_packet_bytes; - channel_send_->CallEncoder([&](AudioEncoder* encoder) { encoder->OnReceivedOverhead(overhead_per_packet_bytes); }); - if (total_packet_overhead_bytes_ != overhead_per_packet_bytes) { - total_packet_overhead_bytes_ = overhead_per_packet_bytes; - if (registered_with_allocator_) { - ConfigureBitrateObserver(); - } + if (registered_with_allocator_) { + ConfigureBitrateObserver(); } } size_t AudioSendStream::TestOnlyGetPerPacketOverheadBytes() const { - MutexLock lock(&overhead_per_packet_lock_); - return GetPerPacketOverheadBytes(); -} - -size_t AudioSendStream::GetPerPacketOverheadBytes() const { - return transport_overhead_per_packet_bytes_ + - rtp_rtcp_module_->ExpectedPerPacketOverhead(); + RTC_DCHECK_RUN_ON(&worker_thread_checker_); + return overhead_per_packet_; } RtpState AudioSendStream::GetRtpState() const { @@ -648,13 +622,9 @@ bool AudioSendStream::SetupSendCodec(const Config& new_config) { } // Set currently known overhead (used in ANA, opus only). - // If overhead changes later, it will be updated in UpdateOverheadForEncoder. - { - MutexLock lock(&overhead_per_packet_lock_); - size_t overhead = GetPerPacketOverheadBytes(); - if (overhead > 0) { - encoder->OnReceivedOverhead(overhead); - } + // If overhead changes later, it will be updated in UpdateOverheadPerPacket. + if (overhead_per_packet_ > 0) { + encoder->OnReceivedOverhead(overhead_per_packet_); } StoreEncoderProperties(encoder->SampleRateHz(), encoder->NumChannels()); @@ -716,18 +686,14 @@ void AudioSendStream::ReconfigureANA(const Config& new_config) { return; } if (new_config.audio_network_adaptor_config) { - // This lock needs to be acquired before CallEncoder, since it aquires - // another lock and we need to maintain the same order at all call sites to - // avoid deadlock. - MutexLock lock(&overhead_per_packet_lock_); - size_t overhead = GetPerPacketOverheadBytes(); channel_send_->CallEncoder([&](AudioEncoder* encoder) { + RTC_DCHECK_RUN_ON(&worker_thread_checker_); if (encoder->EnableAudioNetworkAdaptor( *new_config.audio_network_adaptor_config, event_log_)) { RTC_LOG(LS_INFO) << "Audio network adaptor enabled on SSRC " << new_config.rtp.ssrc; - if (overhead > 0) { - encoder->OnReceivedOverhead(overhead); + if (overhead_per_packet_ > 0) { + encoder->OnReceivedOverhead(overhead_per_packet_); } } else { RTC_LOG(LS_INFO) << "Failed to enable Audio network adaptor on SSRC " @@ -832,8 +798,7 @@ void AudioSendStream::ConfigureBitrateObserver() { priority_bitrate += max_overhead; } else { RTC_DCHECK(frame_length_range_); - const DataSize overhead_per_packet = - DataSize::Bytes(total_packet_overhead_bytes_); + const DataSize overhead_per_packet = DataSize::Bytes(overhead_per_packet_); DataRate min_overhead = overhead_per_packet / frame_length_range_->second; priority_bitrate += min_overhead; } @@ -897,10 +862,9 @@ AudioSendStream::GetMinMaxBitrateConstraints() const { RTC_LOG(LS_WARNING) << "frame_length_range_ is not set"; return absl::nullopt; } - const DataSize kOverheadPerPacket = - DataSize::Bytes(total_packet_overhead_bytes_); - constraints.min += kOverheadPerPacket / frame_length_range_->second; - constraints.max += kOverheadPerPacket / frame_length_range_->first; + const DataSize overhead_per_packet = DataSize::Bytes(overhead_per_packet_); + constraints.min += overhead_per_packet / frame_length_range_->second; + constraints.max += overhead_per_packet / frame_length_range_->first; } return constraints; } @@ -910,14 +874,5 @@ void AudioSendStream::RegisterCngPayloadType(int payload_type, channel_send_->RegisterCngPayloadType(payload_type, clockrate_hz); } -void AudioSendStream::UpdateCachedTargetAudioBitrateConstraints() { - absl::optional - new_constraints = GetMinMaxBitrateConstraints(); - if (!new_constraints.has_value()) { - return; - } - cached_constraints_ = new_constraints; -} - } // namespace internal } // namespace webrtc diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h index 09fd712d40..374d7b1207 100644 --- a/audio/audio_send_stream.h +++ b/audio/audio_send_stream.h @@ -110,8 +110,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, const voe::ChannelSendInterface* GetChannel() const; // Returns combined per-packet overhead. - size_t TestOnlyGetPerPacketOverheadBytes() const - RTC_LOCKS_EXCLUDED(overhead_per_packet_lock_); + size_t TestOnlyGetPerPacketOverheadBytes() const; private: class TimedTransport; @@ -152,19 +151,11 @@ class AudioSendStream final : public webrtc::AudioSendStream, // Sets per-packet overhead on encoded (for ANA) based on current known values // of transport and packetization overheads. - void UpdateOverheadForEncoder() - RTC_EXCLUSIVE_LOCKS_REQUIRED(overhead_per_packet_lock_); - - // Returns combined per-packet overhead. - size_t GetPerPacketOverheadBytes() const - RTC_EXCLUSIVE_LOCKS_REQUIRED(overhead_per_packet_lock_); + void UpdateOverheadPerPacket(); void RegisterCngPayloadType(int payload_type, int clockrate_hz) RTC_RUN_ON(worker_thread_checker_); - void UpdateCachedTargetAudioBitrateConstraints() - RTC_RUN_ON(worker_thread_checker_); - Clock* clock_; const FieldTrialsView& field_trials_; @@ -193,9 +184,6 @@ class AudioSendStream final : public webrtc::AudioSendStream, BitrateAllocatorInterface* const bitrate_allocator_ RTC_GUARDED_BY(worker_thread_checker_); - absl::optional - cached_constraints_ RTC_GUARDED_BY(worker_thread_checker_) = - absl::nullopt; RtpTransportControllerSendInterface* const rtp_transport_; RtpRtcpInterface* const rtp_rtcp_module_; @@ -217,17 +205,14 @@ class AudioSendStream final : public webrtc::AudioSendStream, const std::vector& extensions); static int TransportSeqNumId(const Config& config); - mutable Mutex overhead_per_packet_lock_; - size_t overhead_per_packet_ RTC_GUARDED_BY(overhead_per_packet_lock_) = 0; - // Current transport overhead (ICE, TURN, etc.) size_t transport_overhead_per_packet_bytes_ - RTC_GUARDED_BY(overhead_per_packet_lock_) = 0; + RTC_GUARDED_BY(worker_thread_checker_) = 0; + // Total overhead, including transport and RTP headers. + size_t overhead_per_packet_ RTC_GUARDED_BY(worker_thread_checker_) = 0; bool registered_with_allocator_ RTC_GUARDED_BY(worker_thread_checker_) = false; - size_t total_packet_overhead_bytes_ RTC_GUARDED_BY(worker_thread_checker_) = - 0; absl::optional> frame_length_range_ RTC_GUARDED_BY(worker_thread_checker_); }; diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc index c854f734b5..8c17326865 100644 --- a/audio/audio_send_stream_unittest.cc +++ b/audio/audio_send_stream_unittest.cc @@ -560,8 +560,7 @@ TEST(AudioSendStreamTest, AudioNetworkAdaptorReceivesOverhead) { InSequence s; EXPECT_CALL( *mock_encoder, - OnReceivedOverhead(Eq(kOverheadPerPacket.bytes()))) - .Times(2); + OnReceivedOverhead(Eq(kOverheadPerPacket.bytes()))); EXPECT_CALL(*mock_encoder, EnableAudioNetworkAdaptor(StrEq(kAnaConfigString), _)) .WillOnce(Return(true)); @@ -847,7 +846,6 @@ TEST(AudioSendStreamTest, AudioOverheadChanged) { EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead) .WillRepeatedly(Return(audio_overhead_per_packet_bytes)); auto send_stream = helper.CreateAudioSendStream(); - auto new_config = helper.config(); BitrateAllocationUpdate update; update.target_bitrate = @@ -861,6 +859,8 @@ TEST(AudioSendStreamTest, AudioOverheadChanged) { EXPECT_CALL(*helper.rtp_rtcp(), ExpectedPerPacketOverhead) .WillRepeatedly(Return(audio_overhead_per_packet_bytes + 20)); + // RTP overhead can only change in response to RTCP or configuration change. + send_stream->Reconfigure(helper.config(), nullptr); EXPECT_CALL(*helper.channel_send(), OnBitrateAllocation); send_stream->OnBitrateUpdated(update); From c708c00f95e8d95b34045ee71559599d43e9a844 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 22 Jan 2024 13:17:05 +0100 Subject: [PATCH 004/170] Add VideoDecoderFactory function to pass Environment for VideoDecoder construction Bug: webrtc:15791 Change-Id: I3fa962ae13d8b36092a5b910f1ce6e946689daea Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335680 Reviewed-by: Philip Eliasson Reviewed-by: Mirko Bonadei Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41600} --- api/BUILD.gn | 1 + api/test/mock_video_decoder_factory.h | 13 +++++-- api/video_codecs/BUILD.gn | 2 + api/video_codecs/video_decoder_factory.cc | 45 +++++++++++++++++++++++ api/video_codecs/video_decoder_factory.h | 31 +++++++--------- 5 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 api/video_codecs/video_decoder_factory.cc diff --git a/api/BUILD.gn b/api/BUILD.gn index 6af4fa5517..95850c6e17 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -1345,6 +1345,7 @@ if (rtc_include_tests) { deps = [ "../api/video_codecs:video_codecs_api", "../test:test_support", + "environment", ] } diff --git a/api/test/mock_video_decoder_factory.h b/api/test/mock_video_decoder_factory.h index 6150d9f8b5..48d96ea58b 100644 --- a/api/test/mock_video_decoder_factory.h +++ b/api/test/mock_video_decoder_factory.h @@ -14,6 +14,7 @@ #include #include +#include "api/environment/environment.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder_factory.h" @@ -21,17 +22,21 @@ namespace webrtc { -class MockVideoDecoderFactory : public webrtc::VideoDecoderFactory { +class MockVideoDecoderFactory : public VideoDecoderFactory { public: ~MockVideoDecoderFactory() override { Die(); } - MOCK_METHOD(std::vector, + MOCK_METHOD(std::vector, GetSupportedFormats, (), (const, override)); - MOCK_METHOD(std::unique_ptr, + MOCK_METHOD(std::unique_ptr, + Create, + (const Environment&, const SdpVideoFormat&), + (override)); + MOCK_METHOD(std::unique_ptr, CreateVideoDecoder, - (const webrtc::SdpVideoFormat&), + (const SdpVideoFormat&), (override)); MOCK_METHOD(void, Die, ()); }; diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn index 3865f4fee7..aaa2a5750a 100644 --- a/api/video_codecs/BUILD.gn +++ b/api/video_codecs/BUILD.gn @@ -58,6 +58,7 @@ rtc_library("video_codecs_api") { "video_codec.h", "video_decoder.cc", "video_decoder.h", + "video_decoder_factory.cc", "video_decoder_factory.h", "video_encoder.cc", "video_encoder.h", @@ -91,6 +92,7 @@ rtc_library("video_codecs_api") { "../../rtc_base:refcount", "../../rtc_base:stringutils", "../../rtc_base/system:rtc_export", + "../environment", "../units:data_rate", "../video:encoded_image", "../video:render_resolution", diff --git a/api/video_codecs/video_decoder_factory.cc b/api/video_codecs/video_decoder_factory.cc new file mode 100644 index 0000000000..60fe92bf38 --- /dev/null +++ b/api/video_codecs/video_decoder_factory.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 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/video_codecs/video_decoder_factory.h" + +#include + +#include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_decoder.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +VideoDecoderFactory::CodecSupport VideoDecoderFactory::QueryCodecSupport( + const SdpVideoFormat& format, + bool reference_scaling) const { + // Default implementation, query for supported formats and check if the + // specified format is supported. Returns false if `reference_scaling` is + // true. + return {.is_supported = !reference_scaling && + format.IsCodecInList(GetSupportedFormats())}; +} + +std::unique_ptr VideoDecoderFactory::Create( + const Environment& env, + const SdpVideoFormat& format) { + return CreateVideoDecoder(format); +} + +std::unique_ptr VideoDecoderFactory::CreateVideoDecoder( + const SdpVideoFormat& format) { + // Newer code shouldn't call this function, + // Older code should implement it in derived classes. + RTC_CHECK_NOTREACHED(); + return nullptr; +} + +} // namespace webrtc diff --git a/api/video_codecs/video_decoder_factory.h b/api/video_codecs/video_decoder_factory.h index 7e1d2ee883..6048cb27fb 100644 --- a/api/video_codecs/video_decoder_factory.h +++ b/api/video_codecs/video_decoder_factory.h @@ -12,17 +12,15 @@ #define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_H_ #include -#include #include -#include "absl/types/optional.h" +#include "api/environment/environment.h" #include "api/video_codecs/sdp_video_format.h" +#include "api/video_codecs/video_decoder.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { -class VideoDecoder; - // A factory that creates VideoDecoders. // NOTE: This class is still under development and may change without notice. class RTC_EXPORT VideoDecoderFactory { @@ -32,6 +30,8 @@ class RTC_EXPORT VideoDecoderFactory { bool is_power_efficient = false; }; + virtual ~VideoDecoderFactory() = default; + // Returns a list of supported video formats in order of preference, to use // for signaling etc. virtual std::vector GetSupportedFormats() const = 0; @@ -47,21 +47,18 @@ class RTC_EXPORT VideoDecoderFactory { // different scalabilty modes. NOTE: QueryCodecSupport is currently an // experimental feature that is subject to change without notice. virtual CodecSupport QueryCodecSupport(const SdpVideoFormat& format, - bool reference_scaling) const { - // Default implementation, query for supported formats and check if the - // specified format is supported. Returns false if `reference_scaling` is - // true. - CodecSupport codec_support; - codec_support.is_supported = - !reference_scaling && format.IsCodecInList(GetSupportedFormats()); - return codec_support; - } + bool reference_scaling) const; - // Creates a VideoDecoder for the specified format. + // Creates a VideoDecoder for the specified `format`. + // TODO: bugs.webrtc.org/15791 - Make pure virtual when implemented in all + // derived classes. + virtual std::unique_ptr Create(const Environment& env, + const SdpVideoFormat& format); + + // TODO: bugs.webrtc.org/15791 - Make private or delete when all callers are + // migrated to `Create`. virtual std::unique_ptr CreateVideoDecoder( - const SdpVideoFormat& format) = 0; - - virtual ~VideoDecoderFactory() {} + const SdpVideoFormat& format); }; } // namespace webrtc From 1b61c7161edb645153f1f76e1f731443f95e6bfb Mon Sep 17 00:00:00 2001 From: Karim H Date: Thu, 4 Jan 2024 09:28:49 +0400 Subject: [PATCH 005/170] Expose setCodecPreferences/getCapabilities for iOS Bug: webrtc:15749 Change-Id: I92f5d5dc5d9eb4d0a60c33ed724a0d3e8b4fa1a8 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333402 Auto-Submit: Karim Ham Reviewed-by: Florent Castelli Reviewed-by: Peter Hanspers Commit-Queue: Mirko Bonadei Commit-Queue: Florent Castelli Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41601} --- AUTHORS | 1 + sdk/BUILD.gn | 15 ++ .../peerconnection/RTCPeerConnectionFactory.h | 13 ++ .../RTCPeerConnectionFactory.mm | 29 +++ .../RTCRtpCapabilities+Private.h | 32 +++ .../api/peerconnection/RTCRtpCapabilities.h | 31 +++ .../api/peerconnection/RTCRtpCapabilities.mm | 60 ++++++ .../RTCRtpCodecCapability+Private.h | 33 +++ .../peerconnection/RTCRtpCodecCapability.h | 58 ++++++ .../peerconnection/RTCRtpCodecCapability.mm | 116 +++++++++++ .../RTCRtpHeaderExtensionCapability+Private.h | 34 ++++ .../RTCRtpHeaderExtensionCapability.h | 33 +++ .../RTCRtpHeaderExtensionCapability.mm | 56 +++++ .../api/peerconnection/RTCRtpTransceiver.h | 7 + .../api/peerconnection/RTCRtpTransceiver.mm | 11 + .../RTCPeerConnectionFactory_xctest.m | 192 ++++++++++++++++++ 16 files changed, 721 insertions(+) create mode 100644 sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h create mode 100644 sdk/objc/api/peerconnection/RTCRtpCapabilities.h create mode 100644 sdk/objc/api/peerconnection/RTCRtpCapabilities.mm create mode 100644 sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h create mode 100644 sdk/objc/api/peerconnection/RTCRtpCodecCapability.h create mode 100644 sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm create mode 100644 sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h create mode 100644 sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h create mode 100644 sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm diff --git a/AUTHORS b/AUTHORS index 6e922401d0..c0c40930d6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -65,6 +65,7 @@ Jie Mao Jiwon Kim Johnny Wong Jose Antonio Olivera Ortega +Karim Hammache Keiichi Enomoto Kiran Thind Korniltsev Anatoly diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index e28bdcc5a2..a044c469e0 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -991,6 +991,12 @@ if (is_ios || is_mac) { "objc/api/peerconnection/RTCRtcpParameters+Private.h", "objc/api/peerconnection/RTCRtcpParameters.h", "objc/api/peerconnection/RTCRtcpParameters.mm", + "objc/api/peerconnection/RTCRtpCapabilities+Private.h", + "objc/api/peerconnection/RTCRtpCapabilities.h", + "objc/api/peerconnection/RTCRtpCapabilities.mm", + "objc/api/peerconnection/RTCRtpCodecCapability+Private.h", + "objc/api/peerconnection/RTCRtpCodecCapability.h", + "objc/api/peerconnection/RTCRtpCodecCapability.mm", "objc/api/peerconnection/RTCRtpCodecParameters+Private.h", "objc/api/peerconnection/RTCRtpCodecParameters.h", "objc/api/peerconnection/RTCRtpCodecParameters.mm", @@ -1000,6 +1006,9 @@ if (is_ios || is_mac) { "objc/api/peerconnection/RTCRtpHeaderExtension+Private.h", "objc/api/peerconnection/RTCRtpHeaderExtension.h", "objc/api/peerconnection/RTCRtpHeaderExtension.mm", + "objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h", + "objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h", + "objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm", "objc/api/peerconnection/RTCRtpParameters+Private.h", "objc/api/peerconnection/RTCRtpParameters.h", "objc/api/peerconnection/RTCRtpParameters.mm", @@ -1309,9 +1318,12 @@ if (is_ios || is_mac) { "objc/api/peerconnection/RTCPeerConnectionFactory.h", "objc/api/peerconnection/RTCPeerConnectionFactoryOptions.h", "objc/api/peerconnection/RTCRtcpParameters.h", + "objc/api/peerconnection/RTCRtpCapabilities.h", + "objc/api/peerconnection/RTCRtpCodecCapability.h", "objc/api/peerconnection/RTCRtpCodecParameters.h", "objc/api/peerconnection/RTCRtpEncodingParameters.h", "objc/api/peerconnection/RTCRtpHeaderExtension.h", + "objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h", "objc/api/peerconnection/RTCRtpParameters.h", "objc/api/peerconnection/RTCRtpReceiver.h", "objc/api/peerconnection/RTCRtpSender.h", @@ -1423,9 +1435,12 @@ if (is_ios || is_mac) { "objc/api/peerconnection/RTCPeerConnectionFactory.h", "objc/api/peerconnection/RTCPeerConnectionFactoryOptions.h", "objc/api/peerconnection/RTCRtcpParameters.h", + "objc/api/peerconnection/RTCRtpCapabilities.h", + "objc/api/peerconnection/RTCRtpCodecCapability.h", "objc/api/peerconnection/RTCRtpCodecParameters.h", "objc/api/peerconnection/RTCRtpEncodingParameters.h", "objc/api/peerconnection/RTCRtpHeaderExtension.h", + "objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h", "objc/api/peerconnection/RTCRtpParameters.h", "objc/api/peerconnection/RTCRtpReceiver.h", "objc/api/peerconnection/RTCRtpSender.h", diff --git a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h index 5575af98c9..17777f6d5d 100644 --- a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h +++ b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.h @@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN +@class RTC_OBJC_TYPE(RTCRtpCapabilities); @class RTC_OBJC_TYPE(RTCAudioSource); @class RTC_OBJC_TYPE(RTCAudioTrack); @class RTC_OBJC_TYPE(RTCConfiguration); @@ -51,6 +52,18 @@ RTC_OBJC_EXPORT decoderFactory:(nullable id)decoderFactory audioDevice:(nullable id)audioDevice; +/** + * Valid kind values are kRTCMediaStreamTrackKindAudio and + * kRTCMediaStreamTrackKindVideo. + */ +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesForKind:(NSString *)kind; + +/** + * Valid kind values are kRTCMediaStreamTrackKindAudio and + * kRTCMediaStreamTrackKindVideo. + */ +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpReceiverCapabilitiesForKind:(NSString *)kind; + /** Initialize an RTCAudioSource with constraints. */ - (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints: (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints; diff --git a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm index 445006f0d0..64be41ae15 100644 --- a/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm +++ b/sdk/objc/api/peerconnection/RTCPeerConnectionFactory.mm @@ -13,6 +13,7 @@ #import "RTCPeerConnectionFactory+Native.h" #import "RTCPeerConnectionFactory+Private.h" #import "RTCPeerConnectionFactoryOptions+Private.h" +#import "RTCRtpCapabilities+Private.h" #import "RTCAudioSource+Private.h" #import "RTCAudioTrack+Private.h" @@ -38,6 +39,7 @@ #include "api/transport/field_trial_based_config.h" #import "components/video_codec/RTCVideoDecoderFactoryH264.h" #import "components/video_codec/RTCVideoEncoderFactoryH264.h" +#include "media/base/media_constants.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_processing/include/audio_processing.h" @@ -214,6 +216,20 @@ return self; } +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpSenderCapabilitiesForKind:(NSString *)kind { + cricket::MediaType mediaType = [[self class] mediaTypeForKind:kind]; + + webrtc::RtpCapabilities rtpCapabilities = _nativeFactory->GetRtpSenderCapabilities(mediaType); + return [[RTC_OBJC_TYPE(RTCRtpCapabilities) alloc] initWithNativeRtpCapabilities:rtpCapabilities]; +} + +- (RTC_OBJC_TYPE(RTCRtpCapabilities) *)rtpReceiverCapabilitiesForKind:(NSString *)kind { + cricket::MediaType mediaType = [[self class] mediaTypeForKind:kind]; + + webrtc::RtpCapabilities rtpCapabilities = _nativeFactory->GetRtpReceiverCapabilities(mediaType); + return [[RTC_OBJC_TYPE(RTCRtpCapabilities) alloc] initWithNativeRtpCapabilities:rtpCapabilities]; +} + - (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints: (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints { std::unique_ptr nativeConstraints; @@ -338,4 +354,17 @@ return _networkThread.get(); } +#pragma mark - Private + ++ (cricket::MediaType)mediaTypeForKind:(NSString *)kind { + if (kind == kRTCMediaStreamTrackKindAudio) { + return cricket::MEDIA_TYPE_AUDIO; + } else if (kind == kRTCMediaStreamTrackKindVideo) { + return cricket::MEDIA_TYPE_VIDEO; + } else { + RTC_DCHECK_NOTREACHED(); + return cricket::MEDIA_TYPE_UNSUPPORTED; + } +} + @end diff --git a/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h b/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h new file mode 100644 index 0000000000..be51993f2f --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpCapabilities+Private.h @@ -0,0 +1,32 @@ +/* + * Copyright 2024 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 "RTCRtpCapabilities.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpCapabilities)() + +/** + * The native RtpCapabilities representation of this RTCRtpCapabilities + * object. This is needed to pass to the underlying C++ APIs. + */ +@property(nonatomic, readonly) webrtc::RtpCapabilities nativeRtpCapabilities; + +/** + * Initialize an RTCRtpCapabilities from a native RtpCapabilities. + */ +- (instancetype)initWithNativeRtpCapabilities:(const webrtc::RtpCapabilities &)rtpCapabilities; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/api/peerconnection/RTCRtpCapabilities.h b/sdk/objc/api/peerconnection/RTCRtpCapabilities.h new file mode 100644 index 0000000000..7e898b5a80 --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpCapabilities.h @@ -0,0 +1,31 @@ +/* + * Copyright 2024 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 + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +@class RTC_OBJC_TYPE(RTCRtpCodecCapability); +@class RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability); + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpCapabilities) : NSObject + +@property(nonatomic, copy) NSArray *codecs; +@property(nonatomic, copy) + NSArray *headerExtensions; + +- (instancetype)init; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm b/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm new file mode 100644 index 0000000000..85537a91ad --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpCapabilities.mm @@ -0,0 +1,60 @@ +/* + * Copyright 2024 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 "RTCRtpCapabilities+Private.h" + +#import "RTCRtpCodecCapability+Private.h" +#import "RTCRtpHeaderExtensionCapability+Private.h" + +#import "base/RTCLogging.h" +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtpCapabilities) + +@synthesize codecs = _codecs; +@synthesize headerExtensions = _headerExtensions; + +- (instancetype)init { + webrtc::RtpCapabilities nativeRtpCapabilities; + return [self initWithNativeRtpCapabilities:nativeRtpCapabilities]; +} + +- (instancetype)initWithNativeRtpCapabilities: + (const webrtc::RtpCapabilities &)nativeRtpCapabilities { + if (self = [super init]) { + NSMutableArray *codecs = [[NSMutableArray alloc] init]; + for (const auto &codec : nativeRtpCapabilities.codecs) { + [codecs addObject:[[RTC_OBJC_TYPE(RTCRtpCodecCapability) alloc] + initWithNativeRtpCodecCapability:codec]]; + } + _codecs = codecs; + + NSMutableArray *headerExtensions = [[NSMutableArray alloc] init]; + for (const auto &headerExtension : nativeRtpCapabilities.header_extensions) { + [headerExtensions addObject:[[RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) alloc] + initWithNativeRtpHeaderExtensionCapability:headerExtension]]; + } + _headerExtensions = headerExtensions; + } + return self; +} + +- (webrtc::RtpCapabilities)nativeRtpCapabilities { + webrtc::RtpCapabilities rtpCapabilities; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in _codecs) { + rtpCapabilities.codecs.push_back(codec.nativeRtpCodecCapability); + } + for (RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) * headerExtension in _headerExtensions) { + rtpCapabilities.header_extensions.push_back(headerExtension.nativeRtpHeaderExtensionCapability); + } + return rtpCapabilities; +} + +@end diff --git a/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h b/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h new file mode 100644 index 0000000000..6af13b3b23 --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpCodecCapability+Private.h @@ -0,0 +1,33 @@ +/* + * Copyright 2024 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 "RTCRtpCodecCapability.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpCodecCapability)() + +/** + * The native RtpCodecCapability representation of this RTCRtpCodecCapability + * object. This is needed to pass to the underlying C++ APIs. + */ +@property(nonatomic, readonly) webrtc::RtpCodecCapability nativeRtpCodecCapability; + +/** + * Initialize an RTCRtpCodecCapability from a native RtpCodecCapability. + */ +- (instancetype)initWithNativeRtpCodecCapability: + (const webrtc::RtpCodecCapability &)nativeRtpCodecCapability; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h b/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h new file mode 100644 index 0000000000..5604148e5d --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpCodecCapability.h @@ -0,0 +1,58 @@ +/* + * Copyright 2024 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 + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpCodecCapability) : NSObject + +/** The preferred RTP payload type. */ +@property(nonatomic, readonly, nullable) NSNumber *preferredPayloadType; + +/** + * The codec MIME subtype. Valid types are listed in: + * http://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-2 + * + * Several supported types are represented by the constants above. + */ +@property(nonatomic, readonly) NSString *name; + +/** + * The media type of this codec. Equivalent to MIME top-level type. + * + * Valid values are kRTCMediaStreamTrackKindAudio and + * kRTCMediaStreamTrackKindVideo. + */ +@property(nonatomic, readonly) NSString *kind; + +/** The codec clock rate expressed in Hertz. */ +@property(nonatomic, readonly, nullable) NSNumber *clockRate; + +/** + * The number of audio channels (mono=1, stereo=2). + * Set to null for video codecs. + **/ +@property(nonatomic, readonly, nullable) NSNumber *numChannels; + +/** The "format specific parameters" field from the "a=fmtp" line in the SDP */ +@property(nonatomic, readonly) NSDictionary *parameters; + +/** The MIME type of the codec. */ +@property(nonatomic, readonly) NSString *mimeType; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm b/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm new file mode 100644 index 0000000000..2dc1e5dc4b --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpCodecCapability.mm @@ -0,0 +1,116 @@ +/* + * Copyright 2024 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 "RTCRtpCodecCapability+Private.h" + +#import "RTCMediaStreamTrack.h" +#import "helpers/NSString+StdString.h" + +#include "media/base/media_constants.h" +#include "rtc_base/checks.h" + +@implementation RTC_OBJC_TYPE (RTCRtpCodecCapability) + +@synthesize preferredPayloadType = _preferredPayloadType; +@synthesize name = _name; +@synthesize kind = _kind; +@synthesize clockRate = _clockRate; +@synthesize numChannels = _numChannels; +@synthesize parameters = _parameters; +@synthesize mimeType = _mimeType; + +- (instancetype)init { + webrtc::RtpCodecCapability rtpCodecCapability; + return [self initWithNativeRtpCodecCapability:rtpCodecCapability]; +} + +- (instancetype)initWithNativeRtpCodecCapability: + (const webrtc::RtpCodecCapability &)nativeRtpCodecCapability { + if (self = [super init]) { + if (nativeRtpCodecCapability.preferred_payload_type) { + _preferredPayloadType = + [NSNumber numberWithInt:*nativeRtpCodecCapability.preferred_payload_type]; + } + _name = [NSString stringForStdString:nativeRtpCodecCapability.name]; + switch (nativeRtpCodecCapability.kind) { + case cricket::MEDIA_TYPE_AUDIO: + _kind = kRTCMediaStreamTrackKindAudio; + break; + case cricket::MEDIA_TYPE_VIDEO: + _kind = kRTCMediaStreamTrackKindVideo; + break; + case cricket::MEDIA_TYPE_DATA: + RTC_DCHECK_NOTREACHED(); + break; + case cricket::MEDIA_TYPE_UNSUPPORTED: + RTC_DCHECK_NOTREACHED(); + break; + } + if (nativeRtpCodecCapability.clock_rate) { + _clockRate = [NSNumber numberWithInt:*nativeRtpCodecCapability.clock_rate]; + } + if (nativeRtpCodecCapability.num_channels) { + _numChannels = [NSNumber numberWithInt:*nativeRtpCodecCapability.num_channels]; + } + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + for (const auto ¶meter : nativeRtpCodecCapability.parameters) { + [parameters setObject:[NSString stringForStdString:parameter.second] + forKey:[NSString stringForStdString:parameter.first]]; + } + _parameters = parameters; + _mimeType = [NSString stringForStdString:nativeRtpCodecCapability.mime_type()]; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpCodecCapability) {\n " + @"preferredPayloadType: %@\n name: %@\n kind: %@\n " + @"clockRate: %@\n numChannels: %@\n parameters: %@\n " + @"mimeType: %@\n}", + _preferredPayloadType, + _name, + _kind, + _clockRate, + _numChannels, + _parameters, + _mimeType]; +} + +- (webrtc::RtpCodecCapability)nativeRtpCodecCapability { + webrtc::RtpCodecCapability rtpCodecCapability; + if (_preferredPayloadType != nil) { + rtpCodecCapability.preferred_payload_type = absl::optional(_preferredPayloadType.intValue); + } + rtpCodecCapability.name = [NSString stdStringForString:_name]; + // NSString pointer comparison is safe here since "kind" is readonly and only + // populated above. + if (_kind == kRTCMediaStreamTrackKindAudio) { + rtpCodecCapability.kind = cricket::MEDIA_TYPE_AUDIO; + } else if (_kind == kRTCMediaStreamTrackKindVideo) { + rtpCodecCapability.kind = cricket::MEDIA_TYPE_VIDEO; + } else { + RTC_DCHECK_NOTREACHED(); + } + if (_clockRate != nil) { + rtpCodecCapability.clock_rate = absl::optional(_clockRate.intValue); + } + if (_numChannels != nil) { + rtpCodecCapability.num_channels = absl::optional(_numChannels.intValue); + } + for (NSString *paramKey in _parameters.allKeys) { + std::string key = [NSString stdStringForString:paramKey]; + std::string value = [NSString stdStringForString:_parameters[paramKey]]; + rtpCodecCapability.parameters[key] = value; + } + return rtpCodecCapability; +} + +@end diff --git a/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h new file mode 100644 index 0000000000..4e800bc996 --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability+Private.h @@ -0,0 +1,34 @@ +/* + * Copyright 2024 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 "RTCRtpHeaderExtensionCapability.h" + +#include "api/rtp_parameters.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability)() + +/** +* The native RtpHeaderExtensionCapability representation of this +* RTCRtpHeaderExtensionCapability object. This is needed to pass to the underlying C++ APIs. +*/ +@property(nonatomic, + readonly) webrtc::RtpHeaderExtensionCapability nativeRtpHeaderExtensionCapability; + +/** + * Initialize an RTCRtpHeaderExtensionCapability from a native RtpHeaderExtensionCapability. + */ +- (instancetype)initWithNativeRtpHeaderExtensionCapability: + (const webrtc::RtpHeaderExtensionCapability &)rtpHeaderExtensionCapability; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h new file mode 100644 index 0000000000..7a5d442e6a --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.h @@ -0,0 +1,33 @@ +/* + * Copyright 2024 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 + +#import "RTCMacros.h" + +NS_ASSUME_NONNULL_BEGIN + +RTC_OBJC_EXPORT +@interface RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability) : NSObject + +/** The URI of the RTP header extension, as defined in RFC5285. */ +@property(nonatomic, readonly, copy) NSString *uri; + +/** The value put in the RTP packet to identify the header extension. */ +@property(nonatomic, readonly, nullable) NSNumber* preferredId; + +/** Whether the header extension is encrypted or not. */ +@property(nonatomic, readonly, getter=isPreferredEncrypted) BOOL preferredEncrypted; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm new file mode 100644 index 0000000000..c9af744a92 --- /dev/null +++ b/sdk/objc/api/peerconnection/RTCRtpHeaderExtensionCapability.mm @@ -0,0 +1,56 @@ +/* + * Copyright 2024 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 "RTCRtpHeaderExtensionCapability+Private.h" + +#import "helpers/NSString+StdString.h" + +@implementation RTC_OBJC_TYPE (RTCRtpHeaderExtensionCapability) + +@synthesize uri = _uri; +@synthesize preferredId = _preferredId; +@synthesize preferredEncrypted = _preferredEncrypted; + +- (instancetype)init { + webrtc::RtpHeaderExtensionCapability nativeRtpHeaderExtensionCapability; + return [self initWithNativeRtpHeaderExtensionCapability:nativeRtpHeaderExtensionCapability]; +} + +- (instancetype)initWithNativeRtpHeaderExtensionCapability: + (const webrtc::RtpHeaderExtensionCapability &)nativeRtpHeaderExtensionCapability { + if (self = [super init]) { + _uri = [NSString stringForStdString:nativeRtpHeaderExtensionCapability.uri]; + if (nativeRtpHeaderExtensionCapability.preferred_id) { + _preferredId = [NSNumber numberWithInt:*nativeRtpHeaderExtensionCapability.preferred_id]; + } + _preferredEncrypted = nativeRtpHeaderExtensionCapability.preferred_encrypt; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpHeaderExtensionCapability) {\n uri: " + @"%@\n preferredId: %@\n preferredEncrypted: %d\n}", + _uri, + _preferredId, + _preferredEncrypted]; +} + +- (webrtc::RtpHeaderExtensionCapability)nativeRtpHeaderExtensionCapability { + webrtc::RtpHeaderExtensionCapability rtpHeaderExtensionCapability; + rtpHeaderExtensionCapability.uri = [NSString stdStringForString:_uri]; + if (_preferredId != nil) { + rtpHeaderExtensionCapability.preferred_id = absl::optional(_preferredId.intValue); + } + rtpHeaderExtensionCapability.preferred_encrypt = _preferredEncrypted; + return rtpHeaderExtensionCapability; +} + +@end diff --git a/sdk/objc/api/peerconnection/RTCRtpTransceiver.h b/sdk/objc/api/peerconnection/RTCRtpTransceiver.h index fd59013639..1701f680a4 100644 --- a/sdk/objc/api/peerconnection/RTCRtpTransceiver.h +++ b/sdk/objc/api/peerconnection/RTCRtpTransceiver.h @@ -46,6 +46,7 @@ RTC_OBJC_EXPORT @end @class RTC_OBJC_TYPE(RTCRtpTransceiver); +@class RTC_OBJC_TYPE(RTCRtpCodecCapability); /** The RTCRtpTransceiver maps to the RTCRtpTransceiver defined by the * WebRTC specification. A transceiver represents a combination of an RTCRtpSender @@ -118,6 +119,12 @@ RTC_OBJC_EXPORT */ - (void)stopInternal; +/** The setCodecPreferences method overrides the default codec preferences used + * by WebRTC for this transceiver. + * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-setcodecpreferences + */ +- (void)setCodecPreferences:(NSArray *)codecs; + /** An update of directionality does not take effect immediately. Instead, * future calls to createOffer and createAnswer mark the corresponding media * descriptions as sendrecv, sendonly, recvonly, or inactive. diff --git a/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm b/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm index ae1cf79864..eb0ad96738 100644 --- a/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm +++ b/sdk/objc/api/peerconnection/RTCRtpTransceiver.mm @@ -10,6 +10,7 @@ #import "RTCRtpTransceiver+Private.h" +#import "RTCRtpCodecCapability+Private.h" #import "RTCRtpEncodingParameters+Private.h" #import "RTCRtpParameters+Private.h" #import "RTCRtpReceiver+Private.h" @@ -17,6 +18,8 @@ #import "base/RTCLogging.h" #import "helpers/NSString+StdString.h" +#include "api/rtp_parameters.h" + NSString *const kRTCRtpTransceiverErrorDomain = @"org.webrtc.RTCRtpTranceiver"; @implementation RTC_OBJC_TYPE (RTCRtpTransceiverInit) @@ -105,6 +108,14 @@ NSString *const kRTCRtpTransceiverErrorDomain = @"org.webrtc.RTCRtpTranceiver"; _nativeRtpTransceiver->StopInternal(); } +- (void)setCodecPreferences:(NSArray *)codecs { + std::vector codecCapabilities; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * rtpCodecCapability in codecs) { + codecCapabilities.push_back(rtpCodecCapability.nativeRtpCodecCapability); + } + _nativeRtpTransceiver->SetCodecPreferences(codecCapabilities); +} + - (NSString *)description { return [NSString stringWithFormat:@"RTC_OBJC_TYPE(RTCRtpTransceiver) {\n sender: %@\n receiver: %@\n}", diff --git a/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m b/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m index 56c74971b6..d1d9ca0352 100644 --- a/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m +++ b/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m @@ -8,6 +8,9 @@ * be found in the AUTHORS file in the root of the source tree. */ +#import "base/RTCVideoDecoderFactory.h" +#import "base/RTCVideoEncoderFactory.h" + #import "api/peerconnection/RTCAudioSource.h" #import "api/peerconnection/RTCConfiguration.h" #import "api/peerconnection/RTCDataChannel.h" @@ -16,6 +19,8 @@ #import "api/peerconnection/RTCMediaStreamTrack.h" #import "api/peerconnection/RTCPeerConnection.h" #import "api/peerconnection/RTCPeerConnectionFactory.h" +#import "api/peerconnection/RTCRtpCapabilities.h" +#import "api/peerconnection/RTCRtpCodecCapability.h" #import "api/peerconnection/RTCRtpReceiver.h" #import "api/peerconnection/RTCRtpSender.h" #import "api/peerconnection/RTCRtpTransceiver.h" @@ -25,6 +30,40 @@ #import +@interface MockVideoEncoderDecoderFactory + : NSObject +- (instancetype)initWithSupportedCodecs: + (nonnull NSArray *)supportedCodecs; +@end + +@implementation MockVideoEncoderDecoderFactory { + NSArray *_supportedCodecs; +} + +- (instancetype)initWithSupportedCodecs: + (nonnull NSArray *)supportedCodecs { + if (self = [super init]) { + _supportedCodecs = supportedCodecs; + } + return self; +} + +- (nullable id)createEncoder: + (nonnull RTC_OBJC_TYPE(RTCVideoCodecInfo) *)info { + return nil; +} + +- (nullable id)createDecoder: + (nonnull RTC_OBJC_TYPE(RTCVideoCodecInfo) *)info { + return nil; +} + +- (nonnull NSArray *)supportedCodecs { + return _supportedCodecs; +} + +@end + @interface RTCPeerConnectionFactoryTests : XCTestCase @end @@ -325,6 +364,147 @@ } } +- (void)testSenderCapabilities { + @autoreleasepool { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory; + MockVideoEncoderDecoderFactory *encoder; + MockVideoEncoderDecoderFactory *decoder; + + NSArray *supportedCodecs = @[ + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"], + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"] + ]; + + encoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + decoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder + decoderFactory:decoder]; + + RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities = + [factory rtpSenderCapabilitiesForKind:kRTCMediaStreamTrackKindVideo]; + NSMutableArray *codecNames = [NSMutableArray new]; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) { + [codecNames addObject:codec.name]; + } + + XCTAssertTrue([codecNames containsObject:@"VP8"]); + XCTAssertTrue([codecNames containsObject:@"H264"]); + factory = nil; + } +} + +- (void)testReceiverCapabilities { + @autoreleasepool { + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory; + MockVideoEncoderDecoderFactory *encoder; + MockVideoEncoderDecoderFactory *decoder; + + NSArray *supportedCodecs = @[ + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"], + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"] + ]; + + encoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + decoder = [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder + decoderFactory:decoder]; + + RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities = + [factory rtpReceiverCapabilitiesForKind:kRTCMediaStreamTrackKindVideo]; + NSMutableArray *codecNames = [NSMutableArray new]; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) { + [codecNames addObject:codec.name]; + } + + XCTAssertTrue([codecNames containsObject:@"VP8"]); + XCTAssertTrue([codecNames containsObject:@"H264"]); + factory = nil; + } +} + +- (void)testSetCodecPreferences { + @autoreleasepool { + RTC_OBJC_TYPE(RTCConfiguration) *config = [[RTC_OBJC_TYPE(RTCConfiguration) alloc] init]; + RTC_OBJC_TYPE(RTCMediaConstraints) *constraints = + [[RTC_OBJC_TYPE(RTCMediaConstraints) alloc] initWithMandatoryConstraints:nil + optionalConstraints:nil]; + RTC_OBJC_TYPE(RTCRtpTransceiverInit) *init = + [[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]; + + NSArray *supportedCodecs = @[ + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"VP8"], + [[RTC_OBJC_TYPE(RTCVideoCodecInfo) alloc] initWithName:@"H264"] + ]; + + MockVideoEncoderDecoderFactory *encoder = + [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + MockVideoEncoderDecoderFactory *decoder = + [[MockVideoEncoderDecoderFactory alloc] initWithSupportedCodecs:supportedCodecs]; + + RTC_OBJC_TYPE(RTCPeerConnectionFactory) * factory; + RTC_OBJC_TYPE(RTCPeerConnection) * peerConnection; + RTC_OBJC_TYPE(RTCRtpTransceiver) * tranceiver; + factory = [[RTC_OBJC_TYPE(RTCPeerConnectionFactory) alloc] initWithEncoderFactory:encoder + decoderFactory:decoder]; + + peerConnection = [factory peerConnectionWithConfiguration:config + constraints:constraints + delegate:nil]; + tranceiver = [peerConnection addTransceiverOfType:RTCRtpMediaTypeVideo init:init]; + XCTAssertNotNil(tranceiver); + + RTC_OBJC_TYPE(RTCRtpCapabilities) *capabilities = + [factory rtpReceiverCapabilitiesForKind:kRTCMediaStreamTrackKindVideo]; + + RTC_OBJC_TYPE(RTCRtpCodecCapability) * targetCodec; + for (RTC_OBJC_TYPE(RTCRtpCodecCapability) * codec in capabilities.codecs) { + if ([codec.name isEqual:@"VP8"]) { + targetCodec = codec; + break; + } + } + XCTAssertNotNil(targetCodec); + + [tranceiver setCodecPreferences:@[ targetCodec ]]; + + @autoreleasepool { + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + + __block BOOL completed = NO; + [peerConnection + offerForConstraints:constraints + completionHandler:^(RTCSessionDescription *_Nullable sdp, NSError *_Nullable error) { + XCTAssertNil(error); + XCTAssertNotNil(sdp); + + NSArray *rtpMaps = [self rtpMapsFromSDP:sdp.sdp]; + XCTAssertEqual(1, rtpMaps.count); + + XCTAssertNotNil(targetCodec.preferredPayloadType); + XCTAssertNotNil(targetCodec.clockRate); + + NSString *expected = + [NSString stringWithFormat:@"a=rtpmap:%i VP8/%i", + targetCodec.preferredPayloadType.intValue, + targetCodec.clockRate.intValue]; + + XCTAssertTrue([expected isEqualToString:rtpMaps[0]]); + + completed = YES; + dispatch_semaphore_signal(semaphore); + }]; + + [peerConnection close]; + peerConnection = nil; + factory = nil; + tranceiver = nil; + + dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 15.0 * NSEC_PER_SEC)); + XCTAssertTrue(completed); + } + } +} + - (bool)negotiatePeerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)pc1 withPeerConnection:(RTC_OBJC_TYPE(RTCPeerConnection) *)pc2 negotiationTimeout:(NSTimeInterval)timeout { @@ -377,4 +557,16 @@ dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC))); } +- (NSArray *)rtpMapsFromSDP:(NSString *)sdp { + NSMutableArray *rtpMaps = [NSMutableArray new]; + NSArray *sdpLines = + [sdp componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + for (NSString *line in sdpLines) { + if ([line hasPrefix:@"a=rtpmap"]) { + [rtpMaps addObject:line]; + } + } + return rtpMaps; +} + @end From 44e4453067ae2f27c3c571e9b4747b4e9ca7d885 Mon Sep 17 00:00:00 2001 From: Tommi Date: Tue, 23 Jan 2024 22:40:29 +0100 Subject: [PATCH 006/170] Fix Port test and supply a legal value for the port type. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This isn't a problem right now but will be when we move away from using a free string as the storage type. Bug: none Change-Id: I12c2de416f9fce13a8284e7d36fa3c2081453299 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335880 Reviewed-by: Björn Terelius Commit-Queue: Björn Terelius Auto-Submit: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41602} --- p2p/base/port_unittest.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/p2p/base/port_unittest.cc b/p2p/base/port_unittest.cc index de35d94259..ab3ff86fd1 100644 --- a/p2p/base/port_unittest.cc +++ b/p2p/base/port_unittest.cc @@ -825,9 +825,9 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> { absl::string_view username, absl::string_view password, const webrtc::FieldTrialsView* field_trials = nullptr) { - auto port = std::make_unique(&main_, "test", &socket_factory_, - MakeNetwork(addr), 0, 0, username, - password, field_trials); + auto port = std::make_unique( + &main_, cricket::LOCAL_PORT_TYPE, &socket_factory_, MakeNetwork(addr), + 0, 0, username, password, field_trials); port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict); return port; } @@ -845,8 +845,9 @@ class PortTest : public ::testing::Test, public sigslot::has_slots<> { std::unique_ptr CreateTestPort(const rtc::Network* network, absl::string_view username, absl::string_view password) { - auto port = std::make_unique(&main_, "test", &socket_factory_, - network, 0, 0, username, password); + auto port = std::make_unique(&main_, cricket::LOCAL_PORT_TYPE, + &socket_factory_, network, 0, 0, + username, password); port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict); return port; } From 5372bcec52705d484af8c496e85c9b1a88862621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= Date: Mon, 22 Jan 2024 09:56:09 +0100 Subject: [PATCH 007/170] Reland "[Stats] Make RTCStatsMember a type alias for absl::optional." MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a reland of commit 79ac694d9b70fa9cd7b6a0f00bbee5d7fbbe64de Original change's description: > [Stats] Make RTCStatsMember a type alias for absl::optional. > > The moment we've all been waiting for. > > Step 1: Add type alias (this CL). > Step 2: Migrate all uses of RTCStatsMember to absl::optional. > Step 3: Delete type alias. > > Bug: webrtc:15164 > Change-Id: I00a7202c0b684fb2c57fcad4f501bccc167f1fa3 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/334680 > Commit-Queue: Henrik Boström > Reviewed-by: Harald Alvestrand > Reviewed-by: Evan Shrubsole > Cr-Commit-Position: refs/heads/main@{#41593} # Only unrelated bot failures NOTRY=True Bug: webrtc:15164 Change-Id: I0f1991409326679a260cb24907808eaa28385350 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335960 Reviewed-by: Harald Alvestrand Commit-Queue: Henrik Boström Reviewed-by: Evan Shrubsole Cr-Commit-Position: refs/heads/main@{#41603} --- api/BUILD.gn | 1 - api/stats/attribute.h | 55 ++++++----- api/stats/rtc_stats.h | 1 - api/stats/rtc_stats_member.h | 185 ----------------------------------- stats/BUILD.gn | 1 - stats/attribute.cc | 19 ++-- stats/rtc_stats_member.cc | 62 ------------ stats/rtc_stats_unittest.cc | 96 +++++++----------- 8 files changed, 70 insertions(+), 350 deletions(-) delete mode 100644 api/stats/rtc_stats_member.h delete mode 100644 stats/rtc_stats_member.cc diff --git a/api/BUILD.gn b/api/BUILD.gn index 95850c6e17..0652552eb3 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -774,7 +774,6 @@ rtc_source_set("rtc_stats_api") { "stats/attribute.h", "stats/rtc_stats.h", "stats/rtc_stats_collector_callback.h", - "stats/rtc_stats_member.h", "stats/rtc_stats_report.h", "stats/rtcstats_objects.h", ] diff --git a/api/stats/attribute.h b/api/stats/attribute.h index 09211f469c..d5fb290750 100644 --- a/api/stats/attribute.h +++ b/api/stats/attribute.h @@ -16,37 +16,41 @@ #include #include +#include "absl/types/optional.h" #include "absl/types/variant.h" -#include "api/stats/rtc_stats_member.h" +#include "rtc_base/checks.h" #include "rtc_base/system/rtc_export.h" namespace webrtc { +// TODO(https://crbug.com/webrtc/15164): Migrate all uses of RTCStatsMember to +// absl::optional and delete this type alias. +template +using RTCStatsMember = absl::optional; + // A light-weight wrapper of an RTCStats attribute (an individual metric). class RTC_EXPORT Attribute { public: - // TODO(https://crbug.com/webrtc/15164): Replace uses of RTCStatsMember - // with absl::optional and update these pointer types. - typedef absl::variant*, - const RTCStatsMember*, - const RTCStatsMember*, - const RTCStatsMember*, - const RTCStatsMember*, - const RTCStatsMember*, - const RTCStatsMember*, - const RTCStatsMember>*, - const RTCStatsMember>*, - const RTCStatsMember>*, - const RTCStatsMember>*, - const RTCStatsMember>*, - const RTCStatsMember>*, - const RTCStatsMember>*, - const RTCStatsMember>*, - const RTCStatsMember>*> + typedef absl::variant*, + const absl::optional*, + const absl::optional*, + const absl::optional*, + const absl::optional*, + const absl::optional*, + const absl::optional*, + const absl::optional>*, + const absl::optional>*, + const absl::optional>*, + const absl::optional>*, + const absl::optional>*, + const absl::optional>*, + const absl::optional>*, + const absl::optional>*, + const absl::optional>*> StatVariant; template - explicit Attribute(const char* name, const RTCStatsMember* attribute) + Attribute(const char* name, const absl::optional* attribute) : name_(name), attribute_(attribute) {} const char* name() const; @@ -55,21 +59,18 @@ class RTC_EXPORT Attribute { bool has_value() const; template bool holds_alternative() const { - return absl::holds_alternative*>(attribute_); + return absl::holds_alternative*>(attribute_); } template - absl::optional as_optional() const { + const absl::optional& as_optional() const { RTC_CHECK(holds_alternative()); - if (!has_value()) { - return absl::nullopt; - } - return absl::optional(get()); + return *absl::get*>(attribute_); } template const T& get() const { RTC_CHECK(holds_alternative()); RTC_CHECK(has_value()); - return absl::get*>(attribute_)->value(); + return absl::get*>(attribute_)->value(); } bool is_sequence() const; diff --git a/api/stats/rtc_stats.h b/api/stats/rtc_stats.h index edd293f5c9..678108109a 100644 --- a/api/stats/rtc_stats.h +++ b/api/stats/rtc_stats.h @@ -21,7 +21,6 @@ #include #include "api/stats/attribute.h" -#include "api/stats/rtc_stats_member.h" #include "api/units/timestamp.h" #include "rtc_base/checks.h" #include "rtc_base/system/rtc_export.h" diff --git a/api/stats/rtc_stats_member.h b/api/stats/rtc_stats_member.h deleted file mode 100644 index 9039569ede..0000000000 --- a/api/stats/rtc_stats_member.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2023 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_STATS_RTC_STATS_MEMBER_H_ -#define API_STATS_RTC_STATS_MEMBER_H_ - -#include -#include -#include -#include - -#include "absl/types/optional.h" -#include "rtc_base/checks.h" -#include "rtc_base/system/rtc_export.h" -#include "rtc_base/system/rtc_export_template.h" - -namespace webrtc { - -// Interface for `RTCStats` members, which have a name and a value of a type -// defined in a subclass. Only the types listed in `Type` are supported, these -// are implemented by `RTCStatsMember`. The value of a member may be -// undefined, the value can only be read if `is_defined`. -class RTCStatsMemberInterface { - public: - // Member value types. - enum Type { - kBool, // bool - kInt32, // int32_t - kUint32, // uint32_t - kInt64, // int64_t - kUint64, // uint64_t - kDouble, // double - kString, // std::string - - kSequenceBool, // std::vector - kSequenceInt32, // std::vector - kSequenceUint32, // std::vector - kSequenceInt64, // std::vector - kSequenceUint64, // std::vector - kSequenceDouble, // std::vector - kSequenceString, // std::vector - - kMapStringUint64, // std::map - kMapStringDouble, // std::map - }; - - virtual ~RTCStatsMemberInterface() {} - - virtual Type type() const = 0; - virtual bool is_sequence() const = 0; - virtual bool is_string() const = 0; - virtual bool has_value() const = 0; - // Type and value comparator. The names are not compared. These operators are - // exposed for testing. - bool operator==(const RTCStatsMemberInterface& other) const { - return IsEqual(other); - } - bool operator!=(const RTCStatsMemberInterface& other) const { - return !(*this == other); - } - - virtual const RTCStatsMemberInterface* member_ptr() const { return this; } - template - const T& cast_to() const { - RTC_DCHECK_EQ(type(), T::StaticType()); - return static_cast(*member_ptr()); - } - - protected: - virtual bool IsEqual(const RTCStatsMemberInterface& other) const = 0; -}; - -// Template implementation of `RTCStatsMemberInterface`. -// The supported types are the ones described by -// `RTCStatsMemberInterface::Type`. -template -class RTCStatsMember : public RTCStatsMemberInterface { - public: - RTCStatsMember() {} - explicit RTCStatsMember(const T& value) : value_(value) {} - - static Type StaticType(); - Type type() const override { return StaticType(); } - bool is_sequence() const override; - bool is_string() const override; - - template - inline T value_or(U default_value) const { - return value_.value_or(default_value); - } - // TODO(https://crbug.com/webrtc/15164): Migrate to value_or() and delete. - template - inline T ValueOrDefault(U default_value) const { - return value_or(default_value); - } - - // Assignment operators. - T& operator=(const T& value) { - value_ = value; - return value_.value(); - } - T& operator=(const T&& value) { - value_ = std::move(value); - return value_.value(); - } - - // Getter methods that look the same as absl::optional. Please prefer these - // in order to unblock replacing RTCStatsMember with absl::optional in - // the future (https://crbug.com/webrtc/15164). - bool has_value() const override { return value_.has_value(); } - const T& value() const { return value_.value(); } - T& value() { return value_.value(); } - T& operator*() { - RTC_DCHECK(value_); - return *value_; - } - const T& operator*() const { - RTC_DCHECK(value_); - return *value_; - } - T* operator->() { - RTC_DCHECK(value_); - return &(*value_); - } - const T* operator->() const { - RTC_DCHECK(value_); - return &(*value_); - } - - bool IsEqual(const RTCStatsMemberInterface& other) const override { - if (type() != other.type()) - return false; - const RTCStatsMember& other_t = - static_cast&>(other); - return value_ == other_t.value_; - } - - private: - absl::optional value_; -}; - -namespace rtc_stats_internal { - -typedef std::map MapStringUint64; -typedef std::map MapStringDouble; - -} // namespace rtc_stats_internal - -#define WEBRTC_DECLARE_RTCSTATSMEMBER(T) \ - template <> \ - RTC_EXPORT RTCStatsMemberInterface::Type RTCStatsMember::StaticType(); \ - template <> \ - RTC_EXPORT bool RTCStatsMember::is_sequence() const; \ - template <> \ - RTC_EXPORT bool RTCStatsMember::is_string() const; \ - extern template class RTC_EXPORT_TEMPLATE_DECLARE(RTC_EXPORT) \ - RTCStatsMember - -WEBRTC_DECLARE_RTCSTATSMEMBER(bool); -WEBRTC_DECLARE_RTCSTATSMEMBER(int32_t); -WEBRTC_DECLARE_RTCSTATSMEMBER(uint32_t); -WEBRTC_DECLARE_RTCSTATSMEMBER(int64_t); -WEBRTC_DECLARE_RTCSTATSMEMBER(uint64_t); -WEBRTC_DECLARE_RTCSTATSMEMBER(double); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::string); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); -WEBRTC_DECLARE_RTCSTATSMEMBER(std::vector); -WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64); -WEBRTC_DECLARE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble); - -} // namespace webrtc - -#endif // API_STATS_RTC_STATS_MEMBER_H_ diff --git a/stats/BUILD.gn b/stats/BUILD.gn index 8993272921..76edc441cb 100644 --- a/stats/BUILD.gn +++ b/stats/BUILD.gn @@ -18,7 +18,6 @@ rtc_library("rtc_stats") { sources = [ "attribute.cc", "rtc_stats.cc", - "rtc_stats_member.cc", "rtc_stats_report.cc", "rtcstats_objects.cc", ] diff --git a/stats/attribute.cc b/stats/attribute.cc index fab948b1bd..cf49cb2311 100644 --- a/stats/attribute.cc +++ b/stats/attribute.cc @@ -25,12 +25,12 @@ namespace { struct VisitIsSequence { // Any type of vector is a sequence. template - bool operator()(const RTCStatsMember>* attribute) { + bool operator()(const absl::optional>* attribute) { return true; } // Any other type is not. template - bool operator()(const RTCStatsMember* attribute) { + bool operator()(const absl::optional* attribute) { return false; } }; @@ -62,7 +62,7 @@ struct VisitToString { // Vector attributes. template - std::string operator()(const RTCStatsMember>* attribute) { + std::string operator()(const absl::optional>* attribute) { rtc::StringBuilder sb; sb << "["; const char* separator = ""; @@ -84,7 +84,7 @@ struct VisitToString { // Map attributes. template std::string operator()( - const RTCStatsMember>* attribute) { + const absl::optional>* attribute) { rtc::StringBuilder sb; sb << "{"; const char* separator = ""; @@ -106,21 +106,18 @@ struct VisitToString { } // Simple attributes. template - std::string operator()(const RTCStatsMember* attribute) { + std::string operator()(const absl::optional* attribute) { return ValueToString(attribute->value()); } }; struct VisitIsEqual { template - bool operator()(const RTCStatsMember* attribute) { + bool operator()(const absl::optional* attribute) { if (!other.holds_alternative()) { return false; } - absl::optional attribute_as_optional = - attribute->has_value() ? absl::optional(attribute->value()) - : absl::nullopt; - return attribute_as_optional == other.as_optional(); + return *attribute == other.as_optional(); } const Attribute& other; @@ -146,7 +143,7 @@ bool Attribute::is_sequence() const { } bool Attribute::is_string() const { - return absl::holds_alternative*>( + return absl::holds_alternative*>( attribute_); } diff --git a/stats/rtc_stats_member.cc b/stats/rtc_stats_member.cc deleted file mode 100644 index 3f91988ed0..0000000000 --- a/stats/rtc_stats_member.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2023 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/stats/rtc_stats_member.h" - -namespace webrtc { - -#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str) \ - template <> \ - RTCStatsMemberInterface::Type RTCStatsMember::StaticType() { \ - return type; \ - } \ - template <> \ - bool RTCStatsMember::is_sequence() const { \ - return is_seq; \ - } \ - template <> \ - bool RTCStatsMember::is_string() const { \ - return is_str; \ - } \ - template class RTC_EXPORT_TEMPLATE_DEFINE(RTC_EXPORT) RTCStatsMember - -WEBRTC_DEFINE_RTCSTATSMEMBER(bool, kBool, false, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, kInt32, false, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, kUint32, false, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, kInt64, false, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, kUint64, false, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(double, kDouble, false, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceBool, true, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceInt32, true, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, - kSequenceUint32, - true, - false); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceInt64, true, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, - kSequenceUint64, - true, - false); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, kSequenceDouble, true, false); -WEBRTC_DEFINE_RTCSTATSMEMBER(std::vector, - kSequenceString, - true, - false); -WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringUint64, - kMapStringUint64, - false, - false); -WEBRTC_DEFINE_RTCSTATSMEMBER(rtc_stats_internal::MapStringDouble, - kMapStringDouble, - false, - false); - -} // namespace webrtc diff --git a/stats/rtc_stats_unittest.cc b/stats/rtc_stats_unittest.cc index fd90692875..1098f04b65 100644 --- a/stats/rtc_stats_unittest.cc +++ b/stats/rtc_stats_unittest.cc @@ -166,7 +166,8 @@ TEST(RTCStatsTest, EqualityOperator) { stats_with_all_values.m_map_string_double = std::map(); EXPECT_NE(stats_with_all_values, empty_stats); EXPECT_EQ(stats_with_all_values, stats_with_all_values); - EXPECT_NE(stats_with_all_values.m_int32, stats_with_all_values.m_uint32); + EXPECT_NE(stats_with_all_values.GetAttribute(stats_with_all_values.m_int32), + stats_with_all_values.GetAttribute(stats_with_all_values.m_uint32)); RTCTestStats one_member_different[] = { stats_with_all_values, stats_with_all_values, stats_with_all_values, @@ -392,71 +393,42 @@ TEST(RTCStatsTest, RTCStatsPrintsValidJson) { TEST(RTCStatsTest, IsSequence) { RTCTestStats stats("statsId", Timestamp::Micros(42)); - EXPECT_FALSE(stats.m_bool.is_sequence()); - EXPECT_FALSE(stats.m_int32.is_sequence()); - EXPECT_FALSE(stats.m_uint32.is_sequence()); - EXPECT_FALSE(stats.m_int64.is_sequence()); - EXPECT_FALSE(stats.m_uint64.is_sequence()); - EXPECT_FALSE(stats.m_double.is_sequence()); - EXPECT_FALSE(stats.m_string.is_sequence()); - EXPECT_TRUE(stats.m_sequence_bool.is_sequence()); - EXPECT_TRUE(stats.m_sequence_int32.is_sequence()); - EXPECT_TRUE(stats.m_sequence_uint32.is_sequence()); - EXPECT_TRUE(stats.m_sequence_int64.is_sequence()); - EXPECT_TRUE(stats.m_sequence_uint64.is_sequence()); - EXPECT_TRUE(stats.m_sequence_double.is_sequence()); - EXPECT_TRUE(stats.m_sequence_string.is_sequence()); - EXPECT_FALSE(stats.m_map_string_uint64.is_sequence()); - EXPECT_FALSE(stats.m_map_string_double.is_sequence()); -} - -TEST(RTCStatsTest, Type) { - RTCTestStats stats("statsId", Timestamp::Micros(42)); - EXPECT_EQ(RTCStatsMemberInterface::kBool, stats.m_bool.type()); - EXPECT_EQ(RTCStatsMemberInterface::kInt32, stats.m_int32.type()); - EXPECT_EQ(RTCStatsMemberInterface::kUint32, stats.m_uint32.type()); - EXPECT_EQ(RTCStatsMemberInterface::kInt64, stats.m_int64.type()); - EXPECT_EQ(RTCStatsMemberInterface::kUint64, stats.m_uint64.type()); - EXPECT_EQ(RTCStatsMemberInterface::kDouble, stats.m_double.type()); - EXPECT_EQ(RTCStatsMemberInterface::kString, stats.m_string.type()); - EXPECT_EQ(RTCStatsMemberInterface::kSequenceBool, - stats.m_sequence_bool.type()); - EXPECT_EQ(RTCStatsMemberInterface::kSequenceInt32, - stats.m_sequence_int32.type()); - EXPECT_EQ(RTCStatsMemberInterface::kSequenceUint32, - stats.m_sequence_uint32.type()); - EXPECT_EQ(RTCStatsMemberInterface::kSequenceInt64, - stats.m_sequence_int64.type()); - EXPECT_EQ(RTCStatsMemberInterface::kSequenceUint64, - stats.m_sequence_uint64.type()); - EXPECT_EQ(RTCStatsMemberInterface::kSequenceDouble, - stats.m_sequence_double.type()); - EXPECT_EQ(RTCStatsMemberInterface::kSequenceString, - stats.m_sequence_string.type()); - EXPECT_EQ(RTCStatsMemberInterface::kMapStringUint64, - stats.m_map_string_uint64.type()); - EXPECT_EQ(RTCStatsMemberInterface::kMapStringDouble, - stats.m_map_string_double.type()); + EXPECT_FALSE(stats.GetAttribute(stats.m_bool).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_int32).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_uint32).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_int64).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_uint64).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_double).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_string).is_sequence()); + EXPECT_TRUE(stats.GetAttribute(stats.m_sequence_bool).is_sequence()); + EXPECT_TRUE(stats.GetAttribute(stats.m_sequence_int32).is_sequence()); + EXPECT_TRUE(stats.GetAttribute(stats.m_sequence_uint32).is_sequence()); + EXPECT_TRUE(stats.GetAttribute(stats.m_sequence_int64).is_sequence()); + EXPECT_TRUE(stats.GetAttribute(stats.m_sequence_uint64).is_sequence()); + EXPECT_TRUE(stats.GetAttribute(stats.m_sequence_double).is_sequence()); + EXPECT_TRUE(stats.GetAttribute(stats.m_sequence_string).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_map_string_uint64).is_sequence()); + EXPECT_FALSE(stats.GetAttribute(stats.m_map_string_double).is_sequence()); } TEST(RTCStatsTest, IsString) { RTCTestStats stats("statsId", Timestamp::Micros(42)); - EXPECT_TRUE(stats.m_string.is_string()); - EXPECT_FALSE(stats.m_bool.is_string()); - EXPECT_FALSE(stats.m_int32.is_string()); - EXPECT_FALSE(stats.m_uint32.is_string()); - EXPECT_FALSE(stats.m_int64.is_string()); - EXPECT_FALSE(stats.m_uint64.is_string()); - EXPECT_FALSE(stats.m_double.is_string()); - EXPECT_FALSE(stats.m_sequence_bool.is_string()); - EXPECT_FALSE(stats.m_sequence_int32.is_string()); - EXPECT_FALSE(stats.m_sequence_uint32.is_string()); - EXPECT_FALSE(stats.m_sequence_int64.is_string()); - EXPECT_FALSE(stats.m_sequence_uint64.is_string()); - EXPECT_FALSE(stats.m_sequence_double.is_string()); - EXPECT_FALSE(stats.m_sequence_string.is_string()); - EXPECT_FALSE(stats.m_map_string_uint64.is_string()); - EXPECT_FALSE(stats.m_map_string_double.is_string()); + EXPECT_TRUE(stats.GetAttribute(stats.m_string).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_bool).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_int32).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_uint32).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_int64).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_uint64).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_double).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_sequence_bool).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_sequence_int32).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_sequence_uint32).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_sequence_int64).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_sequence_uint64).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_sequence_double).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_sequence_string).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_map_string_uint64).is_string()); + EXPECT_FALSE(stats.GetAttribute(stats.m_map_string_double).is_string()); } TEST(RTCStatsTest, AttributeToString) { From a8375bb973721e019f033311ec04a40697ae3180 Mon Sep 17 00:00:00 2001 From: Florent Castelli Date: Wed, 24 Jan 2024 15:41:06 +0100 Subject: [PATCH 008/170] iOS: Fix building tests on real devices Bug: webrtc:15797 Change-Id: Ieae0a08bb6b141cb70d6c865bf98041f1d21e1ca Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336060 Commit-Queue: Florent Castelli Auto-Submit: Florent Castelli Reviewed-by: Peter Hanspers Reviewed-by: Christoffer Dewerin Cr-Commit-Position: refs/heads/main@{#41604} --- sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m b/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m index d1d9ca0352..7d42b6bdbb 100644 --- a/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m +++ b/sdk/objc/unittests/RTCPeerConnectionFactory_xctest.m @@ -473,7 +473,8 @@ __block BOOL completed = NO; [peerConnection offerForConstraints:constraints - completionHandler:^(RTCSessionDescription *_Nullable sdp, NSError *_Nullable error) { + completionHandler:^(RTC_OBJC_TYPE(RTCSessionDescription) *_Nullable sdp, + NSError *_Nullable error) { XCTAssertNil(error); XCTAssertNotNil(sdp); From b7e8a10fe43c58d438e8bcfc5e4cbc49393c95b5 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Wed, 24 Jan 2024 23:52:18 -0800 Subject: [PATCH 009/170] Roll chromium_revision cf886b3ada..712952759e (1250272:1251936) Change log: https://chromium.googlesource.com/chromium/src/+log/cf886b3ada..712952759e Full diff: https://chromium.googlesource.com/chromium/src/+/cf886b3ada..712952759e Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/515107a79c..51853d9cce * src/build: https://chromium.googlesource.com/chromium/src/build/+log/5b6a44ceba..f0e6a46076 * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/797a5979e6..d8688b9036 * src/buildtools/linux64: git_revision:f99e015ac35f689cfdbf46e4eb174e5d2da78d8e..git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef * src/buildtools/mac: git_revision:f99e015ac35f689cfdbf46e4eb174e5d2da78d8e..git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef * src/buildtools/win: git_revision:f99e015ac35f689cfdbf46e4eb174e5d2da78d8e..git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/165d473065..8ab02af836 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/7ecc2765e4..6bed18b881 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/b4357120e9..821b8dc4d9 * src/third_party/android_build_tools/aapt2: y1G4s2RWI63L9ZLgzS3RzFdWdeblpCmYyAUzMphcQawC..G1S0vNnfv3f8FD-9mH5RFSUiK-mnSwri_IdiVQKwLP0C * src/third_party/android_build_tools/manifest_merger: tFbjqslkduDT_-y8WEZlsl9iulzcm3mgienslcU71poC..fPIg5SQ9nbj982soSMoZlTPVfZ2zVKZRusg-r0ONCxUC * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/3e413d7b62..d1eeccf9e4 * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/c341d58921..2bc81cdf4f * src/third_party/fuzztest/src: https://chromium.googlesource.com/external/github.com/google/fuzztest.git/+log/12e7428ab0..a6db991e3e * src/third_party/libaom/source/libaom: https://aomedia.googlesource.com/aom.git/+log/646f28605e..1a72ea323d * src/third_party/libc++/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git/+log/24cb5545a9..28aa23ffb4 * src/third_party/libc++abi/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git/+log/9986707a5f..a46df1f416 * src/third_party/libunwind/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git/+log/f400fdb561..fc505746f0 * src/third_party/libvpx/source/libvpx: https://chromium.googlesource.com/webm/libvpx.git/+log/b95d175726..eeb1be7f23 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/30666f946a..bd299c3878 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/949b7e6342..d090bfe02e DEPS diff: https://chromium.googlesource.com/chromium/src/+/cf886b3ada..712952759e/DEPS No update to Clang. BUG=None Change-Id: If2af0b600defdf147840feabf69f0b0ac74ad58b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336160 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41605} --- DEPS | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/DEPS b/DEPS index 22ca235dc5..d3740bb021 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'cf886b3ada97beff0d89d9a3d96c0d7ca96441ed', + 'chromium_revision': '712952759e824f309c244a18ff426fe5d1e706ca', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,30 +50,30 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@515107a79caeb828608252f764728c65ad0ebe78', + 'https://chromium.googlesource.com/chromium/src/base@51853d9cce5aee38c5cbc9e7819aa6b93ec95a12', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@5b6a44ceba681ccb85a38846fff19be0bb011167', + 'https://chromium.googlesource.com/chromium/src/build@f0e6a4607685263efe102982265fe581d805dc07', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@797a5979e6215c6a2ffd84e22bb873d89d573594', + 'https://chromium.googlesource.com/chromium/src/buildtools@d8688b9036d46d14ef1f6fc26bcbb1da2b17f897', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@165d473065c84624a718ffb29936dfeee688922d', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@8ab02af836755c8bd6e3e546f4d599e4c6b239c0', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@7ecc2765e4d3b4224c00d3dee556daa937b667ba', + 'https://chromium.googlesource.com/chromium/src/testing@6bed18b881f3c27c8c246cfbc1e147c0912dfc91', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@b4357120e9be1fbb8d6377115bde87bce745382e', + 'https://chromium.googlesource.com/chromium/src/third_party@821b8dc4d9f4db913694650f9da067e6d3619590', 'src/buildtools/linux64': { 'packages': [ { 'package': 'gn/gn/linux-${{arch}}', - 'version': 'git_revision:f99e015ac35f689cfdbf46e4eb174e5d2da78d8e', + 'version': 'git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef', } ], 'dep_type': 'cipd', @@ -83,7 +83,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/mac-${{arch}}', - 'version': 'git_revision:f99e015ac35f689cfdbf46e4eb174e5d2da78d8e', + 'version': 'git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef', } ], 'dep_type': 'cipd', @@ -93,7 +93,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/windows-amd64', - 'version': 'git_revision:f99e015ac35f689cfdbf46e4eb174e5d2da78d8e', + 'version': 'git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef', } ], 'dep_type': 'cipd', @@ -115,11 +115,11 @@ deps = { 'src/third_party/clang-format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@e5337933f2951cacd3aeacd238ce4578163ca0b9', 'src/third_party/libc++/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@24cb5545a9a648f580ef7ce7b758689578f0a2a7', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@28aa23ffb4c7344914a5b4ac7169f12e5a12333f', 'src/third_party/libc++abi/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@9986707a5f2fc6d5d1ffa7f224a032bdd45c95fd', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@a46df1f416d9bbaa25bceaa684418f94ec3935b2', 'src/third_party/libunwind/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@f400fdb561d4416b59b8f8a33d8ec8b79da60495', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@fc505746f02c927d792bdeb328307e0e87500342', 'src/third_party/ninja': { 'packages': [ @@ -155,7 +155,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/aapt2', - 'version': 'y1G4s2RWI63L9ZLgzS3RzFdWdeblpCmYyAUzMphcQawC', + 'version': 'G1S0vNnfv3f8FD-9mH5RFSUiK-mnSwri_IdiVQKwLP0C', }, ], 'condition': 'checkout_android', @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@62ecd463583d09eb7d15b1d410055f30b2c7bcb4', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@3e413d7b62c09fda8713146714ba2146a0369d86', + 'https://chromium.googlesource.com/catapult.git@d1eeccf9e4a273c3639d6554c889f8ee3ca9bc0d', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@c341d58921ab188e4edacce04a221559bce86e8d', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@2bc81cdf4f2f384527eb2e3a39f2e38a4a8193b5', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@17525de887d54b970ffdd421a0879c1db1952307', 'src/third_party/flatbuffers/src': @@ -288,7 +288,7 @@ deps = { 'src/third_party/libFuzzer/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/compiler-rt/lib/fuzzer.git@758bd21f103a501b362b1ca46fa8fcb692eaa303', 'src/third_party/fuzztest/src': - 'https://chromium.googlesource.com/external/github.com/google/fuzztest.git@12e7428ab0847b1d1dc6c4b89203adfd1f16a1ad', + 'https://chromium.googlesource.com/external/github.com/google/fuzztest.git@a6db991e3e487c4bf131fe8de737267e2b1ecfa4', 'src/third_party/libjpeg_turbo': 'https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git@9b894306ec3b28cea46e84c32b56773a98c483da', 'src/third_party/libsrtp': @@ -296,15 +296,15 @@ deps = { 'src/third_party/dav1d/libdav1d': 'https://chromium.googlesource.com/external/github.com/videolan/dav1d.git@47107e384bd1dc25674acf04d000a8cdc6195234', 'src/third_party/libaom/source/libaom': - 'https://aomedia.googlesource.com/aom.git@646f28605eed1076d784451faa05a4e91e46ff6e', + 'https://aomedia.googlesource.com/aom.git@1a72ea323d65e46eb90d08d492c04891abb91926', 'src/third_party/libunwindstack': { 'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@a3bb4cd02e0e984a235069f812cbef2b37c389e5', 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@30666f946a71e4e05cb789cc391472b6c21c7741', + 'https://android.googlesource.com/platform/external/perfetto.git@bd299c3878ebd23de57b0f1cef2811a92c6a3407', 'src/third_party/libvpx/source/libvpx': - 'https://chromium.googlesource.com/webm/libvpx.git@b95d17572629c676bdcfd535fb3990b9f6f8fb11', + 'https://chromium.googlesource.com/webm/libvpx.git@eeb1be7f23eee652372df4fa3b14cf542ee2c040', 'src/third_party/libyuv': 'https://chromium.googlesource.com/libyuv/libyuv.git@04821d1e7d60845525e8db55c7bcd41ef5be9406', 'src/third_party/lss': { @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@949b7e63427db605f268538821e5f94e64229079', + 'https://chromium.googlesource.com/chromium/src/tools@d090bfe02ee2ac2363114ae3172fbc44ae9e1a80', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -416,7 +416,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': 'tFbjqslkduDT_-y8WEZlsl9iulzcm3mgienslcU71poC', + 'version': 'fPIg5SQ9nbj982soSMoZlTPVfZ2zVKZRusg-r0ONCxUC', }, ], 'condition': 'checkout_android', From c13a7f9a00a946a56f79a982296ff1b634cc47e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= Date: Thu, 25 Jan 2024 09:50:50 +0100 Subject: [PATCH 010/170] Change string constant to constexpr char[] to unblock roll. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Should fix the "Chromium Binary Size" failures on for example https://chromium-review.googlesource.com/c/chromium/src/+/5234153. For the "Mutable Constants Added & Removed" check. NOTRY=True Bug: webrtc:15164 Change-Id: I5713e224018460edee5d4fd2d028c27834f46b00 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336200 Reviewed-by: Mirko Bonadei Commit-Queue: Henrik Boström Cr-Commit-Position: refs/heads/main@{#41606} --- pc/rtc_stats_collector.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index a5a3067fa1..6de174b065 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -72,7 +72,7 @@ namespace { const char kDirectionInbound = 'I'; const char kDirectionOutbound = 'O'; -const char* kAudioPlayoutSingletonId = "AP"; +static constexpr char kAudioPlayoutSingletonId[] = "AP"; // TODO(https://crbug.com/webrtc/10656): Consider making IDs less predictable. std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) { From de3c726121bd097e79a8f1aa43df48aab7e2237f Mon Sep 17 00:00:00 2001 From: Christoffer Dewerin Date: Mon, 22 Jan 2024 12:01:44 +0100 Subject: [PATCH 011/170] Update to vpython 3.11 and remove .vpython (v2.x) Bug: b/310806212 Change-Id: I7fdb12ee4f83410bed9358e7249e4601e773056f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335641 Reviewed-by: Mirko Bonadei Commit-Queue: Christoffer Dewerin Cr-Commit-Position: refs/heads/main@{#41607} --- .vpython | 76 ------------------------------------------------------- .vpython3 | 38 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 95 deletions(-) delete mode 100644 .vpython diff --git a/.vpython b/.vpython deleted file mode 100644 index d226875f02..0000000000 --- a/.vpython +++ /dev/null @@ -1,76 +0,0 @@ -# This is a vpython "spec" file. -# -# It describes patterns for python wheel dependencies of the python scripts in -# the chromium repo, particularly for dependencies that have compiled components -# (since pure-python dependencies can be easily vendored into third_party). -# -# When vpython is invoked, it finds this file and builds a python VirtualEnv, -# containing all of the dependencies described in this file, fetching them from -# CIPD (the "Chrome Infrastructure Package Deployer" service). Unlike `pip`, -# this never requires the end-user machine to have a working python extension -# compilation environment. All of these packages are built using: -# https://chromium.googlesource.com/infra/infra/+/main/infra/tools/dockerbuild/ -# -# All python scripts in the repo share this same spec, to avoid dependency -# fragmentation. -# -# If you have depot_tools installed in your $PATH, you can invoke python scripts -# in this repo by running them as you normally would run them, except -# substituting `vpython` instead of `python` on the command line, e.g.: -# vpython path/to/script.py some --arguments -# -# Read more about `vpython` and how to modify this file here: -# https://chromium.googlesource.com/infra/infra/+/main/doc/users/vpython.md - -python_version: "2.7" - -# Used by: -# third_party/catapult -wheel: < - name: "infra/python/wheels/psutil/${platform}_${py_python}_${py_abi}" - version: "version:5.2.2" -> - -# Used by tools_webrtc/perf/process_perf_results.py. -wheel: < - name: "infra/python/wheels/httplib2-py2_py3" - version: "version:0.10.3" -> - -# Used by: -# build/toolchain/win -wheel: < - name: "infra/python/wheels/pypiwin32/${vpython_platform}" - version: "version:219" - match_tag: < - platform: "win32" - > - match_tag: < - platform: "win_amd64" - > -> - -wheel: < - name: "infra/python/wheels/six-py2_py3" - version: "version:1.15.0" -> -wheel: < - name: "infra/python/wheels/pbr-py2_py3" - version: "version:3.0.0" -> -wheel: < - name: "infra/python/wheels/funcsigs-py2_py3" - version: "version:1.0.2" -> -wheel: < - name: "infra/python/wheels/mock-py2_py3" - version: "version:2.0.0" -> -wheel: < - name: "infra/python/wheels/protobuf-py2_py3" - version: "version:3.13.0" -> -wheel: < - name: "infra/python/wheels/requests-py2_py3" - version: "version:2.13.0" -> diff --git a/.vpython3 b/.vpython3 index 3f571df261..2be8efaa0a 100644 --- a/.vpython3 +++ b/.vpython3 @@ -22,24 +22,24 @@ # Read more about `vpython` and how to modify this file here: # https://chromium.googlesource.com/infra/infra/+/main/doc/users/vpython.md -python_version: "3.8" +python_version: "3.11" # Used by: # third_party/catapult wheel: < name: "infra/python/wheels/psutil/${vpython_platform}" - version: "version:5.8.0.chromium.2" + version: "version:5.8.0.chromium.3" > # Used by tools_webrtc/perf/process_perf_results.py. wheel: < name: "infra/python/wheels/httplib2-py3" - version: "version:0.19.1" + version: "version:0.22.0" > wheel: < - name: "infra/python/wheels/pyparsing-py2_py3" - version: "version:2.4.7" + name: "infra/python/wheels/pyparsing-py3" + version: "version:3.1.1" > @@ -47,7 +47,7 @@ wheel: < # build/toolchain/win wheel: < name: "infra/python/wheels/pywin32/${vpython_platform}" - version: "version:300" + version: "version:306" match_tag: < platform: "win32" > @@ -59,48 +59,48 @@ wheel: < # GRPC used by iOS test. wheel: < name: "infra/python/wheels/grpcio/${vpython_platform}" - version: "version:1.44.0" + version: "version:1.57.0" > wheel: < name: "infra/python/wheels/six-py2_py3" - version: "version:1.15.0" + version: "version:1.16.0" > wheel: < name: "infra/python/wheels/pbr-py2_py3" - version: "version:3.0.0" + version: "version:5.9.0" > wheel: < name: "infra/python/wheels/funcsigs-py2_py3" version: "version:1.0.2" > wheel: < - name: "infra/python/wheels/mock-py2_py3" - version: "version:2.0.0" + name: "infra/python/wheels/mock-py3" + version: "version:4.0.3" > wheel: < name: "infra/python/wheels/protobuf-py3" - version: "version:3.20.0" + version: "version:4.25.1" > wheel: < name: "infra/python/wheels/requests-py3" version: "version:2.31.0" > wheel: < - name: "infra/python/wheels/idna-py2_py3" - version: "version:2.8" + name: "infra/python/wheels/idna-py3" + version: "version:3.4" > wheel: < - name: "infra/python/wheels/urllib3-py2_py3" - version: "version:1.26.6" + name: "infra/python/wheels/urllib3-py3" + version: "version:2.1.0" > wheel: < - name: "infra/python/wheels/certifi-py2_py3" - version: "version:2020.11.8" + name: "infra/python/wheels/certifi-py3" + version: "version:2023.11.17" > wheel: < name: "infra/python/wheels/charset_normalizer-py3" - version: "version:2.0.4" + version: "version:3.3.2" > wheel: < name: "infra/python/wheels/brotli/${vpython_platform}" From c3624d02d015a5a546739715a6f2dd5829e4f188 Mon Sep 17 00:00:00 2001 From: Jakob Ivarsson Date: Wed, 24 Jan 2024 09:48:01 +0100 Subject: [PATCH 012/170] Add field trial that enables Opus PLC. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Low-Coverage-Reason: EXPERIMENTAL_CODE Code is behind field trial that will only be used for testing. Bug: webrtc:13322 Change-Id: Ie306be808381b3a20b4e0d58349927bf3524018a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335840 Reviewed-by: Tomas Lundqvist Commit-Queue: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41608} --- experiments/field_trials.py | 3 +++ .../codecs/opus/audio_decoder_opus.cc | 23 ++++++++++++++++++- .../codecs/opus/audio_decoder_opus.h | 3 +++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/experiments/field_trials.py b/experiments/field_trials.py index 4aa9bcbe4b..70e131e3da 100755 --- a/experiments/field_trials.py +++ b/experiments/field_trials.py @@ -50,6 +50,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-Audio-OpusSetSignalVoiceWithDtx', 'webrtc:4559', date(2024, 4, 1)), + FieldTrial('WebRTC-Audio-OpusGeneratePlc', + 'webrtc:13322', + date(2024, 4, 1)), FieldTrial('WebRTC-AV1-OverridePriorityBitrate', 'webrtc:15763', date(2024, 4, 1)), diff --git a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc index cff9685548..0f53409f48 100644 --- a/modules/audio_coding/codecs/opus/audio_decoder_opus.cc +++ b/modules/audio_coding/codecs/opus/audio_decoder_opus.cc @@ -17,12 +17,15 @@ #include "api/array_view.h" #include "modules/audio_coding/codecs/opus/audio_coder_opus_common.h" #include "rtc_base/checks.h" +#include "system_wrappers/include/field_trial.h" namespace webrtc { AudioDecoderOpusImpl::AudioDecoderOpusImpl(size_t num_channels, int sample_rate_hz) - : channels_{num_channels}, sample_rate_hz_{sample_rate_hz} { + : channels_(num_channels), + sample_rate_hz_(sample_rate_hz), + generate_plc_(field_trial::IsEnabled("WebRTC-Audio-OpusGeneratePlc")) { RTC_DCHECK(num_channels == 1 || num_channels == 2); RTC_DCHECK(sample_rate_hz == 16000 || sample_rate_hz == 48000); const int error = @@ -125,4 +128,22 @@ size_t AudioDecoderOpusImpl::Channels() const { return channels_; } +void AudioDecoderOpusImpl::GeneratePlc( + size_t requested_samples_per_channel, + rtc::BufferT* concealment_audio) { + if (!generate_plc_) { + return; + } + int plc_size = WebRtcOpus_PlcDuration(dec_state_) * channels_; + concealment_audio->AppendData(plc_size, [&](rtc::ArrayView decoded) { + int16_t temp_type = 1; + int ret = + WebRtcOpus_Decode(dec_state_, nullptr, 0, decoded.data(), &temp_type); + if (ret < 0) { + return 0; + } + return ret; + }); +} + } // namespace webrtc diff --git a/modules/audio_coding/codecs/opus/audio_decoder_opus.h b/modules/audio_coding/codecs/opus/audio_decoder_opus.h index e8fd0440bc..2dd62fd4ee 100644 --- a/modules/audio_coding/codecs/opus/audio_decoder_opus.h +++ b/modules/audio_coding/codecs/opus/audio_decoder_opus.h @@ -40,6 +40,8 @@ class AudioDecoderOpusImpl final : public AudioDecoder { bool PacketHasFec(const uint8_t* encoded, size_t encoded_len) const override; int SampleRateHz() const override; size_t Channels() const override; + void GeneratePlc(size_t requested_samples_per_channel, + rtc::BufferT* concealment_audio) override; protected: int DecodeInternal(const uint8_t* encoded, @@ -57,6 +59,7 @@ class AudioDecoderOpusImpl final : public AudioDecoder { OpusDecInst* dec_state_; const size_t channels_; const int sample_rate_hz_; + const bool generate_plc_; }; } // namespace webrtc From cc70a6d1748cd28a9d62fb234ab3f0b48cbebb1e Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Thu, 25 Jan 2024 08:34:26 +0000 Subject: [PATCH 013/170] Guard GenerateUniqueId aginst concurrent access. Similar to https://webrtc-review.googlesource.com/c/src/+/147020. Bug: b/264473017 Change-Id: I40a6239f28c01b90f521f3cadcb4aea4f6d6461c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336180 Reviewed-by: Harald Alvestrand Commit-Queue: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41609} --- pc/rtp_receiver.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pc/rtp_receiver.cc b/pc/rtp_receiver.cc index a2b3353c0e..9431aab10a 100644 --- a/pc/rtp_receiver.cc +++ b/pc/rtp_receiver.cc @@ -12,6 +12,7 @@ #include +#include #include #include @@ -22,8 +23,10 @@ namespace webrtc { // This function is only expected to be called on the signalling thread. +// On the other hand, some test or even production setups may use +// several signaling threads. int RtpReceiverInternal::GenerateUniqueId() { - static int g_unique_id = 0; + static std::atomic g_unique_id{0}; return ++g_unique_id; } From e3a4bdb46f6747a764d5fd55e5093d8832591877 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Thu, 25 Jan 2024 08:17:44 -0800 Subject: [PATCH 014/170] Roll chromium_revision 712952759e..844caa73fd (1251936:1252127) Change log: https://chromium.googlesource.com/chromium/src/+log/712952759e..844caa73fd Full diff: https://chromium.googlesource.com/chromium/src/+/712952759e..844caa73fd Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/51853d9cce..1e7f08e968 * src/build: https://chromium.googlesource.com/chromium/src/build/+log/f0e6a46076..0b7a0198da * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/8ab02af836..2e7ed5b523 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/6bed18b881..d03a2cf751 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/821b8dc4d9..b2c536b297 * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/d1eeccf9e4..d7ee2f7345 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/bd299c3878..d9c3231123 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/d090bfe02e..80bf17f2a7 DEPS diff: https://chromium.googlesource.com/chromium/src/+/712952759e..844caa73fd/DEPS Clang version changed llvmorg-18-init-16072-gc4146121e940:llvmorg-18-init-17730-gf670112a Details: https://chromium.googlesource.com/chromium/src/+/712952759e..844caa73fd/tools/clang/scripts/update.py BUG=None Change-Id: Ie56907c4fb9b83ffd12d8d2dd133ceb04cf0485e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336261 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41610} --- DEPS | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DEPS b/DEPS index d3740bb021..6cafb926b4 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '712952759e824f309c244a18ff426fe5d1e706ca', + 'chromium_revision': '844caa73fdd4e4f48fd8b57802ae0617dfcb3819', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,9 +50,9 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@51853d9cce5aee38c5cbc9e7819aa6b93ec95a12', + 'https://chromium.googlesource.com/chromium/src/base@1e7f08e968d8354d58e7ff4a818062d99f36d889', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@f0e6a4607685263efe102982265fe581d805dc07', + 'https://chromium.googlesource.com/chromium/src/build@0b7a0198da6202822e3c9d934327e390760459f1', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@d8688b9036d46d14ef1f6fc26bcbb1da2b17f897', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@8ab02af836755c8bd6e3e546f4d599e4c6b239c0', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@2e7ed5b52398f0c7ca72e0ac6f5801bb06cabf96', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@6bed18b881f3c27c8c246cfbc1e147c0912dfc91', + 'https://chromium.googlesource.com/chromium/src/testing@d03a2cf751fcc23f1ec306a9eb6946b06ecb1f2c', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@821b8dc4d9f4db913694650f9da067e6d3619590', + 'https://chromium.googlesource.com/chromium/src/third_party@b2c536b297b9fd34ac67f226d247bf0a6773d912', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@62ecd463583d09eb7d15b1d410055f30b2c7bcb4', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@d1eeccf9e4a273c3639d6554c889f8ee3ca9bc0d', + 'https://chromium.googlesource.com/catapult.git@d7ee2f7345cc7b989b88c5323f9b3e6e380fb0d5', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@bd299c3878ebd23de57b0f1cef2811a92c6a3407', + 'https://android.googlesource.com/platform/external/perfetto.git@d9c3231123fd6b1d0c1afd49d27c628a3b01c4f6', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@eeb1be7f23eee652372df4fa3b14cf542ee2c040', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@d090bfe02ee2ac2363114ae3172fbc44ae9e1a80', + 'https://chromium.googlesource.com/chromium/src/tools@80bf17f2a7715bfa381b2ca2e4e31cfb3efb44e8', 'src/third_party/accessibility_test_framework': { 'packages': [ From a310d78662c22c1a3cfea6d765d1f51097ffcd49 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Thu, 25 Jan 2024 12:27:18 +0000 Subject: [PATCH 015/170] Refactor a lot of the p2p:rtc_p2p target This CL splits many of the source files in p2p:rtc_p2p into individual compile targets. One target - connection_and_port - was left with multiple source files because it was too tangled to detangle at once. Bug: webrtc:15796 Change-Id: I607417e5945306ef64335f40a0ae50f0d15dee6f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335881 Reviewed-by: Mirko Bonadei Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41611} --- api/BUILD.gn | 5 + api/test/pclf/BUILD.gn | 1 + examples/BUILD.gn | 2 + media/BUILD.gn | 2 + p2p/BUILD.gn | 557 ++++++++++++++++++++++++++++--- p2p/base/basic_ice_controller.h | 1 - p2p/base/p2p_constants.h | 2 + p2p/base/p2p_transport_channel.h | 2 - p2p/base/port.cc | 2 - pc/BUILD.gn | 71 ++++ test/pc/e2e/BUILD.gn | 1 + test/peer_scenario/BUILD.gn | 1 + 12 files changed, 593 insertions(+), 54 deletions(-) diff --git a/api/BUILD.gn b/api/BUILD.gn index 0652552eb3..cb23ea32cf 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -334,6 +334,7 @@ rtc_library("libjingle_peerconnection_api") { ":sequence_checker", ":turn_customizer", "../call:rtp_interfaces", + "../p2p:connection_and_port", "../p2p:rtc_p2p", "../pc:media_factory", "../rtc_base:copy_on_write_buffer", @@ -935,6 +936,10 @@ rtc_library("ice_transport_factory") { ":make_ref_counted", ":packet_socket_factory", ":scoped_refptr", + "../p2p:connection_and_port", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", "../rtc_base:threading", "../rtc_base/system:rtc_export", diff --git a/api/test/pclf/BUILD.gn b/api/test/pclf/BUILD.gn index 4f62984e83..6d1d2bef5d 100644 --- a/api/test/pclf/BUILD.gn +++ b/api/test/pclf/BUILD.gn @@ -74,6 +74,7 @@ rtc_library("media_quality_test_params") { "../../../api/transport:network_control", "../../../api/video_codecs:video_codecs_api", "../../../modules/audio_processing:api", + "../../../p2p:connection_and_port", "../../../p2p:rtc_p2p", "../../../rtc_base:network", "../../../rtc_base:rtc_certificate_generator", diff --git a/examples/BUILD.gn b/examples/BUILD.gn index 4ace29bb7e..991f9d8686 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -702,6 +702,7 @@ if (is_linux || is_chromeos || is_win) { "../api/video_codecs:video_codecs_api", "../media:media_channel", "../media:rtc_media_base", + "../p2p:connection_and_port", "../p2p:rtc_p2p", "../pc:video_track_source", "../rtc_base:async_dns_resolver", @@ -809,6 +810,7 @@ if (is_linux || is_chromeos || is_win) { deps = [ ":read_auth_file", "../p2p:p2p_server_utils", + "../p2p:port_interface", "../p2p:rtc_p2p", "../pc:rtc_pc", "../rtc_base:async_udp_socket", diff --git a/media/BUILD.gn b/media/BUILD.gn index 2a9cbcbff4..93d104cdd0 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -582,6 +582,7 @@ rtc_source_set("rtc_data_sctp_transport_internal") { "../api:rtc_error", "../api/transport:datagram_transport_interface", "../media:rtc_media_base", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:copy_on_write_buffer", "../rtc_base:threading", @@ -606,6 +607,7 @@ if (rtc_build_dcsctp) { "../net/dcsctp/public:types", "../net/dcsctp/public:utils", "../net/dcsctp/timer:task_queue_timeout", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn index a663e85e22..140bf215c6 100644 --- a/p2p/BUILD.gn +++ b/p2p/BUILD.gn @@ -18,21 +18,16 @@ group("p2p") { rtc_library("rtc_p2p") { visibility = [ "*" ] sources = [ - "base/active_ice_controller_factory_interface.h", - "base/active_ice_controller_interface.h", - "base/async_stun_tcp_socket.cc", - "base/async_stun_tcp_socket.h", - "base/basic_async_resolver_factory.cc", - "base/basic_async_resolver_factory.h", - "base/basic_ice_controller.cc", - "base/basic_ice_controller.h", + # TODO(bugs.webrtc.org/15769): Finish cleanup and remove. + + "base/active_ice_controller_factory_interface.h", # To be removed (Chrome) + "base/active_ice_controller_interface.h", # To be removed (Internal) + "base/basic_ice_controller.h", # To be removed (Chrome) "base/basic_packet_socket_factory.cc", "base/basic_packet_socket_factory.h", - "base/candidate_pair_interface.h", - "base/connection.cc", - "base/connection.h", - "base/connection_info.cc", - "base/connection_info.h", + "base/candidate_pair_interface.h", # To be removed + "base/connection.h", # To be removed + "base/connection_info.h", # To be removed "base/default_ice_transport_factory.cc", "base/default_ice_transport_factory.h", "base/dtls_transport.cc", @@ -40,51 +35,32 @@ rtc_library("rtc_p2p") { "base/dtls_transport_factory.h", "base/dtls_transport_internal.cc", "base/dtls_transport_internal.h", - "base/ice_agent_interface.h", - "base/ice_controller_factory_interface.h", - "base/ice_controller_interface.cc", - "base/ice_controller_interface.h", - "base/ice_credentials_iterator.cc", - "base/ice_credentials_iterator.h", - "base/ice_switch_reason.cc", - "base/ice_switch_reason.h", - "base/ice_transport_internal.cc", - "base/ice_transport_internal.h", - "base/p2p_constants.cc", - "base/p2p_constants.h", - "base/p2p_transport_channel.cc", - "base/p2p_transport_channel.h", - "base/p2p_transport_channel_ice_field_trials.h", - "base/packet_transport_internal.cc", - "base/packet_transport_internal.h", - "base/port.cc", - "base/port.h", - "base/port_allocator.cc", - "base/port_allocator.h", - "base/port_interface.cc", - "base/port_interface.h", + "base/ice_agent_interface.h", # To be removed (Chrome) + "base/ice_controller_interface.h", # To be removed (Chrome) + "base/ice_credentials_iterator.h", # To be removed + "base/ice_switch_reason.h", # To be removed (Chrome) + "base/ice_transport_internal.h", # To be removed + "base/p2p_constants.h", # To be removed + "base/p2p_transport_channel.h", # To be removed (Chrome) + "base/p2p_transport_channel_ice_field_trials.h", # To be removed + "base/packet_transport_internal.h", # To be removed + "base/port.h", # To be removed (Chrome) + "base/port_allocator.h", # To be removed (Chrome) + "base/port_interface.h", # To be removed "base/pseudo_tcp.cc", "base/pseudo_tcp.h", - "base/regathering_controller.cc", - "base/regathering_controller.h", - "base/stun_dictionary.cc", - "base/stun_dictionary.h", + "base/stun_dictionary.h", # To be removed "base/stun_port.cc", "base/stun_port.h", - "base/stun_request.cc", - "base/stun_request.h", "base/tcp_port.cc", "base/tcp_port.h", - "base/transport_description.cc", - "base/transport_description.h", + "base/transport_description.h", # To be removed "base/transport_description_factory.cc", "base/transport_description_factory.h", "base/transport_info.h", "base/turn_port.cc", "base/turn_port.h", "base/udp_port.h", - "base/wrapping_active_ice_controller.cc", - "base/wrapping_active_ice_controller.h", "client/basic_port_allocator.cc", "client/basic_port_allocator.h", "client/relay_port_factory_interface.h", @@ -93,6 +69,29 @@ rtc_library("rtc_p2p") { ] deps = [ + ":active_ice_controller_factory_interface", + ":async_stun_tcp_socket", + ":basic_async_resolver_factory", + ":basic_ice_controller", + ":candidate_pair_interface", + ":connection_and_port", + ":connection_info", + ":ice_agent_interface", + ":ice_controller_factory_interface", + ":ice_controller_interface", + ":ice_credentials_iterator", + ":ice_switch_reason", + ":ice_transport_internal", + ":p2p_constants", + ":p2p_transport_channel", + ":p2p_transport_channel_ice_field_trials", + ":packet_transport_internal", + ":port_interface", + ":regathering_controller", + ":stun_dictionary", + ":stun_request", + ":transport_description", + ":wrapping_active_ice_controller", "../api:array_view", "../api:async_dns_resolver", "../api:candidate", @@ -176,13 +175,446 @@ rtc_library("rtc_p2p") { ] } +rtc_source_set("active_ice_controller_factory_interface") { + sources = [ "base/active_ice_controller_factory_interface.h" ] + deps = [ + ":active_ice_controller_interface", + ":ice_agent_interface", + ":ice_controller_factory_interface", + ] +} + +rtc_source_set("active_ice_controller_interface") { + sources = [ "base/active_ice_controller_interface.h" ] + deps = [ + ":connection_and_port", + ":ice_switch_reason", + ":ice_transport_internal", + ":transport_description", + "../api:array_view", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +} + +rtc_library("basic_async_resolver_factory") { + sources = [ + "base/basic_async_resolver_factory.cc", + "base/basic_async_resolver_factory.h", + ] + deps = [ + "../api:async_dns_resolver", + "../rtc_base:async_dns_resolver", + "../rtc_base:logging", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] +} + +rtc_library("async_stun_tcp_socket") { + sources = [ + "base/async_stun_tcp_socket.cc", + "base/async_stun_tcp_socket.h", + ] + deps = [ + "../api:array_view", + "../api/transport:stun_types", + "../api/units:timestamp", + "../rtc_base:async_packet_socket", + "../rtc_base:async_tcp_socket", + "../rtc_base:byte_order", + "../rtc_base:checks", + "../rtc_base:socket", + "../rtc_base:socket_address", + "../rtc_base:timeutils", + "../rtc_base/network:received_packet", + "../rtc_base/network:sent_packet", + ] +} + +rtc_library("basic_ice_controller") { + sources = [ + "base/basic_ice_controller.cc", + "base/basic_ice_controller.h", + ] + deps = [ + ":ice_controller_factory_interface", + ":ice_controller_interface", + ] +} + +rtc_source_set("candidate_pair_interface") { + sources = [ "base/candidate_pair_interface.h" ] +} + +# This set of files is too intertwined to break into separate +# targets at this point. +# TODO(bugs.webrtc.org/15796): Finish breakup +rtc_library("connection_and_port") { + sources = [ + "base/connection.cc", + "base/connection.h", + "base/port.cc", + "base/port.h", + "base/port_allocator.cc", + "base/port_allocator.h", + ] + deps = [ + ":candidate_pair_interface", + ":connection_info", + ":ice_credentials_iterator", + ":p2p_constants", + ":p2p_transport_channel_ice_field_trials", + ":port_interface", + ":stun_request", + ":transport_description", + "../api:array_view", + "../api:candidate", + "../api:field_trials_view", + "../api:packet_socket_factory", + "../api:rtc_error", + "../api:sequence_checker", + "../api/task_queue", + "../api/transport:enums", + "../api/transport:field_trial_based_config", + "../api/transport:stun_types", + "../api/units:timestamp", + "../logging:ice_log", + "../rtc_base:async_packet_socket", + "../rtc_base:callback_list", + "../rtc_base:checks", + "../rtc_base:crc32", + "../rtc_base:event_tracer", + "../rtc_base:logging", + "../rtc_base:mdns_responder_interface", + "../rtc_base:net_helper", + "../rtc_base:network", + "../rtc_base:proxy_info", + "../rtc_base:rate_tracker", + "../rtc_base:rtc_numerics", + "../rtc_base:safe_minmax", + "../rtc_base:socket_address", + "../rtc_base:ssl", + "../rtc_base:stringutils", + "../rtc_base:threading", + "../rtc_base:weak_ptr", + "../rtc_base/memory:always_valid_pointer", + "../rtc_base/network:received_packet", + "../rtc_base/system:rtc_export", + "../rtc_base/third_party/base64", + "../rtc_base/third_party/sigslot", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_library("connection_info") { + sources = [ + "base/connection_info.cc", + "base/connection_info.h", + ] + deps = [ + "../api:candidate", + "../api/units:timestamp", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +} + +rtc_source_set("ice_agent_interface") { + sources = [ "base/ice_agent_interface.h" ] + deps = [ + ":connection_and_port", + ":ice_switch_reason", + "../api:array_view", + ] +} + +rtc_library("ice_controller_interface") { + sources = [ + "base/ice_controller_interface.cc", + "base/ice_controller_interface.h", + ] + deps = [ + ":connection_and_port", + ":ice_switch_reason", + ":ice_transport_internal", + "../rtc_base:checks", + "../rtc_base/system:rtc_export", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +} + +rtc_source_set("ice_controller_factory_interface") { + sources = [ "base/ice_controller_factory_interface.h" ] + deps = [ + ":ice_controller_interface", + ":ice_transport_internal", + ] +} + +rtc_library("ice_credentials_iterator") { + sources = [ + "base/ice_credentials_iterator.cc", + "base/ice_credentials_iterator.h", + ] + deps = [ + ":p2p_constants", + ":transport_description", + "../rtc_base:ssl", + ] +} + +rtc_library("ice_switch_reason") { + sources = [ + "base/ice_switch_reason.cc", + "base/ice_switch_reason.h", + ] + deps = [ "../rtc_base/system:rtc_export" ] +} + +rtc_library("ice_transport_internal") { + sources = [ + "base/ice_transport_internal.cc", + "base/ice_transport_internal.h", + ] + deps = [ + ":connection_and_port", + ":p2p_constants", + ":packet_transport_internal", + ":stun_dictionary", + ":transport_description", + "../api:candidate", + "../api:rtc_error", + "../api/transport:enums", + "../rtc_base:network_constants", + "../rtc_base:timeutils", + "../rtc_base/system:rtc_export", + "../rtc_base/third_party/sigslot", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_library("p2p_constants") { + sources = [ + "base/p2p_constants.cc", + "base/p2p_constants.h", + ] + deps = [ "../rtc_base/system:rtc_export" ] +} + +rtc_library("p2p_transport_channel") { + sources = [ + "base/p2p_transport_channel.cc", + "base/p2p_transport_channel.h", + ] + deps = [ + ":active_ice_controller_factory_interface", + ":basic_ice_controller", + ":candidate_pair_interface", + ":connection_and_port", + ":connection_info", + ":ice_agent_interface", + ":ice_controller_factory_interface", + ":ice_controller_interface", + ":ice_switch_reason", + ":ice_transport_internal", + ":p2p_constants", + ":p2p_transport_channel_ice_field_trials", + ":port_interface", + ":regathering_controller", + ":stun_dictionary", + ":transport_description", + ":wrapping_active_ice_controller", + "../api:array_view", + "../api:async_dns_resolver", + "../api:candidate", + "../api:field_trials_view", + "../api:ice_transport_interface", + "../api:rtc_error", + "../api:sequence_checker", + "../api/task_queue:pending_task_safety_flag", + "../api/transport:enums", + "../api/transport:stun_types", + "../api/units:time_delta", + "../logging:ice_log", + "../rtc_base:async_packet_socket", + "../rtc_base:checks", + "../rtc_base:crc32", + "../rtc_base:dscp", + "../rtc_base:event_tracer", + "../rtc_base:ip_address", + "../rtc_base:logging", + "../rtc_base:macromagic", + "../rtc_base:net_helper", + "../rtc_base:network", + "../rtc_base:network_constants", + "../rtc_base:network_route", + "../rtc_base:socket", + "../rtc_base:socket_address", + "../rtc_base:stringutils", + "../rtc_base:threading", + "../rtc_base:timeutils", + "../rtc_base/experiments:field_trial_parser", + "../rtc_base/network:sent_packet", + "../rtc_base/system:rtc_export", + "../system_wrappers:metrics", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_source_set("p2p_transport_channel_ice_field_trials") { + sources = [ "base/p2p_transport_channel_ice_field_trials.h" ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +} + +rtc_library("packet_transport_internal") { + sources = [ + "base/packet_transport_internal.cc", + "base/packet_transport_internal.h", + ] + deps = [ + ":connection_and_port", + "../rtc_base:async_packet_socket", + "../rtc_base:network_route", + "../rtc_base:socket", + "../rtc_base/system:rtc_export", + "../rtc_base/third_party/sigslot", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +} + +rtc_library("port_interface") { + sources = [ + "base/port_interface.cc", + "base/port_interface.h", + ] + deps = [ + ":transport_description", + "../api:candidate", + "../rtc_base:async_packet_socket", + "../rtc_base:callback_list", + "../rtc_base:socket_address", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_library("regathering_controller") { + sources = [ + "base/regathering_controller.cc", + "base/regathering_controller.h", + ] + deps = [ + ":connection_and_port", + ":ice_transport_internal", + "../api/task_queue:pending_task_safety_flag", + "../api/units:time_delta", + "../rtc_base:threading", + ] +} + +rtc_library("stun_dictionary") { + sources = [ + "base/stun_dictionary.cc", + "base/stun_dictionary.h", + ] + deps = [ + "../api:rtc_error", + "../api/transport:stun_types", + "../rtc_base:logging", + ] +} + +rtc_library("stun_request") { + sources = [ + "base/stun_request.cc", + "base/stun_request.h", + ] + deps = [ + "../api/task_queue", + "../api/task_queue:pending_task_safety_flag", + "../api/transport:stun_types", + "../api/units:time_delta", + "../rtc_base:checks", + "../rtc_base:logging", + "../rtc_base:ssl", + "../rtc_base:stringutils", + "../rtc_base:timeutils", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] +} + +rtc_library("transport_description") { + sources = [ + "base/transport_description.cc", + "base/transport_description.h", + ] + deps = [ + ":p2p_constants", + "../api:rtc_error", + "../rtc_base:logging", + "../rtc_base:macromagic", + "../rtc_base:ssl", + "../rtc_base:stringutils", + "../rtc_base/system:rtc_export", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_library("wrapping_active_ice_controller") { + sources = [ + "base/wrapping_active_ice_controller.cc", + "base/wrapping_active_ice_controller.h", + ] + deps = [ + ":active_ice_controller_interface", + ":basic_ice_controller", + ":connection_and_port", + ":ice_agent_interface", + ":ice_controller_factory_interface", + ":ice_controller_interface", + ":ice_switch_reason", + ":ice_transport_internal", + ":transport_description", + "../api:sequence_checker", + "../api/task_queue:pending_task_safety_flag", + "../api/units:time_delta", + "../rtc_base:logging", + "../rtc_base:macromagic", + "../rtc_base:threading", + "../rtc_base:timeutils", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +} + if (rtc_include_tests) { rtc_library("fake_ice_transport") { testonly = true visibility = [ "*" ] sources = [ "base/fake_ice_transport.h" ] deps = [ - ":rtc_p2p", + ":ice_transport_internal", "../api:ice_transport_interface", "../api:libjingle_peerconnection_api", "../api/task_queue:pending_task_safety_flag", @@ -202,6 +634,7 @@ if (rtc_include_tests) { visibility = [ "*" ] sources = [ "base/fake_port_allocator.h" ] deps = [ + ":connection_and_port", ":rtc_p2p", "../rtc_base:net_helpers", "../rtc_base:net_test_helpers", @@ -228,10 +661,20 @@ if (rtc_include_tests) { "base/test_turn_server.h", ] deps = [ + ":active_ice_controller_factory_interface", + ":active_ice_controller_interface", + ":connection_and_port", ":fake_ice_transport", ":fake_port_allocator", + ":ice_agent_interface", + ":ice_controller_factory_interface", + ":ice_controller_interface", + ":ice_switch_reason", + ":ice_transport_internal", ":p2p_server_utils", + ":packet_transport_internal", ":rtc_p2p", + ":transport_description", "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", "../api:mock_async_dns_resolver", @@ -284,11 +727,27 @@ if (rtc_include_tests) { "client/basic_port_allocator_unittest.cc", ] deps = [ + ":active_ice_controller_factory_interface", + ":active_ice_controller_interface", + ":async_stun_tcp_socket", + ":basic_ice_controller", + ":connection_and_port", ":fake_ice_transport", ":fake_port_allocator", + ":ice_credentials_iterator", + ":ice_transport_internal", + ":p2p_constants", ":p2p_server_utils", ":p2p_test_utils", + ":p2p_transport_channel", + ":packet_transport_internal", + ":port_interface", + ":regathering_controller", ":rtc_p2p", + ":stun_dictionary", + ":stun_request", + ":transport_description", + ":wrapping_active_ice_controller", "../api:array_view", "../api:candidate", "../api:dtls_transport_interface", @@ -355,7 +814,8 @@ rtc_library("p2p_server_utils") { "base/turn_server.h", ] deps = [ - ":rtc_p2p", + ":async_stun_tcp_socket", + ":port_interface", "../api:array_view", "../api:packet_socket_factory", "../api:sequence_checker", @@ -391,7 +851,6 @@ rtc_library("libstunprober") { ] deps = [ - ":rtc_p2p", "../api:array_view", "../api:async_dns_resolver", "../api:packet_socket_factory", diff --git a/p2p/base/basic_ice_controller.h b/p2p/base/basic_ice_controller.h index 724609d2d7..f9f4d45c7a 100644 --- a/p2p/base/basic_ice_controller.h +++ b/p2p/base/basic_ice_controller.h @@ -19,7 +19,6 @@ #include "p2p/base/ice_controller_factory_interface.h" #include "p2p/base/ice_controller_interface.h" -#include "p2p/base/p2p_transport_channel.h" namespace cricket { diff --git a/p2p/base/p2p_constants.h b/p2p/base/p2p_constants.h index d51ee17a07..3af00bbc2e 100644 --- a/p2p/base/p2p_constants.h +++ b/p2p/base/p2p_constants.h @@ -95,6 +95,8 @@ extern const int CONNECTION_WRITE_TIMEOUT; // Default value of IceConfig.stun_keepalive_interval; extern const int STUN_KEEPALIVE_INTERVAL; +static const int MIN_PINGS_AT_WEAK_PING_INTERVAL = 3; + // The following constants are used at the candidate pair level to determine the // state of a candidate pair. // diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h index 47f37c8c67..6413d2dc64 100644 --- a/p2p/base/p2p_transport_channel.h +++ b/p2p/base/p2p_transport_channel.h @@ -79,8 +79,6 @@ class RtcEventLog; namespace cricket { -static const int MIN_PINGS_AT_WEAK_PING_INTERVAL = 3; - bool IceCredentialsChanged(absl::string_view old_ufrag, absl::string_view old_pwd, absl::string_view new_ufrag, diff --git a/p2p/base/port.cc b/p2p/base/port.cc index a3378fe23a..1289d17d76 100644 --- a/p2p/base/port.cc +++ b/p2p/base/port.cc @@ -22,8 +22,6 @@ #include "absl/memory/memory.h" #include "absl/strings/match.h" #include "absl/strings/string_view.h" -#include "p2p/base/connection.h" -#include "p2p/base/port_allocator.h" #include "rtc_base/checks.h" #include "rtc_base/crc32.h" #include "rtc_base/helpers.h" diff --git a/pc/BUILD.gn b/pc/BUILD.gn index e351748485..2edbf9d63a 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -134,6 +134,7 @@ rtc_source_set("dtls_srtp_transport") { "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", "../api:rtc_error", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:buffer", "../rtc_base:checks", @@ -225,7 +226,11 @@ rtc_source_set("jsep_transport") { "../api:sequence_checker", "../api/transport:datagram_transport_interface", "../media:rtc_data_sctp_transport_internal", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", "../rtc_base:event_tracer", @@ -249,6 +254,7 @@ rtc_source_set("jsep_transport_collection") { ":session_description", "../api:libjingle_peerconnection_api", "../api:sequence_checker", + "../p2p:p2p_constants", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:logging", @@ -295,7 +301,13 @@ rtc_source_set("jsep_transport_controller") { "../api/transport:enums", "../api/transport:sctp_transport_factory_interface", "../media:rtc_data_sctp_transport_internal", + "../p2p:connection_and_port", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:callback_list", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", @@ -347,7 +359,10 @@ rtc_source_set("media_session") { "../media:rtc_media_base", "../media:rtc_sdp_video_format_utils", "../media:stream_params", + "../p2p:ice_credentials_iterator", + "../p2p:p2p_constants", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:ssl", @@ -459,6 +474,7 @@ rtc_source_set("rtp_transport") { "../media:rtc_media_base", "../media:rtp_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:async_packet_socket", "../rtc_base:checks", @@ -484,6 +500,7 @@ rtc_source_set("rtp_transport_internal") { deps = [ ":session_description", "../call:rtp_receiver", + "../p2p:ice_transport_internal", "../p2p:rtc_p2p", "../rtc_base:callback_list", "../rtc_base:network_route", @@ -608,6 +625,7 @@ rtc_source_set("srtp_transport") { "../media:rtc_media_base", "../media:rtp_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:async_packet_socket", "../rtc_base:buffer", @@ -636,6 +654,8 @@ rtc_source_set("transport_stats") { deps = [ "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", + "../p2p:connection_and_port", + "../p2p:ice_transport_internal", "../p2p:rtc_p2p", "../rtc_base:ssl", ] @@ -693,6 +713,7 @@ rtc_source_set("session_description") { "../media:rtc_media_base", "../media:stream_params", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:checks", "../rtc_base:socket_address", "../rtc_base:stringutils", @@ -911,6 +932,10 @@ rtc_source_set("rtc_stats_collector") { "../modules/audio_device", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:connection_and_port", + "../p2p:connection_info", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:event_tracer", @@ -1003,7 +1028,12 @@ rtc_source_set("sdp_offer_answer") { "../media:rid_description", "../media:rtc_media_base", "../media:stream_params", + "../p2p:connection_and_port", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:checks", "../rtc_base:event_tracer", "../rtc_base:logging", @@ -1108,7 +1138,14 @@ rtc_source_set("peer_connection") { "../media:rtc_media_config", "../media:stream_params", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:basic_async_resolver_factory", + "../p2p:connection_and_port", + "../p2p:connection_info", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", "../rtc_base:event_tracer", @@ -1199,6 +1236,10 @@ rtc_source_set("legacy_stats_collector") { "../media:media_channel", "../media:rtc_media_base", "../modules/audio_processing:audio_processing_statistics", + "../p2p:connection_and_port", + "../p2p:connection_info", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:event_tracer", @@ -1272,7 +1313,13 @@ rtc_source_set("webrtc_sdp") { "../media:rtc_media_base", "../media:rtp_utils", "../media:stream_params", + "../p2p:candidate_pair_interface", + "../p2p:connection_and_port", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", + "../p2p:port_interface", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:checks", "../rtc_base:ip_address", "../rtc_base:logging", @@ -1307,6 +1354,7 @@ rtc_source_set("webrtc_session_description_factory") { "../api:sequence_checker", "../api/task_queue", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:rtc_certificate_generator", @@ -1333,6 +1381,8 @@ rtc_library("ice_server_parsing") { deps = [ "../api:libjingle_peerconnection_api", "../api:rtc_error", + "../p2p:connection_and_port", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:ip_address", @@ -1395,6 +1445,7 @@ rtc_source_set("peer_connection_factory") { "../call:rtp_interfaces", "../call:rtp_sender", "../media:rtc_media_base", + "../p2p:connection_and_port", "../p2p:rtc_p2p", "../pc:audio_track", "../pc:connection_context", @@ -2025,10 +2076,15 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_base", "../media:rtc_media_tests_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:candidate_pair_interface", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:p2p_test_utils", + "../p2p:packet_transport_internal", "../p2p:rtc_p2p", + "../p2p:transport_description", "../rtc_base:async_packet_socket", "../rtc_base:buffer", "../rtc_base:byte_order", @@ -2110,7 +2166,9 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_tests_utils", "../modules/audio_device:audio_device_api", "../modules/audio_processing:api", + "../p2p:connection_and_port", "../p2p:p2p_test_utils", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:gunit_helpers", @@ -2161,8 +2219,10 @@ if (rtc_include_tests && !build_with_chromium) { "../api:libjingle_peerconnection_api", "../api:scoped_refptr", "../api/units:time_delta", + "../p2p:connection_and_port", "../p2p:p2p_server_utils", "../p2p:p2p_test_utils", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:gunit_helpers", "../rtc_base:logging", @@ -2342,8 +2402,14 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_device:audio_device_api", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:connection_and_port", + "../p2p:connection_info", "../p2p:fake_port_allocator", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:p2p_server_utils", + "../p2p:port_interface", + "../p2p:transport_description", "../rtc_base:byte_buffer", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", @@ -2552,10 +2618,14 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing:audio_processing_statistics", "../modules/audio_processing:audioproc_test_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:connection_and_port", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", + "../p2p:ice_transport_internal", + "../p2p:p2p_constants", "../p2p:p2p_server_utils", "../p2p:p2p_test_utils", + "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:gunit_helpers", @@ -2702,6 +2772,7 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing", "../modules/audio_processing:api", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:connection_and_port", "../p2p:fake_port_allocator", "../p2p:p2p_test_utils", "../p2p:rtc_p2p", diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn index 0eb7aa2c68..e0d3dbe0bc 100644 --- a/test/pc/e2e/BUILD.gn +++ b/test/pc/e2e/BUILD.gn @@ -576,6 +576,7 @@ if (!build_with_chromium) { "../../../media:media_constants", "../../../media:rid_description", "../../../media:rtc_media_base", + "../../../p2p:p2p_constants", "../../../p2p:rtc_p2p", "../../../pc:sdp_utils", "../../../pc:session_description", diff --git a/test/peer_scenario/BUILD.gn b/test/peer_scenario/BUILD.gn index 18f81a56e6..4736f675ef 100644 --- a/test/peer_scenario/BUILD.gn +++ b/test/peer_scenario/BUILD.gn @@ -54,6 +54,7 @@ if (rtc_include_tests) { "../../modules/audio_device:test_audio_device_module", "../../modules/rtp_rtcp:rtp_rtcp_format", "../../p2p:rtc_p2p", + "../../p2p:transport_description", "../../pc:channel", "../../pc:jsep_transport_controller", "../../pc:pc_test_utils", From ac58a334f7950983f324efa2b4025d2bbff4a67c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= Date: Mon, 22 Jan 2024 13:51:36 +0100 Subject: [PATCH 016/170] [Stats] Migrate from the RTCStatsMember type alias to absl::optional. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this CL, the only usage of RTCStatsMember within WebRTC is the actual type alias declaration. It's not referenced anywhere anymore. This allows us to deleting the type alias, but let's do that in a standalone CL in case it gets reverted. Bug: webrtc:15164 Change-Id: I766d07abb62b5ddd524859b8ed749394fc439e52 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335621 Reviewed-by: Harald Alvestrand Reviewed-by: Evan Shrubsole Commit-Queue: Henrik Boström Cr-Commit-Position: refs/heads/main@{#41612} --- api/stats/rtc_stats.h | 15 +- api/stats/rtcstats_objects.h | 415 +++++++++++++++-------------- pc/BUILD.gn | 1 + pc/rtc_stats_collector_unittest.cc | 3 +- pc/rtc_stats_integrationtest.cc | 17 +- pc/rtc_stats_traversal.cc | 3 +- stats/BUILD.gn | 3 + stats/rtc_stats_report_unittest.cc | 7 +- stats/rtc_stats_unittest.cc | 5 +- stats/test/rtc_test_stats.h | 33 +-- 10 files changed, 257 insertions(+), 245 deletions(-) diff --git a/api/stats/rtc_stats.h b/api/stats/rtc_stats.h index 678108109a..74e7fc4d8e 100644 --- a/api/stats/rtc_stats.h +++ b/api/stats/rtc_stats.h @@ -20,6 +20,7 @@ #include #include +#include "absl/types/optional.h" #include "api/stats/attribute.h" #include "api/units/timestamp.h" #include "rtc_base/checks.h" @@ -38,8 +39,8 @@ namespace webrtc { // Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro // for details. // -// Derived classes list their dictionary attributes (RTCStatsMember to soon -// be replaced by absl::optional) as public fields, allowing the following: +// Derived classes list their dictionary attributes, absl::optional, as +// public fields, allowing the following: // // RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime())); // foo.bar = 42; @@ -51,7 +52,7 @@ namespace webrtc { // iteration: // // for (const auto& attribute : foo.Attributes()) { -// printf("%s = %s\n", attribute.name(), attribute.ValueToString().c_str()); +// printf("%s = %s\n", attribute.name(), attribute.ToString().c_str()); // } class RTC_EXPORT RTCStats { public: @@ -72,12 +73,12 @@ class RTC_EXPORT RTCStats { // metrics as viewed via the Attribute wrapper. std::vector Attributes() const; template - Attribute GetAttribute(const RTCStatsMember& stat) const { + Attribute GetAttribute(const absl::optional& stat) const { for (const auto& attribute : Attributes()) { if (!attribute.holds_alternative()) { continue; } - if (absl::get*>(attribute.as_variant()) == + if (absl::get*>(attribute.as_variant()) == &stat) { return attribute; } @@ -135,8 +136,8 @@ class RTC_EXPORT RTCStats { // // RTCFooStats(const std::string& id, Timestamp timestamp); // -// RTCStatsMember foo; -// RTCStatsMember bar; +// absl::optional foo; +// absl::optional bar; // }; // // rtcfoostats.cc: diff --git a/api/stats/rtcstats_objects.h b/api/stats/rtcstats_objects.h index 351c2cbefe..9f51f56cc5 100644 --- a/api/stats/rtcstats_objects.h +++ b/api/stats/rtcstats_objects.h @@ -18,6 +18,7 @@ #include #include +#include "absl/types/optional.h" #include "api/stats/rtc_stats.h" #include "rtc_base/system/rtc_export.h" @@ -30,10 +31,10 @@ class RTC_EXPORT RTCCertificateStats final : public RTCStats { RTCCertificateStats(std::string id, Timestamp timestamp); ~RTCCertificateStats() override; - RTCStatsMember fingerprint; - RTCStatsMember fingerprint_algorithm; - RTCStatsMember base64_certificate; - RTCStatsMember issuer_certificate_id; + absl::optional fingerprint; + absl::optional fingerprint_algorithm; + absl::optional base64_certificate; + absl::optional issuer_certificate_id; }; // https://w3c.github.io/webrtc-stats/#codec-dict* @@ -43,12 +44,12 @@ class RTC_EXPORT RTCCodecStats final : public RTCStats { RTCCodecStats(std::string id, Timestamp timestamp); ~RTCCodecStats() override; - RTCStatsMember transport_id; - RTCStatsMember payload_type; - RTCStatsMember mime_type; - RTCStatsMember clock_rate; - RTCStatsMember channels; - RTCStatsMember sdp_fmtp_line; + absl::optional transport_id; + absl::optional payload_type; + absl::optional mime_type; + absl::optional clock_rate; + absl::optional channels; + absl::optional sdp_fmtp_line; }; // https://w3c.github.io/webrtc-stats/#dcstats-dict* @@ -58,14 +59,14 @@ class RTC_EXPORT RTCDataChannelStats final : public RTCStats { RTCDataChannelStats(std::string id, Timestamp timestamp); ~RTCDataChannelStats() override; - RTCStatsMember label; - RTCStatsMember protocol; - RTCStatsMember data_channel_identifier; - RTCStatsMember state; - RTCStatsMember messages_sent; - RTCStatsMember bytes_sent; - RTCStatsMember messages_received; - RTCStatsMember bytes_received; + absl::optional label; + absl::optional protocol; + absl::optional data_channel_identifier; + absl::optional state; + absl::optional messages_sent; + absl::optional bytes_sent; + absl::optional messages_received; + absl::optional bytes_received; }; // https://w3c.github.io/webrtc-stats/#candidatepair-dict* @@ -75,35 +76,35 @@ class RTC_EXPORT RTCIceCandidatePairStats final : public RTCStats { RTCIceCandidatePairStats(std::string id, Timestamp timestamp); ~RTCIceCandidatePairStats() override; - RTCStatsMember transport_id; - RTCStatsMember local_candidate_id; - RTCStatsMember remote_candidate_id; - RTCStatsMember state; + absl::optional transport_id; + absl::optional local_candidate_id; + absl::optional remote_candidate_id; + absl::optional state; // Obsolete: priority - RTCStatsMember priority; - RTCStatsMember nominated; + absl::optional priority; + absl::optional nominated; // `writable` does not exist in the spec and old comments suggest it used to // exist but was incorrectly implemented. // TODO(https://crbug.com/webrtc/14171): Standardize and/or modify // implementation. - RTCStatsMember writable; - RTCStatsMember packets_sent; - RTCStatsMember packets_received; - RTCStatsMember bytes_sent; - RTCStatsMember bytes_received; - RTCStatsMember total_round_trip_time; - RTCStatsMember current_round_trip_time; - RTCStatsMember available_outgoing_bitrate; - RTCStatsMember available_incoming_bitrate; - RTCStatsMember requests_received; - RTCStatsMember requests_sent; - RTCStatsMember responses_received; - RTCStatsMember responses_sent; - RTCStatsMember consent_requests_sent; - RTCStatsMember packets_discarded_on_send; - RTCStatsMember bytes_discarded_on_send; - RTCStatsMember last_packet_received_timestamp; - RTCStatsMember last_packet_sent_timestamp; + absl::optional writable; + absl::optional packets_sent; + absl::optional packets_received; + absl::optional bytes_sent; + absl::optional bytes_received; + absl::optional total_round_trip_time; + absl::optional current_round_trip_time; + absl::optional available_outgoing_bitrate; + absl::optional available_incoming_bitrate; + absl::optional requests_received; + absl::optional requests_sent; + absl::optional responses_received; + absl::optional responses_sent; + absl::optional consent_requests_sent; + absl::optional packets_discarded_on_send; + absl::optional bytes_discarded_on_send; + absl::optional last_packet_received_timestamp; + absl::optional last_packet_sent_timestamp; }; // https://w3c.github.io/webrtc-stats/#icecandidate-dict* @@ -112,28 +113,28 @@ class RTC_EXPORT RTCIceCandidateStats : public RTCStats { WEBRTC_RTCSTATS_DECL(); ~RTCIceCandidateStats() override; - RTCStatsMember transport_id; + absl::optional transport_id; // Obsolete: is_remote - RTCStatsMember is_remote; - RTCStatsMember network_type; - RTCStatsMember ip; - RTCStatsMember address; - RTCStatsMember port; - RTCStatsMember protocol; - RTCStatsMember relay_protocol; - RTCStatsMember candidate_type; - RTCStatsMember priority; - RTCStatsMember url; - RTCStatsMember foundation; - RTCStatsMember related_address; - RTCStatsMember related_port; - RTCStatsMember username_fragment; - RTCStatsMember tcp_type; + absl::optional is_remote; + absl::optional network_type; + absl::optional ip; + absl::optional address; + absl::optional port; + absl::optional protocol; + absl::optional relay_protocol; + absl::optional candidate_type; + absl::optional priority; + absl::optional url; + absl::optional foundation; + absl::optional related_address; + absl::optional related_port; + absl::optional username_fragment; + absl::optional tcp_type; // The following metrics are NOT exposed to JavaScript. We should consider // standardizing or removing them. - RTCStatsMember vpn; - RTCStatsMember network_adapter_type; + absl::optional vpn; + absl::optional network_adapter_type; protected: RTCIceCandidateStats(std::string id, Timestamp timestamp, bool is_remote); @@ -168,8 +169,8 @@ class RTC_EXPORT RTCPeerConnectionStats final : public RTCStats { RTCPeerConnectionStats(std::string id, Timestamp timestamp); ~RTCPeerConnectionStats() override; - RTCStatsMember data_channels_opened; - RTCStatsMember data_channels_closed; + absl::optional data_channels_opened; + absl::optional data_channels_closed; }; // https://w3c.github.io/webrtc-stats/#streamstats-dict* @@ -178,10 +179,10 @@ class RTC_EXPORT RTCRtpStreamStats : public RTCStats { WEBRTC_RTCSTATS_DECL(); ~RTCRtpStreamStats() override; - RTCStatsMember ssrc; - RTCStatsMember kind; - RTCStatsMember transport_id; - RTCStatsMember codec_id; + absl::optional ssrc; + absl::optional kind; + absl::optional transport_id; + absl::optional codec_id; protected: RTCRtpStreamStats(std::string id, Timestamp timestamp); @@ -193,8 +194,8 @@ class RTC_EXPORT RTCReceivedRtpStreamStats : public RTCRtpStreamStats { WEBRTC_RTCSTATS_DECL(); ~RTCReceivedRtpStreamStats() override; - RTCStatsMember jitter; - RTCStatsMember packets_lost; // Signed per RFC 3550 + absl::optional jitter; + absl::optional packets_lost; // Signed per RFC 3550 protected: RTCReceivedRtpStreamStats(std::string id, Timestamp timestamp); @@ -206,8 +207,8 @@ class RTC_EXPORT RTCSentRtpStreamStats : public RTCRtpStreamStats { WEBRTC_RTCSTATS_DECL(); ~RTCSentRtpStreamStats() override; - RTCStatsMember packets_sent; - RTCStatsMember bytes_sent; + absl::optional packets_sent; + absl::optional bytes_sent; protected: RTCSentRtpStreamStats(std::string id, Timestamp timestamp); @@ -221,51 +222,51 @@ class RTC_EXPORT RTCInboundRtpStreamStats final RTCInboundRtpStreamStats(std::string id, Timestamp timestamp); ~RTCInboundRtpStreamStats() override; - RTCStatsMember playout_id; - RTCStatsMember track_identifier; - RTCStatsMember mid; - RTCStatsMember remote_id; - RTCStatsMember packets_received; - RTCStatsMember packets_discarded; - RTCStatsMember fec_packets_received; - RTCStatsMember fec_bytes_received; - RTCStatsMember fec_packets_discarded; + absl::optional playout_id; + absl::optional track_identifier; + absl::optional mid; + absl::optional remote_id; + absl::optional packets_received; + absl::optional packets_discarded; + absl::optional fec_packets_received; + absl::optional fec_bytes_received; + absl::optional fec_packets_discarded; // Inbound FEC SSRC. Only present if a mechanism like FlexFEC is negotiated. - RTCStatsMember fec_ssrc; - RTCStatsMember bytes_received; - RTCStatsMember header_bytes_received; + absl::optional fec_ssrc; + absl::optional bytes_received; + absl::optional header_bytes_received; // Inbound RTX stats. Only defined when RTX is used and it is therefore // possible to distinguish retransmissions. - RTCStatsMember retransmitted_packets_received; - RTCStatsMember retransmitted_bytes_received; - RTCStatsMember rtx_ssrc; + absl::optional retransmitted_packets_received; + absl::optional retransmitted_bytes_received; + absl::optional rtx_ssrc; - RTCStatsMember last_packet_received_timestamp; - RTCStatsMember jitter_buffer_delay; - RTCStatsMember jitter_buffer_target_delay; - RTCStatsMember jitter_buffer_minimum_delay; - RTCStatsMember jitter_buffer_emitted_count; - RTCStatsMember total_samples_received; - RTCStatsMember concealed_samples; - RTCStatsMember silent_concealed_samples; - RTCStatsMember concealment_events; - RTCStatsMember inserted_samples_for_deceleration; - RTCStatsMember removed_samples_for_acceleration; - RTCStatsMember audio_level; - RTCStatsMember total_audio_energy; - RTCStatsMember total_samples_duration; + absl::optional last_packet_received_timestamp; + absl::optional jitter_buffer_delay; + absl::optional jitter_buffer_target_delay; + absl::optional jitter_buffer_minimum_delay; + absl::optional jitter_buffer_emitted_count; + absl::optional total_samples_received; + absl::optional concealed_samples; + absl::optional silent_concealed_samples; + absl::optional concealment_events; + absl::optional inserted_samples_for_deceleration; + absl::optional removed_samples_for_acceleration; + absl::optional audio_level; + absl::optional total_audio_energy; + absl::optional total_samples_duration; // Stats below are only implemented or defined for video. - RTCStatsMember frames_received; - RTCStatsMember frame_width; - RTCStatsMember frame_height; - RTCStatsMember frames_per_second; - RTCStatsMember frames_decoded; - RTCStatsMember key_frames_decoded; - RTCStatsMember frames_dropped; - RTCStatsMember total_decode_time; - RTCStatsMember total_processing_delay; - RTCStatsMember total_assembly_time; - RTCStatsMember frames_assembled_from_multiple_packets; + absl::optional frames_received; + absl::optional frame_width; + absl::optional frame_height; + absl::optional frames_per_second; + absl::optional frames_decoded; + absl::optional key_frames_decoded; + absl::optional frames_dropped; + absl::optional total_decode_time; + absl::optional total_processing_delay; + absl::optional total_assembly_time; + absl::optional frames_assembled_from_multiple_packets; // TODO(https://crbug.com/webrtc/15600): Implement framesRendered, which is // incremented at the same time that totalInterFrameDelay and // totalSquaredInterFrameDelay is incremented. (Dividing inter-frame delay by @@ -277,43 +278,43 @@ class RTC_EXPORT RTCInboundRtpStreamStats final // at delivery to sink, not at actual render time. When we have an actual // frame rendered callback, move the calculating of these metrics to there in // order to make them more accurate. - RTCStatsMember total_inter_frame_delay; - RTCStatsMember total_squared_inter_frame_delay; - RTCStatsMember pause_count; - RTCStatsMember total_pauses_duration; - RTCStatsMember freeze_count; - RTCStatsMember total_freezes_duration; + absl::optional total_inter_frame_delay; + absl::optional total_squared_inter_frame_delay; + absl::optional pause_count; + absl::optional total_pauses_duration; + absl::optional freeze_count; + absl::optional total_freezes_duration; // https://w3c.github.io/webrtc-provisional-stats/#dom-rtcinboundrtpstreamstats-contenttype - RTCStatsMember content_type; + absl::optional content_type; // Only populated if audio/video sync is enabled. // TODO(https://crbug.com/webrtc/14177): Expose even if A/V sync is off? - RTCStatsMember estimated_playout_timestamp; + absl::optional estimated_playout_timestamp; // Only defined for video. // In JavaScript, this is only exposed if HW exposure is allowed. - RTCStatsMember decoder_implementation; + absl::optional decoder_implementation; // FIR and PLI counts are only defined for |kind == "video"|. - RTCStatsMember fir_count; - RTCStatsMember pli_count; - RTCStatsMember nack_count; - RTCStatsMember qp_sum; + absl::optional fir_count; + absl::optional pli_count; + absl::optional nack_count; + absl::optional qp_sum; // This is a remnant of the legacy getStats() API. When the "video-timing" // header extension is used, // https://webrtc.github.io/webrtc-org/experiments/rtp-hdrext/video-timing/, // `googTimingFrameInfo` is exposed with the value of // TimingFrameInfo::ToString(). // TODO(https://crbug.com/webrtc/14586): Unship or standardize this metric. - RTCStatsMember goog_timing_frame_info; + absl::optional goog_timing_frame_info; // In JavaScript, this is only exposed if HW exposure is allowed. - RTCStatsMember power_efficient_decoder; + absl::optional power_efficient_decoder; // The following metrics are NOT exposed to JavaScript. We should consider // standardizing or removing them. - RTCStatsMember jitter_buffer_flushes; - RTCStatsMember delayed_packet_outage_samples; - RTCStatsMember relative_packet_arrival_delay; - RTCStatsMember interruption_count; - RTCStatsMember total_interruption_duration; - RTCStatsMember min_playout_delay; + absl::optional jitter_buffer_flushes; + absl::optional delayed_packet_outage_samples; + absl::optional relative_packet_arrival_delay; + absl::optional interruption_count; + absl::optional total_interruption_duration; + absl::optional min_playout_delay; }; // https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict* @@ -324,46 +325,46 @@ class RTC_EXPORT RTCOutboundRtpStreamStats final RTCOutboundRtpStreamStats(std::string id, Timestamp timestamp); ~RTCOutboundRtpStreamStats() override; - RTCStatsMember media_source_id; - RTCStatsMember remote_id; - RTCStatsMember mid; - RTCStatsMember rid; - RTCStatsMember retransmitted_packets_sent; - RTCStatsMember header_bytes_sent; - RTCStatsMember retransmitted_bytes_sent; - RTCStatsMember target_bitrate; - RTCStatsMember frames_encoded; - RTCStatsMember key_frames_encoded; - RTCStatsMember total_encode_time; - RTCStatsMember total_encoded_bytes_target; - RTCStatsMember frame_width; - RTCStatsMember frame_height; - RTCStatsMember frames_per_second; - RTCStatsMember frames_sent; - RTCStatsMember huge_frames_sent; - RTCStatsMember total_packet_send_delay; - RTCStatsMember quality_limitation_reason; - RTCStatsMember> quality_limitation_durations; + absl::optional media_source_id; + absl::optional remote_id; + absl::optional mid; + absl::optional rid; + absl::optional retransmitted_packets_sent; + absl::optional header_bytes_sent; + absl::optional retransmitted_bytes_sent; + absl::optional target_bitrate; + absl::optional frames_encoded; + absl::optional key_frames_encoded; + absl::optional total_encode_time; + absl::optional total_encoded_bytes_target; + absl::optional frame_width; + absl::optional frame_height; + absl::optional frames_per_second; + absl::optional frames_sent; + absl::optional huge_frames_sent; + absl::optional total_packet_send_delay; + absl::optional quality_limitation_reason; + absl::optional> quality_limitation_durations; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-qualitylimitationresolutionchanges - RTCStatsMember quality_limitation_resolution_changes; + absl::optional quality_limitation_resolution_changes; // https://w3c.github.io/webrtc-provisional-stats/#dom-rtcoutboundrtpstreamstats-contenttype - RTCStatsMember content_type; + absl::optional content_type; // In JavaScript, this is only exposed if HW exposure is allowed. // Only implemented for video. // TODO(https://crbug.com/webrtc/14178): Implement for audio as well. - RTCStatsMember encoder_implementation; + absl::optional encoder_implementation; // FIR and PLI counts are only defined for |kind == "video"|. - RTCStatsMember fir_count; - RTCStatsMember pli_count; - RTCStatsMember nack_count; - RTCStatsMember qp_sum; - RTCStatsMember active; + absl::optional fir_count; + absl::optional pli_count; + absl::optional nack_count; + absl::optional qp_sum; + absl::optional active; // In JavaScript, this is only exposed if HW exposure is allowed. - RTCStatsMember power_efficient_encoder; - RTCStatsMember scalability_mode; + absl::optional power_efficient_encoder; + absl::optional scalability_mode; // RTX ssrc. Only present if RTX is negotiated. - RTCStatsMember rtx_ssrc; + absl::optional rtx_ssrc; }; // https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict* @@ -374,11 +375,11 @@ class RTC_EXPORT RTCRemoteInboundRtpStreamStats final RTCRemoteInboundRtpStreamStats(std::string id, Timestamp timestamp); ~RTCRemoteInboundRtpStreamStats() override; - RTCStatsMember local_id; - RTCStatsMember round_trip_time; - RTCStatsMember fraction_lost; - RTCStatsMember total_round_trip_time; - RTCStatsMember round_trip_time_measurements; + absl::optional local_id; + absl::optional round_trip_time; + absl::optional fraction_lost; + absl::optional total_round_trip_time; + absl::optional round_trip_time_measurements; }; // https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict* @@ -389,12 +390,12 @@ class RTC_EXPORT RTCRemoteOutboundRtpStreamStats final RTCRemoteOutboundRtpStreamStats(std::string id, Timestamp timestamp); ~RTCRemoteOutboundRtpStreamStats() override; - RTCStatsMember local_id; - RTCStatsMember remote_timestamp; - RTCStatsMember reports_sent; - RTCStatsMember round_trip_time; - RTCStatsMember round_trip_time_measurements; - RTCStatsMember total_round_trip_time; + absl::optional local_id; + absl::optional remote_timestamp; + absl::optional reports_sent; + absl::optional round_trip_time; + absl::optional round_trip_time_measurements; + absl::optional total_round_trip_time; }; // https://w3c.github.io/webrtc-stats/#dom-rtcmediasourcestats @@ -403,8 +404,8 @@ class RTC_EXPORT RTCMediaSourceStats : public RTCStats { WEBRTC_RTCSTATS_DECL(); ~RTCMediaSourceStats() override; - RTCStatsMember track_identifier; - RTCStatsMember kind; + absl::optional track_identifier; + absl::optional kind; protected: RTCMediaSourceStats(std::string id, Timestamp timestamp); @@ -417,11 +418,11 @@ class RTC_EXPORT RTCAudioSourceStats final : public RTCMediaSourceStats { RTCAudioSourceStats(std::string id, Timestamp timestamp); ~RTCAudioSourceStats() override; - RTCStatsMember audio_level; - RTCStatsMember total_audio_energy; - RTCStatsMember total_samples_duration; - RTCStatsMember echo_return_loss; - RTCStatsMember echo_return_loss_enhancement; + absl::optional audio_level; + absl::optional total_audio_energy; + absl::optional total_samples_duration; + absl::optional echo_return_loss; + absl::optional echo_return_loss_enhancement; }; // https://w3c.github.io/webrtc-stats/#dom-rtcvideosourcestats @@ -431,10 +432,10 @@ class RTC_EXPORT RTCVideoSourceStats final : public RTCMediaSourceStats { RTCVideoSourceStats(std::string id, Timestamp timestamp); ~RTCVideoSourceStats() override; - RTCStatsMember width; - RTCStatsMember height; - RTCStatsMember frames; - RTCStatsMember frames_per_second; + absl::optional width; + absl::optional height; + absl::optional frames; + absl::optional frames_per_second; }; // https://w3c.github.io/webrtc-stats/#transportstats-dict* @@ -444,23 +445,23 @@ class RTC_EXPORT RTCTransportStats final : public RTCStats { RTCTransportStats(std::string id, Timestamp timestamp); ~RTCTransportStats() override; - RTCStatsMember bytes_sent; - RTCStatsMember packets_sent; - RTCStatsMember bytes_received; - RTCStatsMember packets_received; - RTCStatsMember rtcp_transport_stats_id; - RTCStatsMember dtls_state; - RTCStatsMember selected_candidate_pair_id; - RTCStatsMember local_certificate_id; - RTCStatsMember remote_certificate_id; - RTCStatsMember tls_version; - RTCStatsMember dtls_cipher; - RTCStatsMember dtls_role; - RTCStatsMember srtp_cipher; - RTCStatsMember selected_candidate_pair_changes; - RTCStatsMember ice_role; - RTCStatsMember ice_local_username_fragment; - RTCStatsMember ice_state; + absl::optional bytes_sent; + absl::optional packets_sent; + absl::optional bytes_received; + absl::optional packets_received; + absl::optional rtcp_transport_stats_id; + absl::optional dtls_state; + absl::optional selected_candidate_pair_id; + absl::optional local_certificate_id; + absl::optional remote_certificate_id; + absl::optional tls_version; + absl::optional dtls_cipher; + absl::optional dtls_role; + absl::optional srtp_cipher; + absl::optional selected_candidate_pair_changes; + absl::optional ice_role; + absl::optional ice_local_username_fragment; + absl::optional ice_state; }; // https://w3c.github.io/webrtc-stats/#playoutstats-dict* @@ -470,12 +471,12 @@ class RTC_EXPORT RTCAudioPlayoutStats final : public RTCStats { RTCAudioPlayoutStats(const std::string& id, Timestamp timestamp); ~RTCAudioPlayoutStats() override; - RTCStatsMember kind; - RTCStatsMember synthesized_samples_duration; - RTCStatsMember synthesized_samples_events; - RTCStatsMember total_samples_duration; - RTCStatsMember total_playout_delay; - RTCStatsMember total_samples_count; + absl::optional kind; + absl::optional synthesized_samples_duration; + absl::optional synthesized_samples_events; + absl::optional total_samples_duration; + absl::optional total_playout_delay; + absl::optional total_samples_count; }; } // namespace webrtc diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 2edbf9d63a..1f814cb1aa 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -970,6 +970,7 @@ rtc_source_set("rtc_stats_traversal") { "../api:scoped_refptr", "../rtc_base:checks", ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } rtc_source_set("sdp_offer_answer") { diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc index 61b3bca1db..03512bbcde 100644 --- a/pc/rtc_stats_collector_unittest.cc +++ b/pc/rtc_stats_collector_unittest.cc @@ -23,6 +23,7 @@ #include #include "absl/strings/str_replace.h" +#include "absl/types/optional.h" #include "api/candidate.h" #include "api/dtls_transport_interface.h" #include "api/media_stream_interface.h" @@ -3723,7 +3724,7 @@ class RTCTestStats : public RTCStats { RTCTestStats(const std::string& id, Timestamp timestamp) : RTCStats(id, timestamp) {} - RTCStatsMember dummy_stat; + absl::optional dummy_stat; }; WEBRTC_RTCSTATS_IMPL(RTCTestStats, diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc index 002f9d34b5..de8e6e3f67 100644 --- a/pc/rtc_stats_integrationtest.cc +++ b/pc/rtc_stats_integrationtest.cc @@ -18,6 +18,7 @@ #include "absl/algorithm/container.h" #include "absl/strings/match.h" +#include "absl/types/optional.h" #include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/audio_options.h" @@ -212,14 +213,14 @@ class RTCStatsVerifier { } template - void MarkAttributeTested(const RTCStatsMember& field, + void MarkAttributeTested(const absl::optional& field, bool test_successful) { untested_attribute_names_.erase(stats_->GetAttribute(field).name()); all_tests_successful_ &= test_successful; } template - void TestAttributeIsDefined(const RTCStatsMember& field) { + void TestAttributeIsDefined(const absl::optional& field) { EXPECT_TRUE(field.has_value()) << stats_->type() << "." << stats_->GetAttribute(field).name() << "[" << stats_->id() << "] was undefined."; @@ -227,7 +228,7 @@ class RTCStatsVerifier { } template - void TestAttributeIsUndefined(const RTCStatsMember& field) { + void TestAttributeIsUndefined(const absl::optional& field) { Attribute attribute = stats_->GetAttribute(field); EXPECT_FALSE(field.has_value()) << stats_->type() << "." << attribute.name() << "[" << stats_->id() @@ -236,7 +237,7 @@ class RTCStatsVerifier { } template - void TestAttributeIsPositive(const RTCStatsMember& field) { + void TestAttributeIsPositive(const absl::optional& field) { Attribute attribute = stats_->GetAttribute(field); EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name() << "[" << stats_->id() << "] was undefined."; @@ -252,7 +253,7 @@ class RTCStatsVerifier { } template - void TestAttributeIsNonNegative(const RTCStatsMember& field) { + void TestAttributeIsNonNegative(const absl::optional& field) { Attribute attribute = stats_->GetAttribute(field); EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name() << "[" << stats_->id() << "] was undefined."; @@ -268,13 +269,13 @@ class RTCStatsVerifier { } template - void TestAttributeIsIDReference(const RTCStatsMember& field, + void TestAttributeIsIDReference(const absl::optional& field, const char* expected_type) { TestAttributeIsIDReference(field, expected_type, false); } template - void TestAttributeIsOptionalIDReference(const RTCStatsMember& field, + void TestAttributeIsOptionalIDReference(const absl::optional& field, const char* expected_type) { TestAttributeIsIDReference(field, expected_type, true); } @@ -291,7 +292,7 @@ class RTCStatsVerifier { private: template - void TestAttributeIsIDReference(const RTCStatsMember& field, + void TestAttributeIsIDReference(const absl::optional& field, const char* expected_type, bool optional) { if (optional && !field.has_value()) { diff --git a/pc/rtc_stats_traversal.cc b/pc/rtc_stats_traversal.cc index dfd0570b8f..e9d11b5ae5 100644 --- a/pc/rtc_stats_traversal.cc +++ b/pc/rtc_stats_traversal.cc @@ -15,6 +15,7 @@ #include #include +#include "absl/types/optional.h" #include "api/stats/rtcstats_objects.h" #include "rtc_base/checks.h" @@ -42,7 +43,7 @@ void TraverseAndTakeVisitedStats(RTCStatsReport* report, } } -void AddIdIfDefined(const RTCStatsMember& id, +void AddIdIfDefined(const absl::optional& id, std::vector* neighbor_ids) { if (id.has_value()) neighbor_ids->push_back(&(*id)); diff --git a/stats/BUILD.gn b/stats/BUILD.gn index 76edc441cb..1ca584d6a2 100644 --- a/stats/BUILD.gn +++ b/stats/BUILD.gn @@ -45,6 +45,7 @@ rtc_library("rtc_stats_test_utils") { "../rtc_base:checks", "../rtc_base/system:rtc_export", ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } if (rtc_include_tests && !build_with_chromium) { @@ -74,5 +75,7 @@ if (rtc_include_tests && !build_with_chromium) { "//testing/android/native_test:native_test_support", ] } + + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } } diff --git a/stats/rtc_stats_report_unittest.cc b/stats/rtc_stats_report_unittest.cc index b3ac0a2db4..f11ff52e53 100644 --- a/stats/rtc_stats_report_unittest.cc +++ b/stats/rtc_stats_report_unittest.cc @@ -10,6 +10,7 @@ #include "api/stats/rtc_stats_report.h" +#include "absl/types/optional.h" #include "api/stats/attribute.h" #include "api/stats/rtc_stats.h" #include "rtc_base/checks.h" @@ -24,7 +25,7 @@ class RTCTestStats1 : public RTCStats { RTCTestStats1(const std::string& id, Timestamp timestamp) : RTCStats(id, timestamp) {} - RTCStatsMember integer; + absl::optional integer; }; WEBRTC_RTCSTATS_IMPL(RTCTestStats1, @@ -39,7 +40,7 @@ class RTCTestStats2 : public RTCStats { RTCTestStats2(const std::string& id, Timestamp timestamp) : RTCStats(id, timestamp) {} - RTCStatsMember number; + absl::optional number; }; WEBRTC_RTCSTATS_IMPL(RTCTestStats2, @@ -54,7 +55,7 @@ class RTCTestStats3 : public RTCStats { RTCTestStats3(const std::string& id, Timestamp timestamp) : RTCStats(id, timestamp) {} - RTCStatsMember string; + absl::optional string; }; WEBRTC_RTCSTATS_IMPL(RTCTestStats3, diff --git a/stats/rtc_stats_unittest.cc b/stats/rtc_stats_unittest.cc index 1098f04b65..555360f07f 100644 --- a/stats/rtc_stats_unittest.cc +++ b/stats/rtc_stats_unittest.cc @@ -15,6 +15,7 @@ #include #include +#include "absl/types/optional.h" #include "rtc_base/checks.h" #include "rtc_base/strings/json.h" #include "stats/test/rtc_test_stats.h" @@ -46,7 +47,7 @@ class RTCChildStats : public RTCStats { RTCChildStats(const std::string& id, Timestamp timestamp) : RTCStats(id, timestamp) {} - RTCStatsMember child_int; + absl::optional child_int; }; WEBRTC_RTCSTATS_IMPL(RTCChildStats, @@ -61,7 +62,7 @@ class RTCGrandChildStats : public RTCChildStats { RTCGrandChildStats(const std::string& id, Timestamp timestamp) : RTCChildStats(id, timestamp) {} - RTCStatsMember grandchild_int; + absl::optional grandchild_int; }; WEBRTC_RTCSTATS_IMPL(RTCGrandChildStats, diff --git a/stats/test/rtc_test_stats.h b/stats/test/rtc_test_stats.h index 05c0904c02..ff1a06f97c 100644 --- a/stats/test/rtc_test_stats.h +++ b/stats/test/rtc_test_stats.h @@ -16,6 +16,7 @@ #include #include +#include "absl/types/optional.h" #include "api/stats/rtc_stats.h" #include "rtc_base/system/rtc_export.h" @@ -27,22 +28,22 @@ class RTC_EXPORT RTCTestStats : public RTCStats { RTCTestStats(const std::string& id, Timestamp timestamp); ~RTCTestStats() override; - RTCStatsMember m_bool; - RTCStatsMember m_int32; - RTCStatsMember m_uint32; - RTCStatsMember m_int64; - RTCStatsMember m_uint64; - RTCStatsMember m_double; - RTCStatsMember m_string; - RTCStatsMember> m_sequence_bool; - RTCStatsMember> m_sequence_int32; - RTCStatsMember> m_sequence_uint32; - RTCStatsMember> m_sequence_int64; - RTCStatsMember> m_sequence_uint64; - RTCStatsMember> m_sequence_double; - RTCStatsMember> m_sequence_string; - RTCStatsMember> m_map_string_uint64; - RTCStatsMember> m_map_string_double; + absl::optional m_bool; + absl::optional m_int32; + absl::optional m_uint32; + absl::optional m_int64; + absl::optional m_uint64; + absl::optional m_double; + absl::optional m_string; + absl::optional> m_sequence_bool; + absl::optional> m_sequence_int32; + absl::optional> m_sequence_uint32; + absl::optional> m_sequence_int64; + absl::optional> m_sequence_uint64; + absl::optional> m_sequence_double; + absl::optional> m_sequence_string; + absl::optional> m_map_string_uint64; + absl::optional> m_map_string_double; }; } // namespace webrtc From 0817380a56a627c8ea24d5dedcab5708f64bc27a Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Tue, 23 Jan 2024 13:02:46 +0100 Subject: [PATCH 017/170] Pass Environment when creating VideoDecoder in VideoReceiveStream2 Bug: webrtc:15791 Change-Id: Ic646d6303bab1d28057258707aaa3c3e75ac9454 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335820 Reviewed-by: Philip Eliasson Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41613} --- video/video_receive_stream2.cc | 2 +- video/video_receive_stream2_unittest.cc | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc index 9e095064ba..7d307c6d2c 100644 --- a/video/video_receive_stream2.cc +++ b/video/video_receive_stream2.cc @@ -519,7 +519,7 @@ void VideoReceiveStream2::CreateAndRegisterExternalDecoder( TRACE_EVENT0("webrtc", "VideoReceiveStream2::CreateAndRegisterExternalDecoder"); std::unique_ptr video_decoder = - config_.decoder_factory->CreateVideoDecoder(decoder.video_format); + config_.decoder_factory->Create(env_, decoder.video_format); // If we still have no valid decoder, we have to create a "Null" decoder // that ignores all calls. The reason we can get into this state is that the // old decoder factory interface doesn't have a way to query supported diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc index 50e00aa31b..221d17b5be 100644 --- a/video/video_receive_stream2_unittest.cc +++ b/video/video_receive_stream2_unittest.cc @@ -205,10 +205,9 @@ class VideoReceiveStream2Test : public ::testing::TestWithParam { time_controller_.GetMainThread()), h264_decoder_factory_(&mock_decoder_) { // By default, mock decoder factory is backed by VideoDecoderProxyFactory. - ON_CALL(mock_h264_decoder_factory_, CreateVideoDecoder) - .WillByDefault( - Invoke(&h264_decoder_factory_, - &test::VideoDecoderProxyFactory::CreateVideoDecoder)); + ON_CALL(mock_h264_decoder_factory_, Create) + .WillByDefault(Invoke(&h264_decoder_factory_, + &test::VideoDecoderProxyFactory::Create)); // By default, mock decode will wrap the fake decoder. ON_CALL(mock_decoder_, Configure) @@ -459,7 +458,7 @@ TEST_P(VideoReceiveStream2Test, LazyDecoderCreation) { rtppacket.SetTimestamp(0); // No decoders are created by default. - EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0); + EXPECT_CALL(mock_h264_decoder_factory_, Create).Times(0); video_receive_stream_->Start(); time_controller_.AdvanceTime(TimeDelta::Zero()); @@ -467,9 +466,8 @@ TEST_P(VideoReceiveStream2Test, LazyDecoderCreation) { testing::Mock::VerifyAndClearExpectations(&mock_h264_decoder_factory_)); // Verify that the decoder is created when we receive payload data and tries // to decode a frame. - EXPECT_CALL( - mock_h264_decoder_factory_, - CreateVideoDecoder(Field(&SdpVideoFormat::name, testing::Eq("H264")))); + EXPECT_CALL(mock_h264_decoder_factory_, + Create(_, Field(&SdpVideoFormat::name, Eq("H264")))); EXPECT_CALL(mock_decoder_, Configure); EXPECT_CALL(mock_decoder_, RegisterDecodeCompleteCallback); EXPECT_CALL(mock_decoder_, Decode(_, _)); From 7f8470aeee3fb89d6f092439815174182b6327c7 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Thu, 25 Jan 2024 20:12:48 -0800 Subject: [PATCH 018/170] Update WebRTC code version (2024-01-26T04:12:47). Bug: None Change-Id: I27338ea03015c09342762cd65b2afec2175b9b6c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336304 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41614} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 85fdf004ea..4c8c9194b1 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-21T04:12:31"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-26T04:12:47"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 6a3bbefd583dfbc1c0cb1013dda17a26da3f989d Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Tue, 12 Dec 2023 14:45:31 +0100 Subject: [PATCH 019/170] Reland "Enable DD and VLA header extensions by default for Simulcast/SVC" This is a reland of commit 33c7edd58ad0edc71939b9372fff3ab563c1f4a7 taking into account GFD which can be enabled by field trials and somewhat conflicts with DD Original change's description: > Enable DD and VLA header extensions by default for Simulcast/SVC > > When Simulcast (more than one encoding) or SVC (a scalability mode > other than the default L1T1) is used, enable the AV1 Dependency > Descriptor and the video-layer-allocations RTP header extensions by > default. > > The RTP header extensions API can be used to disable them if needed. > > BUG=webrtc:15378 > > Change-Id: I587ac32c9d681461496a136f6950b007e72da86d > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326100 > Reviewed-by: Harald Alvestrand > Reviewed-by: Danil Chapovalov > Commit-Queue: Philipp Hancke > Cr-Commit-Position: refs/heads/main@{#41332} Bug: webrtc:15378 Change-Id: I190edc9435083c0a0a65a6959363f3c41e4a3d1b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/330563 Commit-Queue: Philipp Hancke Reviewed-by: Harald Alvestrand Reviewed-by: Florent Castelli Reviewed-by: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41615} --- pc/rtp_transceiver.cc | 29 +++++++++++++ pc/rtp_transceiver_unittest.cc | 75 ++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index 34d744a3bb..de31b2e36a 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -171,6 +171,35 @@ RtpTransceiver::RtpTransceiver( : media_engine()->voice().send_codecs()); senders_.push_back(sender); receivers_.push_back(receiver); + + // Set default header extensions depending on whether simulcast/SVC is used. + RtpParameters parameters = sender->internal()->GetParametersInternal(); + bool uses_simulcast = parameters.encodings.size() > 1; + bool uses_svc = !parameters.encodings.empty() && + parameters.encodings[0].scalability_mode.has_value() && + parameters.encodings[0].scalability_mode != + ScalabilityModeToString(ScalabilityMode::kL1T1); + if (uses_simulcast || uses_svc) { + // Enable DD and VLA extensions, can be deactivated by the API. + // Skip this if the GFD extension was enabled via field trial + // for backward compability reasons. + bool uses_gfd = + absl::c_find_if( + header_extensions_to_negotiate_, + [](const RtpHeaderExtensionCapability& ext) { + return ext.uri == RtpExtension::kGenericFrameDescriptorUri00 && + ext.direction != webrtc::RtpTransceiverDirection::kStopped; + }) != header_extensions_to_negotiate_.end(); + if (!uses_gfd) { + for (RtpHeaderExtensionCapability& ext : + header_extensions_to_negotiate_) { + if (ext.uri == RtpExtension::kVideoLayersAllocationUri || + ext.uri == RtpExtension::kDependencyDescriptorUri) { + ext.direction = RtpTransceiverDirection::kSendRecv; + } + } + } + } } RtpTransceiver::~RtpTransceiver() { diff --git a/pc/rtp_transceiver_unittest.cc b/pc/rtp_transceiver_unittest.cc index d75e964509..b6dc7b2bb9 100644 --- a/pc/rtp_transceiver_unittest.cc +++ b/pc/rtp_transceiver_unittest.cc @@ -481,6 +481,81 @@ TEST_F(RtpTransceiverTestForHeaderExtensions, RtpTransceiverDirection::kStopped))); } +TEST_F(RtpTransceiverTestForHeaderExtensions, + SimulcastOrSvcEnablesExtensionsByDefault) { + std::vector extensions = { + {RtpExtension::kDependencyDescriptorUri, 1, + RtpTransceiverDirection::kStopped}, + {RtpExtension::kVideoLayersAllocationUri, 2, + RtpTransceiverDirection::kStopped}, + }; + + // Default is stopped. + auto sender = rtc::make_ref_counted(); + auto transceiver = rtc::make_ref_counted( + RtpSenderProxyWithInternal::Create( + rtc::Thread::Current(), sender), + RtpReceiverProxyWithInternal::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + std::vector header_extensions = + transceiver->GetHeaderExtensionsToNegotiate(); + ASSERT_EQ(header_extensions.size(), 2u); + EXPECT_EQ(header_extensions[0].uri, RtpExtension::kDependencyDescriptorUri); + EXPECT_EQ(header_extensions[0].direction, RtpTransceiverDirection::kStopped); + EXPECT_EQ(header_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri); + EXPECT_EQ(header_extensions[1].direction, RtpTransceiverDirection::kStopped); + + // Simulcast, i.e. more than one encoding. + RtpParameters simulcast_parameters; + simulcast_parameters.encodings.resize(2); + auto simulcast_sender = rtc::make_ref_counted(); + EXPECT_CALL(*simulcast_sender, GetParametersInternal()) + .WillRepeatedly(Return(simulcast_parameters)); + auto simulcast_transceiver = rtc::make_ref_counted( + RtpSenderProxyWithInternal::Create( + rtc::Thread::Current(), simulcast_sender), + RtpReceiverProxyWithInternal::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + auto simulcast_extensions = + simulcast_transceiver->GetHeaderExtensionsToNegotiate(); + ASSERT_EQ(simulcast_extensions.size(), 2u); + EXPECT_EQ(simulcast_extensions[0].uri, + RtpExtension::kDependencyDescriptorUri); + EXPECT_EQ(simulcast_extensions[0].direction, + RtpTransceiverDirection::kSendRecv); + EXPECT_EQ(simulcast_extensions[1].uri, + RtpExtension::kVideoLayersAllocationUri); + EXPECT_EQ(simulcast_extensions[1].direction, + RtpTransceiverDirection::kSendRecv); + + // SVC, a single encoding with a scalabilityMode other than L1T1. + webrtc::RtpParameters svc_parameters; + svc_parameters.encodings.resize(1); + svc_parameters.encodings[0].scalability_mode = "L3T3"; + + auto svc_sender = rtc::make_ref_counted(); + EXPECT_CALL(*svc_sender, GetParametersInternal()) + .WillRepeatedly(Return(svc_parameters)); + auto svc_transceiver = rtc::make_ref_counted( + RtpSenderProxyWithInternal::Create( + rtc::Thread::Current(), svc_sender), + RtpReceiverProxyWithInternal::Create( + rtc::Thread::Current(), rtc::Thread::Current(), receiver_), + context(), extensions, + /* on_negotiation_needed= */ [] {}); + std::vector svc_extensions = + svc_transceiver->GetHeaderExtensionsToNegotiate(); + ASSERT_EQ(svc_extensions.size(), 2u); + EXPECT_EQ(svc_extensions[0].uri, RtpExtension::kDependencyDescriptorUri); + EXPECT_EQ(svc_extensions[0].direction, RtpTransceiverDirection::kSendRecv); + EXPECT_EQ(svc_extensions[1].uri, RtpExtension::kVideoLayersAllocationUri); + EXPECT_EQ(svc_extensions[1].direction, RtpTransceiverDirection::kSendRecv); +} + } // namespace } // namespace webrtc From 523eff622efd2535a303cb68f202059b9f835249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= Date: Mon, 22 Jan 2024 13:52:38 +0100 Subject: [PATCH 020/170] [Stats] Delete unused RTCStatsMember type alias. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this CL the migration to absl::optional is complete. Bug: webrtc:15164 Change-Id: I978d86833fbd39154ed9026206a02ea7496f8c4f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335640 Reviewed-by: Harald Alvestrand Commit-Queue: Henrik Boström Reviewed-by: Evan Shrubsole Cr-Commit-Position: refs/heads/main@{#41616} --- api/stats/attribute.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/api/stats/attribute.h b/api/stats/attribute.h index d5fb290750..36500db999 100644 --- a/api/stats/attribute.h +++ b/api/stats/attribute.h @@ -23,14 +23,11 @@ namespace webrtc { -// TODO(https://crbug.com/webrtc/15164): Migrate all uses of RTCStatsMember to -// absl::optional and delete this type alias. -template -using RTCStatsMember = absl::optional; - -// A light-weight wrapper of an RTCStats attribute (an individual metric). +// A light-weight wrapper of an RTCStats attribute, i.e. an individual metric of +// type absl::optional. class RTC_EXPORT Attribute { public: + // All supported attribute types. typedef absl::variant*, const absl::optional*, const absl::optional*, From d213dd55171337f287730fb3581cee9cd92e1646 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Thu, 25 Jan 2024 15:48:24 +0100 Subject: [PATCH 021/170] Pass Environment to VideoDecoders through VideoCodecTester Bug: webrtc:15791 Change-Id: I002734a17ece1d11b77a261aa8160c4afa1702b5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336241 Reviewed-by: Jeremy Leconte Commit-Queue: Danil Chapovalov Reviewed-by: Philip Eliasson Cr-Commit-Position: refs/heads/main@{#41617} --- modules/video_coding/BUILD.gn | 2 + .../codecs/test/video_codec_test.cc | 13 ++-- test/BUILD.gn | 2 + test/video_codec_tester.cc | 19 +++--- test/video_codec_tester.h | 2 + test/video_codec_tester_unittest.cc | 63 +++++++++---------- 6 files changed, 58 insertions(+), 43 deletions(-) diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 0457b818c3..6bf97de9a8 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -999,6 +999,8 @@ if (rtc_include_tests) { deps = [ ":video_codec_interface", + "../../api/environment", + "../../api/environment:environment_factory", "../../api/test/metrics:global_metrics_logger_and_exporter", "../../api/units:data_rate", "../../api/units:frequency", diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc index 2ab1106a59..d5c7b51484 100644 --- a/modules/video_coding/codecs/test/video_codec_test.cc +++ b/modules/video_coding/codecs/test/video_codec_test.cc @@ -14,6 +14,8 @@ #include "absl/flags/flag.h" #include "absl/functional/any_invocable.h" +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/test/metrics/global_metrics_logger_and_exporter.h" #include "api/units/data_rate.h" #include "api/units/frequency.h" @@ -178,6 +180,7 @@ std::string TestOutputPath() { } // namespace std::unique_ptr RunEncodeDecodeTest( + const Environment& env, std::string encoder_impl, std::string decoder_impl, const VideoInfo& video_info, @@ -247,7 +250,7 @@ std::unique_ptr RunEncodeDecodeTest( } return VideoCodecTester::RunEncodeDecodeTest( - source_settings, encoder_factory.get(), decoder_factory.get(), + env, source_settings, encoder_factory.get(), decoder_factory.get(), encoder_settings, decoder_settings, encoding_settings); } @@ -313,6 +316,7 @@ class SpatialQualityTest : public ::testing::TestWithParam stats = - RunEncodeDecodeTest(codec_impl, codec_impl, video_info, frames_settings); + std::unique_ptr stats = RunEncodeDecodeTest( + env, codec_impl, codec_impl, video_info, frames_settings); VideoCodecStats::Stream stream; if (stats != nullptr) { @@ -527,6 +531,7 @@ INSTANTIATE_TEST_SUITE_P( FramerateAdaptationTest::TestParamsToString); TEST(VideoCodecTest, DISABLED_EncodeDecode) { + const Environment env = CreateEnvironment(); std::vector bitrate_str = absl::GetFlag(FLAGS_bitrate_kbps); std::vector bitrate_kbps; std::transform(bitrate_str.begin(), bitrate_str.end(), @@ -544,7 +549,7 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) { // logged test name (implies lossing history in the chromeperf dashboard). // Sync with changes in Stream::LogMetrics (see TODOs there). std::unique_ptr stats = RunEncodeDecodeTest( - CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)), + env, CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)), CodecNameToCodecImpl(absl::GetFlag(FLAGS_decoder)), kRawVideos.at(absl::GetFlag(FLAGS_video_name)), frames_settings); ASSERT_NE(nullptr, stats); diff --git a/test/BUILD.gn b/test/BUILD.gn index 2a37b78c7c..d6b2b989ad 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -727,6 +727,8 @@ if (rtc_include_tests) { "../api:mock_video_encoder", "../api:scoped_refptr", "../api:simulcast_test_fixture_api", + "../api/environment", + "../api/environment:environment_factory", "../api/task_queue", "../api/task_queue:task_queue_test", "../api/test/video:function_video_factory", diff --git a/test/video_codec_tester.cc b/test/video_codec_tester.cc index f5fdc07a6b..37ae712f77 100644 --- a/test/video_codec_tester.cc +++ b/test/video_codec_tester.cc @@ -772,10 +772,12 @@ class VideoCodecAnalyzer : public VideoCodecTester::VideoCodecStats { class Decoder : public DecodedImageCallback { public: - Decoder(VideoDecoderFactory* decoder_factory, + Decoder(const Environment& env, + VideoDecoderFactory* decoder_factory, const DecoderSettings& decoder_settings, VideoCodecAnalyzer* analyzer) - : decoder_factory_(decoder_factory), + : env_(env), + decoder_factory_(decoder_factory), analyzer_(analyzer), pacer_(decoder_settings.pacing_settings) { RTC_CHECK(analyzer_) << "Analyzer must be provided"; @@ -792,7 +794,7 @@ class Decoder : public DecodedImageCallback { } void Initialize(const SdpVideoFormat& sdp_video_format) { - decoder_ = decoder_factory_->CreateVideoDecoder(sdp_video_format); + decoder_ = decoder_factory_->Create(env_, sdp_video_format); RTC_CHECK(decoder_) << "Could not create decoder for video format " << sdp_video_format.ToString(); @@ -863,6 +865,7 @@ class Decoder : public DecodedImageCallback { return WEBRTC_VIDEO_CODEC_OK; } + const Environment env_; VideoDecoderFactory* decoder_factory_; std::unique_ptr decoder_; VideoCodecAnalyzer* const analyzer_; @@ -1476,13 +1479,14 @@ std::map VideoCodecTester::CreateEncodingSettings( } std::unique_ptr -VideoCodecTester::RunDecodeTest(CodedVideoSource* video_source, +VideoCodecTester::RunDecodeTest(const Environment& env, + CodedVideoSource* video_source, VideoDecoderFactory* decoder_factory, const DecoderSettings& decoder_settings, const SdpVideoFormat& sdp_video_format) { std::unique_ptr analyzer = std::make_unique(/*video_source=*/nullptr); - Decoder decoder(decoder_factory, decoder_settings, analyzer.get()); + Decoder decoder(env, decoder_factory, decoder_settings, analyzer.get()); decoder.Initialize(sdp_video_format); while (auto frame = video_source->PullFrame()) { @@ -1522,6 +1526,7 @@ VideoCodecTester::RunEncodeTest( std::unique_ptr VideoCodecTester::RunEncodeDecodeTest( + const Environment& env, const VideoSourceSettings& source_settings, VideoEncoderFactory* encoder_factory, VideoDecoderFactory* decoder_factory, @@ -1539,8 +1544,8 @@ VideoCodecTester::RunEncodeDecodeTest( ScalabilityModeToNumSpatialLayers(frame_settings.scalability_mode); std::vector> decoders; for (int sidx = 0; sidx < num_spatial_layers; ++sidx) { - auto decoder = std::make_unique(decoder_factory, decoder_settings, - analyzer.get()); + auto decoder = std::make_unique(env, decoder_factory, + decoder_settings, analyzer.get()); decoder->Initialize(frame_settings.sdp_video_format); decoders.push_back(std::move(decoder)); } diff --git a/test/video_codec_tester.h b/test/video_codec_tester.h index 87cc5f76f8..00b6093dca 100644 --- a/test/video_codec_tester.h +++ b/test/video_codec_tester.h @@ -199,6 +199,7 @@ class VideoCodecTester { // Decodes video, collects and returns decode metrics. static std::unique_ptr RunDecodeTest( + const Environment& env, CodedVideoSource* video_source, VideoDecoderFactory* decoder_factory, const DecoderSettings& decoder_settings, @@ -213,6 +214,7 @@ class VideoCodecTester { // Encodes and decodes video, collects and returns encode and decode metrics. static std::unique_ptr RunEncodeDecodeTest( + const Environment& env, const VideoSourceSettings& source_settings, VideoEncoderFactory* encoder_factory, VideoDecoderFactory* decoder_factory, diff --git a/test/video_codec_tester_unittest.cc b/test/video_codec_tester_unittest.cc index df5dca90a2..ad1e9e3b03 100644 --- a/test/video_codec_tester_unittest.cc +++ b/test/video_codec_tester_unittest.cc @@ -17,6 +17,8 @@ #include #include +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/test/mock_video_decoder.h" #include "api/test/mock_video_decoder_factory.h" #include "api/test/mock_video_encoder.h" @@ -44,13 +46,12 @@ namespace { using ::testing::_; using ::testing::ElementsAre; using ::testing::Field; -using ::testing::Invoke; -using ::testing::InvokeWithoutArgs; using ::testing::NiceMock; using ::testing::Return; using ::testing::SizeIs; using ::testing::UnorderedElementsAreArray; using ::testing::Values; +using ::testing::WithoutArgs; using VideoCodecStats = VideoCodecTester::VideoCodecStats; using VideoSourceSettings = VideoCodecTester::VideoSourceSettings; @@ -200,30 +201,27 @@ class VideoCodecTesterTest : public ::testing::Test { }); NiceMock decoder_factory; - ON_CALL(decoder_factory, CreateVideoDecoder) - .WillByDefault([&](const SdpVideoFormat&) { - // Video codec tester destroyes decoder at the end of test. Test - // decoder collects stats which we need to access after test. To keep - // the decode alive we wrap it into a wrapper and pass the wrapper to - // the tester. - class DecoderWrapper : public TestVideoDecoder { - public: - explicit DecoderWrapper(TestVideoDecoder* decoder) - : decoder_(decoder) {} - int32_t Decode(const EncodedImage& encoded_frame, - int64_t render_time_ms) { - return decoder_->Decode(encoded_frame, render_time_ms); - } - int32_t RegisterDecodeCompleteCallback( - DecodedImageCallback* callback) { - return decoder_->RegisterDecodeCompleteCallback(callback); - } - TestVideoDecoder* decoder_; - }; - decoders_.push_back(std::make_unique>()); - return std::make_unique>( - decoders_.back().get()); - }); + ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([&] { + // Video codec tester destroyes decoder at the end of test. Test + // decoder collects stats which we need to access after test. To keep + // the decode alive we wrap it into a wrapper and pass the wrapper to + // the tester. + class DecoderWrapper : public TestVideoDecoder { + public: + explicit DecoderWrapper(TestVideoDecoder* decoder) + : decoder_(decoder) {} + int32_t Decode(const EncodedImage& encoded_frame, + int64_t render_time_ms) { + return decoder_->Decode(encoded_frame, render_time_ms); + } + int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) { + return decoder_->RegisterDecodeCompleteCallback(callback); + } + TestVideoDecoder* decoder_; + }; + decoders_.push_back(std::make_unique>()); + return std::make_unique>(decoders_.back().get()); + })); int num_spatial_layers = ScalabilityModeToNumSpatialLayers(scalability_mode); @@ -252,7 +250,7 @@ class VideoCodecTesterTest : public ::testing::Test { std::unique_ptr stats = VideoCodecTester::RunEncodeDecodeTest( - video_source_settings, &encoder_factory, &decoder_factory, + env_, video_source_settings, &encoder_factory, &decoder_factory, EncoderSettings{}, DecoderSettings{}, encoding_settings); remove(yuv_path.c_str()); @@ -260,6 +258,7 @@ class VideoCodecTesterTest : public ::testing::Test { } protected: + const Environment env_ = CreateEnvironment(); std::vector> decoders_; }; @@ -605,6 +604,7 @@ class VideoCodecTesterTestPacing void TearDown() override { remove(source_yuv_file_path_.c_str()); } protected: + const Environment env_ = CreateEnvironment(); std::string source_yuv_file_path_; }; @@ -644,15 +644,14 @@ TEST_P(VideoCodecTesterTestPacing, PaceDecode) { MockCodedVideoSource video_source(kNumFrames, kTargetFramerate); NiceMock decoder_factory; - ON_CALL(decoder_factory, CreateVideoDecoder(_)) - .WillByDefault([](const SdpVideoFormat&) { - return std::make_unique>(); - }); + ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([] { + return std::make_unique>(); + })); DecoderSettings decoder_settings; decoder_settings.pacing_settings = pacing_settings; std::vector frames = - VideoCodecTester::RunDecodeTest(&video_source, &decoder_factory, + VideoCodecTester::RunDecodeTest(env_, &video_source, &decoder_factory, decoder_settings, SdpVideoFormat("VP8")) ->Slice(/*filter=*/{}, /*merge=*/false); ASSERT_THAT(frames, SizeIs(kNumFrames)); From 9a953b28f96a03cc1b95ddff7e167700f4279d34 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Fri, 26 Jan 2024 07:11:50 +0000 Subject: [PATCH 022/170] Detangle p2p/connection.cc and port.cc This CL does: - Run IWYU on the relevant elements - Make connection depend on port_interface, not port - Make port_allocator depend only on port - Move some constants from port.h into p2p_constants This allows a dependency graph without ugly groups. Bug: webrtc:15796 Change-Id: I0ff0e14eacdfe3b230a8d84902a78eb062d6c8af Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336320 Commit-Queue: Harald Alvestrand Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41618} --- api/BUILD.gn | 4 +- api/test/pclf/BUILD.gn | 2 +- examples/BUILD.gn | 2 +- p2p/BUILD.gn | 136 ++++++++++++++++++++++++---- p2p/base/candidate_pair_interface.h | 12 +++ p2p/base/connection.cc | 19 ++-- p2p/base/connection.h | 44 ++++----- p2p/base/p2p_constants.h | 13 +++ p2p/base/p2p_transport_channel.cc | 2 +- p2p/base/p2p_transport_channel.h | 2 +- p2p/base/port.cc | 17 ++-- p2p/base/port.h | 72 +++++++-------- p2p/base/port_allocator.cc | 2 +- p2p/base/port_allocator.h | 8 ++ p2p/base/port_interface.h | 75 +++++++++++++++ pc/BUILD.gn | 28 +++--- 16 files changed, 327 insertions(+), 111 deletions(-) diff --git a/api/BUILD.gn b/api/BUILD.gn index cb23ea32cf..08e33ca92e 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -334,7 +334,7 @@ rtc_library("libjingle_peerconnection_api") { ":sequence_checker", ":turn_customizer", "../call:rtp_interfaces", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:rtc_p2p", "../pc:media_factory", "../rtc_base:copy_on_write_buffer", @@ -936,7 +936,7 @@ rtc_library("ice_transport_factory") { ":make_ref_counted", ":packet_socket_factory", ":scoped_refptr", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", diff --git a/api/test/pclf/BUILD.gn b/api/test/pclf/BUILD.gn index 6d1d2bef5d..20d7077449 100644 --- a/api/test/pclf/BUILD.gn +++ b/api/test/pclf/BUILD.gn @@ -74,7 +74,7 @@ rtc_library("media_quality_test_params") { "../../../api/transport:network_control", "../../../api/video_codecs:video_codecs_api", "../../../modules/audio_processing:api", - "../../../p2p:connection_and_port", + "../../../p2p:connection", "../../../p2p:rtc_p2p", "../../../rtc_base:network", "../../../rtc_base:rtc_certificate_generator", diff --git a/examples/BUILD.gn b/examples/BUILD.gn index 991f9d8686..c3f66e0b98 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -702,7 +702,7 @@ if (is_linux || is_chromeos || is_win) { "../api/video_codecs:video_codecs_api", "../media:media_channel", "../media:rtc_media_base", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:rtc_p2p", "../pc:video_track_source", "../rtc_base:async_dns_resolver", diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn index 140bf215c6..8a5c8df065 100644 --- a/p2p/BUILD.gn +++ b/p2p/BUILD.gn @@ -74,7 +74,7 @@ rtc_library("rtc_p2p") { ":basic_async_resolver_factory", ":basic_ice_controller", ":candidate_pair_interface", - ":connection_and_port", + ":connection", ":connection_info", ":ice_agent_interface", ":ice_controller_factory_interface", @@ -169,6 +169,7 @@ rtc_library("rtc_p2p") { absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", "//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/strings", "//third_party/abseil-cpp/absl/types:optional", @@ -187,7 +188,7 @@ rtc_source_set("active_ice_controller_factory_interface") { rtc_source_set("active_ice_controller_interface") { sources = [ "base/active_ice_controller_interface.h" ] deps = [ - ":connection_and_port", + ":connection", ":ice_switch_reason", ":ice_transport_internal", ":transport_description", @@ -248,14 +249,10 @@ rtc_source_set("candidate_pair_interface") { # This set of files is too intertwined to break into separate # targets at this point. # TODO(bugs.webrtc.org/15796): Finish breakup -rtc_library("connection_and_port") { +rtc_library("connection") { sources = [ "base/connection.cc", "base/connection.h", - "base/port.cc", - "base/port.h", - "base/port_allocator.cc", - "base/port_allocator.h", ] deps = [ ":candidate_pair_interface", @@ -276,28 +273,37 @@ rtc_library("connection_and_port") { "../api/transport:enums", "../api/transport:field_trial_based_config", "../api/transport:stun_types", + "../api/units:time_delta", "../api/units:timestamp", "../logging:ice_log", "../rtc_base:async_packet_socket", + "../rtc_base:byte_buffer", "../rtc_base:callback_list", "../rtc_base:checks", "../rtc_base:crc32", + "../rtc_base:dscp", "../rtc_base:event_tracer", + "../rtc_base:ip_address", "../rtc_base:logging", + "../rtc_base:macromagic", "../rtc_base:mdns_responder_interface", "../rtc_base:net_helper", "../rtc_base:network", + "../rtc_base:network_constants", "../rtc_base:proxy_info", "../rtc_base:rate_tracker", "../rtc_base:rtc_numerics", "../rtc_base:safe_minmax", + "../rtc_base:socket", "../rtc_base:socket_address", "../rtc_base:ssl", "../rtc_base:stringutils", "../rtc_base:threading", + "../rtc_base:timeutils", "../rtc_base:weak_ptr", "../rtc_base/memory:always_valid_pointer", "../rtc_base/network:received_packet", + "../rtc_base/network:sent_packet", "../rtc_base/system:rtc_export", "../rtc_base/third_party/base64", "../rtc_base/third_party/sigslot", @@ -305,6 +311,7 @@ rtc_library("connection_and_port") { absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", "//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/strings", "//third_party/abseil-cpp/absl/strings:string_view", @@ -327,7 +334,7 @@ rtc_library("connection_info") { rtc_source_set("ice_agent_interface") { sources = [ "base/ice_agent_interface.h" ] deps = [ - ":connection_and_port", + ":connection", ":ice_switch_reason", "../api:array_view", ] @@ -339,7 +346,7 @@ rtc_library("ice_controller_interface") { "base/ice_controller_interface.h", ] deps = [ - ":connection_and_port", + ":connection", ":ice_switch_reason", ":ice_transport_internal", "../rtc_base:checks", @@ -382,9 +389,10 @@ rtc_library("ice_transport_internal") { "base/ice_transport_internal.h", ] deps = [ - ":connection_and_port", + ":connection", ":p2p_constants", ":packet_transport_internal", + ":port", ":stun_dictionary", ":transport_description", "../api:candidate", @@ -418,7 +426,7 @@ rtc_library("p2p_transport_channel") { ":active_ice_controller_factory_interface", ":basic_ice_controller", ":candidate_pair_interface", - ":connection_and_port", + ":connection", ":connection_info", ":ice_agent_interface", ":ice_controller_factory_interface", @@ -427,6 +435,8 @@ rtc_library("p2p_transport_channel") { ":ice_transport_internal", ":p2p_constants", ":p2p_transport_channel_ice_field_trials", + ":port", + ":port_allocator", ":port_interface", ":regathering_controller", ":stun_dictionary", @@ -487,7 +497,8 @@ rtc_library("packet_transport_internal") { "base/packet_transport_internal.h", ] deps = [ - ":connection_and_port", + ":connection", + ":port", "../rtc_base:async_packet_socket", "../rtc_base:network_route", "../rtc_base:socket", @@ -497,6 +508,94 @@ rtc_library("packet_transport_internal") { absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } +rtc_library("port") { + sources = [ + "base/port.cc", + "base/port.h", + ] + deps = [ + ":candidate_pair_interface", + ":connection", + ":connection_info", + ":p2p_constants", + ":port_interface", + ":stun_request", + ":transport_description", + "../api:array_view", + "../api:candidate", + "../api:field_trials_view", + "../api:packet_socket_factory", + "../api:rtc_error", + "../api:sequence_checker", + "../api/task_queue", + "../api/transport:field_trial_based_config", + "../api/transport:stun_types", + "../api/units:time_delta", + "../logging:ice_log", + "../rtc_base:async_packet_socket", + "../rtc_base:byte_buffer", + "../rtc_base:callback_list", + "../rtc_base:checks", + "../rtc_base:crc32", + "../rtc_base:dscp", + "../rtc_base:event_tracer", + "../rtc_base:ip_address", + "../rtc_base:logging", + "../rtc_base:macromagic", + "../rtc_base:mdns_responder_interface", + "../rtc_base:net_helper", + "../rtc_base:network", + "../rtc_base:proxy_info", + "../rtc_base:rate_tracker", + "../rtc_base:socket_address", + "../rtc_base:ssl", + "../rtc_base:stringutils", + "../rtc_base:timeutils", + "../rtc_base:weak_ptr", + "../rtc_base/memory:always_valid_pointer", + "../rtc_base/network:received_packet", + "../rtc_base/network:sent_packet", + "../rtc_base/system:rtc_export", + "../rtc_base/third_party/sigslot", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_library("port_allocator") { + sources = [ + "base/port_allocator.cc", + "base/port_allocator.h", + ] + deps = [ + ":connection", + ":ice_credentials_iterator", + ":port", + ":port_interface", + ":transport_description", + "../api:candidate", + "../api:sequence_checker", + "../api/transport:enums", + "../rtc_base:checks", + "../rtc_base:network", + "../rtc_base:proxy_info", + "../rtc_base:socket_address", + "../rtc_base:ssl", + "../rtc_base:threading", + "../rtc_base/system:rtc_export", + "../rtc_base/third_party/sigslot", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + rtc_library("port_interface") { sources = [ "base/port_interface.cc", @@ -505,8 +604,10 @@ rtc_library("port_interface") { deps = [ ":transport_description", "../api:candidate", + "../api:packet_socket_factory", "../rtc_base:async_packet_socket", "../rtc_base:callback_list", + "../rtc_base:proxy_info", "../rtc_base:socket_address", ] absl_deps = [ @@ -521,8 +622,9 @@ rtc_library("regathering_controller") { "base/regathering_controller.h", ] deps = [ - ":connection_and_port", + ":connection", ":ice_transport_internal", + ":port_allocator", "../api/task_queue:pending_task_safety_flag", "../api/units:time_delta", "../rtc_base:threading", @@ -590,7 +692,7 @@ rtc_library("wrapping_active_ice_controller") { deps = [ ":active_ice_controller_interface", ":basic_ice_controller", - ":connection_and_port", + ":connection", ":ice_agent_interface", ":ice_controller_factory_interface", ":ice_controller_interface", @@ -634,7 +736,7 @@ if (rtc_include_tests) { visibility = [ "*" ] sources = [ "base/fake_port_allocator.h" ] deps = [ - ":connection_and_port", + ":connection", ":rtc_p2p", "../rtc_base:net_helpers", "../rtc_base:net_test_helpers", @@ -663,7 +765,7 @@ if (rtc_include_tests) { deps = [ ":active_ice_controller_factory_interface", ":active_ice_controller_interface", - ":connection_and_port", + ":connection", ":fake_ice_transport", ":fake_port_allocator", ":ice_agent_interface", @@ -731,7 +833,7 @@ if (rtc_include_tests) { ":active_ice_controller_interface", ":async_stun_tcp_socket", ":basic_ice_controller", - ":connection_and_port", + ":connection", ":fake_ice_transport", ":fake_port_allocator", ":ice_credentials_iterator", diff --git a/p2p/base/candidate_pair_interface.h b/p2p/base/candidate_pair_interface.h index 2b68fd7ea9..a04ab130cf 100644 --- a/p2p/base/candidate_pair_interface.h +++ b/p2p/base/candidate_pair_interface.h @@ -23,6 +23,18 @@ class CandidatePairInterface { virtual const Candidate& remote_candidate() const = 0; }; +// Specific implementation of the interface, suitable for being a +// data member of other structs. +struct CandidatePair final : public CandidatePairInterface { + ~CandidatePair() override = default; + + const Candidate& local_candidate() const override { return local; } + const Candidate& remote_candidate() const override { return remote; } + + Candidate local; + Candidate remote; +}; + } // namespace cricket #endif // P2P_BASE_CANDIDATE_PAIR_INTERFACE_H_ diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc index bf07dec607..9dd8a80631 100644 --- a/p2p/base/connection.cc +++ b/p2p/base/connection.cc @@ -19,25 +19,26 @@ #include #include "absl/algorithm/container.h" -#include "absl/strings/escaping.h" -#include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" #include "api/units/timestamp.h" -#include "p2p/base/port_allocator.h" +#include "p2p/base/p2p_constants.h" +#include "rtc_base/byte_buffer.h" #include "rtc_base/checks.h" -#include "rtc_base/crc32.h" #include "rtc_base/helpers.h" #include "rtc_base/logging.h" -#include "rtc_base/mdns_responder_interface.h" -#include "rtc_base/message_digest.h" +#include "rtc_base/net_helper.h" #include "rtc_base/network.h" +#include "rtc_base/network/sent_packet.h" +#include "rtc_base/network_constants.h" #include "rtc_base/numerics/safe_minmax.h" +#include "rtc_base/socket.h" +#include "rtc_base/socket_address.h" #include "rtc_base/string_encode.h" #include "rtc_base/string_utils.h" #include "rtc_base/strings/string_builder.h" -#include "rtc_base/third_party/base64/base64.h" +#include "rtc_base/time_utils.h" namespace cricket { namespace { @@ -213,7 +214,7 @@ int Connection::ConnectionRequest::resend_delay() { return CONNECTION_RESPONSE_TIMEOUT; } -Connection::Connection(rtc::WeakPtr port, +Connection::Connection(rtc::WeakPtr port, size_t index, const Candidate& remote_candidate) : network_thread_(port->thread()), @@ -1784,7 +1785,7 @@ void Connection::ForgetLearnedState() { pings_since_last_response_.clear(); } -ProxyConnection::ProxyConnection(rtc::WeakPtr port, +ProxyConnection::ProxyConnection(rtc::WeakPtr port, size_t index, const Candidate& remote_candidate) : Connection(std::move(port), index, remote_candidate) {} diff --git a/p2p/base/connection.h b/p2p/base/connection.h index cf54dc800f..583e62e264 100644 --- a/p2p/base/connection.h +++ b/p2p/base/connection.h @@ -11,19 +11,31 @@ #ifndef P2P_BASE_CONNECTION_H_ #define P2P_BASE_CONNECTION_H_ +#include + +#include +#include #include #include +#include #include #include +#include "absl/functional/any_invocable.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/candidate.h" +#include "api/rtc_error.h" +#include "api/sequence_checker.h" +#include "api/task_queue/task_queue_base.h" #include "api/transport/stun.h" +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h" +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h" #include "logging/rtc_event_log/ice_logger.h" #include "p2p/base/candidate_pair_interface.h" #include "p2p/base/connection_info.h" #include "p2p/base/p2p_transport_channel_ice_field_trials.h" +#include "p2p/base/port_interface.h" #include "p2p/base/stun_request.h" #include "p2p/base/transport_description.h" #include "rtc_base/async_packet_socket.h" @@ -32,6 +44,8 @@ #include "rtc_base/numerics/event_based_exponential_moving_average.h" #include "rtc_base/rate_tracker.h" #include "rtc_base/system/rtc_export.h" +#include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/thread_annotations.h" #include "rtc_base/weak_ptr.h" namespace cricket { @@ -40,23 +54,9 @@ namespace cricket { // adding other flavors in the future. constexpr int kGoogPingVersion = 1; -// Connection and Port has circular dependencies. -// So we use forward declaration rather than include. -class Port; - // Forward declaration so that a ConnectionRequest can contain a Connection. class Connection; -struct CandidatePair final : public CandidatePairInterface { - ~CandidatePair() override = default; - - const Candidate& local_candidate() const override { return local; } - const Candidate& remote_candidate() const override { return remote; } - - Candidate local; - Candidate remote; -}; - // Represents a communication link between a port on the local client and a // port on the remote client. class RTC_EXPORT Connection : public CandidatePairInterface { @@ -102,7 +102,7 @@ class RTC_EXPORT Connection : public CandidatePairInterface { bool writable() const; bool receiving() const; - const Port* port() const { + const PortInterface* port() const { RTC_DCHECK_RUN_ON(network_thread_); return port_.get(); } @@ -326,8 +326,8 @@ class RTC_EXPORT Connection : public CandidatePairInterface { void SendResponseMessage(const StunMessage& response); // An accessor for unit tests. - Port* PortForTest() { return port_.get(); } - const Port* PortForTest() const { return port_.get(); } + PortInterface* PortForTest() { return port_.get(); } + const PortInterface* PortForTest() const { return port_.get(); } std::unique_ptr BuildPingRequestForTest() { RTC_DCHECK_RUN_ON(network_thread_); @@ -364,7 +364,9 @@ class RTC_EXPORT Connection : public CandidatePairInterface { class ConnectionRequest; // Constructs a new connection to the given remote port. - Connection(rtc::WeakPtr port, size_t index, const Candidate& candidate); + Connection(rtc::WeakPtr port, + size_t index, + const Candidate& candidate); // Called back when StunRequestManager has a stun packet to send void OnSendStunPacket(const void* data, size_t size, StunRequest* req); @@ -393,7 +395,7 @@ class RTC_EXPORT Connection : public CandidatePairInterface { void set_connected(bool value); // The local port where this connection sends and receives packets. - Port* port() { return port_.get(); } + PortInterface* port() { return port_.get(); } // NOTE: A pointer to the network thread is held by `port_` so in theory we // shouldn't need to hold on to this pointer here, but rather defer to @@ -402,7 +404,7 @@ class RTC_EXPORT Connection : public CandidatePairInterface { // TODO(tommi): This ^^^ should be fixed. webrtc::TaskQueueBase* const network_thread_; const uint32_t id_; - rtc::WeakPtr port_; + rtc::WeakPtr port_; Candidate local_candidate_ RTC_GUARDED_BY(network_thread_); Candidate remote_candidate_; @@ -515,7 +517,7 @@ class RTC_EXPORT Connection : public CandidatePairInterface { // ProxyConnection defers all the interesting work to the port. class ProxyConnection : public Connection { public: - ProxyConnection(rtc::WeakPtr port, + ProxyConnection(rtc::WeakPtr port, size_t index, const Candidate& remote_candidate); diff --git a/p2p/base/p2p_constants.h b/p2p/base/p2p_constants.h index 3af00bbc2e..c5a2b7058d 100644 --- a/p2p/base/p2p_constants.h +++ b/p2p/base/p2p_constants.h @@ -111,6 +111,19 @@ extern const int CONNECTION_RESPONSE_TIMEOUT; // it. extern const int MIN_CONNECTION_LIFETIME; +// The type preference MUST be an integer from 0 to 126 inclusive. +// https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.2.1 +enum IcePriorityValue : uint8_t { + ICE_TYPE_PREFERENCE_RELAY_TLS = 0, + ICE_TYPE_PREFERENCE_RELAY_TCP = 1, + ICE_TYPE_PREFERENCE_RELAY_UDP = 2, + ICE_TYPE_PREFERENCE_PRFLX_TCP = 80, + ICE_TYPE_PREFERENCE_HOST_TCP = 90, + ICE_TYPE_PREFERENCE_SRFLX = 100, + ICE_TYPE_PREFERENCE_PRFLX = 110, + ICE_TYPE_PREFERENCE_HOST = 126 +}; + } // namespace cricket #endif // P2P_BASE_P2P_CONSTANTS_H_ diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc index 35d7f85d69..0bccb67209 100644 --- a/p2p/base/p2p_transport_channel.cc +++ b/p2p/base/p2p_transport_channel.cc @@ -1693,7 +1693,7 @@ void P2PTransportChannel::OnStartedPinging() { regathering_controller_->Start(); } -bool P2PTransportChannel::IsPortPruned(const Port* port) const { +bool P2PTransportChannel::IsPortPruned(const PortInterface* port) const { RTC_DCHECK_RUN_ON(network_thread_); return !absl::c_linear_search(ports_, port); } diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h index 6413d2dc64..da7933f2e7 100644 --- a/p2p/base/p2p_transport_channel.h +++ b/p2p/base/p2p_transport_channel.h @@ -370,7 +370,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal, } // Indicates if the given local port has been pruned. - bool IsPortPruned(const Port* port) const; + bool IsPortPruned(const PortInterface* port) const; // Indicates if the given remote candidate has been pruned. bool IsRemoteCandidatePruned(const Candidate& cand) const; diff --git a/p2p/base/port.cc b/p2p/base/port.cc index 1289d17d76..aacfef0ede 100644 --- a/p2p/base/port.cc +++ b/p2p/base/port.cc @@ -10,31 +10,34 @@ #include "p2p/base/port.h" -#include - -#include #include +#include #include #include #include -#include "absl/algorithm/container.h" #include "absl/memory/memory.h" #include "absl/strings/match.h" #include "absl/strings/string_view.h" +#include "api/array_view.h" +#include "api/rtc_error.h" +#include "api/units/time_delta.h" +#include "p2p/base/p2p_constants.h" +#include "p2p/base/stun_request.h" +#include "rtc_base/byte_buffer.h" #include "rtc_base/checks.h" #include "rtc_base/crc32.h" #include "rtc_base/helpers.h" +#include "rtc_base/ip_address.h" #include "rtc_base/logging.h" #include "rtc_base/mdns_responder_interface.h" -#include "rtc_base/message_digest.h" +#include "rtc_base/net_helper.h" #include "rtc_base/network.h" -#include "rtc_base/numerics/safe_minmax.h" #include "rtc_base/socket_address.h" #include "rtc_base/string_encode.h" #include "rtc_base/string_utils.h" #include "rtc_base/strings/string_builder.h" -#include "rtc_base/third_party/base64/base64.h" +#include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" namespace cricket { diff --git a/p2p/base/port.h b/p2p/base/port.h index 7b44e534de..e0fccd3907 100644 --- a/p2p/base/port.h +++ b/p2p/base/port.h @@ -11,10 +11,15 @@ #ifndef P2P_BASE_PORT_H_ #define P2P_BASE_PORT_H_ +#include +#include + +#include #include #include #include #include +#include #include #include @@ -25,6 +30,7 @@ #include "api/field_trials_view.h" #include "api/packet_socket_factory.h" #include "api/rtc_error.h" +#include "api/sequence_checker.h" #include "api/task_queue/task_queue_base.h" #include "api/transport/field_trial_based_config.h" #include "api/transport/stun.h" @@ -37,18 +43,22 @@ #include "p2p/base/p2p_constants.h" #include "p2p/base/port_interface.h" #include "p2p/base/stun_request.h" +#include "p2p/base/transport_description.h" #include "rtc_base/async_packet_socket.h" #include "rtc_base/callback_list.h" #include "rtc_base/checks.h" +#include "rtc_base/dscp.h" #include "rtc_base/memory/always_valid_pointer.h" #include "rtc_base/net_helper.h" #include "rtc_base/network.h" #include "rtc_base/network/received_packet.h" +#include "rtc_base/network/sent_packet.h" #include "rtc_base/proxy_info.h" #include "rtc_base/rate_tracker.h" #include "rtc_base/socket_address.h" #include "rtc_base/system/rtc_export.h" #include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/thread_annotations.h" #include "rtc_base/weak_ptr.h" namespace cricket { @@ -59,19 +69,6 @@ extern const char TCPTYPE_ACTIVE_STR[]; extern const char TCPTYPE_PASSIVE_STR[]; extern const char TCPTYPE_SIMOPEN_STR[]; -// The type preference MUST be an integer from 0 to 126 inclusive. -// https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.2.1 -enum IcePriorityValue : uint8_t { - ICE_TYPE_PREFERENCE_RELAY_TLS = 0, - ICE_TYPE_PREFERENCE_RELAY_TCP = 1, - ICE_TYPE_PREFERENCE_RELAY_UDP = 2, - ICE_TYPE_PREFERENCE_PRFLX_TCP = 80, - ICE_TYPE_PREFERENCE_HOST_TCP = 90, - ICE_TYPE_PREFERENCE_SRFLX = 100, - ICE_TYPE_PREFERENCE_PRFLX = 110, - ICE_TYPE_PREFERENCE_HOST = 126 -}; - enum class MdnsNameRegistrationStatus { // IP concealment with mDNS is not enabled or the name registration process is // not started yet. @@ -227,13 +224,13 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { void CancelPendingTasks(); // The thread on which this port performs its I/O. - webrtc::TaskQueueBase* thread() { return thread_; } + webrtc::TaskQueueBase* thread() override { return thread_; } // The factory used to create the sockets of this port. - rtc::PacketSocketFactory* socket_factory() const { return factory_; } + rtc::PacketSocketFactory* socket_factory() const override { return factory_; } // For debugging purposes. - const std::string& content_name() const { return content_name_; } + const std::string& content_name() const override { return content_name_; } void set_content_name(absl::string_view content_name) { content_name_ = std::string(content_name); } @@ -241,7 +238,7 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { int component() const { return component_; } void set_component(int component) { component_ = component; } - bool send_retransmit_count_attribute() const { + bool send_retransmit_count_attribute() const override { return send_retransmit_count_attribute_; } void set_send_retransmit_count_attribute(bool enable) { @@ -249,8 +246,10 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { } // Identifies the generation that this port was created in. - uint32_t generation() const { return generation_; } - void set_generation(uint32_t generation) { generation_ = generation; } + uint32_t generation() const override { return generation_; } + void set_generation(uint32_t generation) override { + generation_ = generation; + } const std::string& username_fragment() const; const std::string& password() const { return password_; } @@ -296,11 +295,11 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { // defers the `delete` operation to when the call stack has been unwound. // Async may be needed when deleting a connection object from within a // callback. - void DestroyConnection(Connection* conn) { + void DestroyConnection(Connection* conn) override { DestroyConnectionInternal(conn, false); } - void DestroyConnectionAsync(Connection* conn) { + void DestroyConnectionAsync(Connection* conn) override { DestroyConnectionInternal(conn, true); } @@ -330,8 +329,8 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { user_agent_ = std::string(user_agent); proxy_ = proxy; } - const std::string& user_agent() { return user_agent_; } - const rtc::ProxyInfo& proxy() { return proxy_; } + const std::string& user_agent() override { return user_agent_; } + const rtc::ProxyInfo& proxy() override { return proxy_; } void EnablePortPackets() override; @@ -350,12 +349,13 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { // stun username attribute if present. bool ParseStunUsername(const StunMessage* stun_msg, std::string* local_username, - std::string* remote_username) const; - std::string CreateStunUsername(absl::string_view remote_username) const; + std::string* remote_username) const override; + std::string CreateStunUsername( + absl::string_view remote_username) const override; bool MaybeIceRoleConflict(const rtc::SocketAddress& addr, IceMessage* stun_msg, - absl::string_view remote_ufrag); + absl::string_view remote_ufrag) override; // Called when a packet has been sent to the socket. // This is made pure virtual to notify subclasses of Port that they MUST @@ -368,9 +368,9 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { void OnReadyToSend(); // Called when the Connection discovers a local peer reflexive candidate. - void AddPrflxCandidate(const Candidate& local); + void AddPrflxCandidate(const Candidate& local) override; - int16_t network_cost() const { return network_cost_; } + int16_t network_cost() const override { return network_cost_; } void GetStunStats(absl::optional* stats) override {} @@ -380,13 +380,14 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { // then the foundation will be different. Two candidate pairs with // the same foundation pairs are likely to have similar network // characteristics. Foundations are used in the frozen algorithm. - std::string ComputeFoundation(absl::string_view type, - absl::string_view protocol, - absl::string_view relay_protocol, - const rtc::SocketAddress& base_address); + std::string ComputeFoundation( + absl::string_view type, + absl::string_view protocol, + absl::string_view relay_protocol, + const rtc::SocketAddress& base_address) override; protected: - virtual void UpdateNetworkCost(); + void UpdateNetworkCost() override; rtc::WeakPtr NewWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -438,13 +439,13 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { size_t size, const rtc::SocketAddress& addr, std::unique_ptr* out_msg, - std::string* out_username); + std::string* out_username) override; // Checks if the address in addr is compatible with the port's ip. bool IsCompatibleAddress(const rtc::SocketAddress& addr); // Returns DSCP value packets generated by the port itself should use. - virtual rtc::DiffServCodePoint StunDscpValue() const; + rtc::DiffServCodePoint StunDscpValue() const override; // Extra work to be done in subclasses when a connection is destroyed. virtual void HandleConnectionDestroyed(Connection* conn) {} @@ -528,7 +529,6 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { absl::string_view type, bool is_final) RTC_RUN_ON(thread_); - friend class Connection; webrtc::CallbackList port_destroyed_callback_list_; }; diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc index 16f5afe36c..3745717510 100644 --- a/p2p/base/port_allocator.cc +++ b/p2p/base/port_allocator.cc @@ -11,13 +11,13 @@ #include "p2p/base/port_allocator.h" #include +#include #include #include #include "absl/strings/string_view.h" #include "p2p/base/ice_credentials_iterator.h" #include "rtc_base/checks.h" -#include "rtc_base/logging.h" namespace cricket { diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h index 11462f78f2..b8cffca9c0 100644 --- a/p2p/base/port_allocator.h +++ b/p2p/base/port_allocator.h @@ -11,18 +11,26 @@ #ifndef P2P_BASE_PORT_ALLOCATOR_H_ #define P2P_BASE_PORT_ALLOCATOR_H_ +#include + #include #include #include #include #include "absl/strings/string_view.h" +#include "absl/types/optional.h" +#include "api/candidate.h" #include "api/sequence_checker.h" #include "api/transport/enums.h" #include "p2p/base/port.h" #include "p2p/base/port_interface.h" +#include "p2p/base/transport_description.h" +#include "rtc_base/checks.h" #include "rtc_base/helpers.h" +#include "rtc_base/network.h" #include "rtc_base/proxy_info.h" +#include "rtc_base/socket_address.h" #include "rtc_base/ssl_certificate.h" #include "rtc_base/system/rtc_export.h" #include "rtc_base/third_party/sigslot/sigslot.h" diff --git a/p2p/base/port_interface.h b/p2p/base/port_interface.h index fe4b204c95..fb8023b5dd 100644 --- a/p2p/base/port_interface.h +++ b/p2p/base/port_interface.h @@ -11,6 +11,7 @@ #ifndef P2P_BASE_PORT_INTERFACE_H_ #define P2P_BASE_PORT_INTERFACE_H_ +#include #include #include #include @@ -18,9 +19,11 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/candidate.h" +#include "api/packet_socket_factory.h" #include "p2p/base/transport_description.h" #include "rtc_base/async_packet_socket.h" #include "rtc_base/callback_list.h" +#include "rtc_base/proxy_info.h" #include "rtc_base/socket_address.h" namespace rtc { @@ -137,8 +140,80 @@ class PortInterface { virtual void GetStunStats(absl::optional* stats) = 0; + // Removes and deletes a connection object. `DestroyConnection` will + // delete the connection object directly whereas `DestroyConnectionAsync` + // defers the `delete` operation to when the call stack has been unwound. + // Async may be needed when deleting a connection object from within a + // callback. + virtual void DestroyConnection(Connection* conn) = 0; + + virtual void DestroyConnectionAsync(Connection* conn) = 0; + + // The thread on which this port performs its I/O. + virtual webrtc::TaskQueueBase* thread() = 0; + + // The factory used to create the sockets of this port. + virtual rtc::PacketSocketFactory* socket_factory() const = 0; + virtual const std::string& user_agent() = 0; + virtual const rtc::ProxyInfo& proxy() = 0; + + // Identifies the generation that this port was created in. + virtual uint32_t generation() const = 0; + virtual void set_generation(uint32_t generation) = 0; + virtual bool send_retransmit_count_attribute() const = 0; + // For debugging purposes. + virtual const std::string& content_name() const = 0; + + // Called when the Connection discovers a local peer reflexive candidate. + virtual void AddPrflxCandidate(const Candidate& local) = 0; + + // Foundation: An arbitrary string that is the same for two candidates + // that have the same type, base IP address, protocol (UDP, TCP, + // etc.), and STUN or TURN server. If any of these are different, + // then the foundation will be different. Two candidate pairs with + // the same foundation pairs are likely to have similar network + // characteristics. Foundations are used in the frozen algorithm. + virtual std::string ComputeFoundation( + absl::string_view type, + absl::string_view protocol, + absl::string_view relay_protocol, + const rtc::SocketAddress& base_address) = 0; + protected: PortInterface(); + virtual void UpdateNetworkCost() = 0; + + // Returns DSCP value packets generated by the port itself should use. + virtual rtc::DiffServCodePoint StunDscpValue() const = 0; + + // If the given data comprises a complete and correct STUN message then the + // return value is true, otherwise false. If the message username corresponds + // with this port's username fragment, msg will contain the parsed STUN + // message. Otherwise, the function may send a STUN response internally. + // remote_username contains the remote fragment of the STUN username. + virtual bool GetStunMessage(const char* data, + size_t size, + const rtc::SocketAddress& addr, + std::unique_ptr* out_msg, + std::string* out_username) = 0; + + // This method will return local and remote username fragements from the + // stun username attribute if present. + virtual bool ParseStunUsername(const StunMessage* stun_msg, + std::string* local_username, + std::string* remote_username) const = 0; + virtual std::string CreateStunUsername( + absl::string_view remote_username) const = 0; + + virtual bool MaybeIceRoleConflict(const rtc::SocketAddress& addr, + IceMessage* stun_msg, + absl::string_view remote_ufrag) = 0; + + virtual int16_t network_cost() const = 0; + + // Connection and Port are entangled; functions exposed to Port only + // should not be public. + friend class Connection; }; } // namespace cricket diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 1f814cb1aa..a426e9b8c5 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -301,7 +301,7 @@ rtc_source_set("jsep_transport_controller") { "../api/transport:enums", "../api/transport:sctp_transport_factory_interface", "../media:rtc_data_sctp_transport_internal", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", @@ -654,7 +654,7 @@ rtc_source_set("transport_stats") { deps = [ "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:ice_transport_internal", "../p2p:rtc_p2p", "../rtc_base:ssl", @@ -932,7 +932,7 @@ rtc_source_set("rtc_stats_collector") { "../modules/audio_device", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:connection_info", "../p2p:ice_transport_internal", "../p2p:p2p_constants", @@ -1029,7 +1029,7 @@ rtc_source_set("sdp_offer_answer") { "../media:rid_description", "../media:rtc_media_base", "../media:stream_params", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", @@ -1140,7 +1140,7 @@ rtc_source_set("peer_connection") { "../media:stream_params", "../modules/rtp_rtcp:rtp_rtcp_format", "../p2p:basic_async_resolver_factory", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:connection_info", "../p2p:ice_transport_internal", "../p2p:p2p_constants", @@ -1237,7 +1237,7 @@ rtc_source_set("legacy_stats_collector") { "../media:media_channel", "../media:rtc_media_base", "../modules/audio_processing:audio_processing_statistics", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:connection_info", "../p2p:ice_transport_internal", "../p2p:p2p_constants", @@ -1315,7 +1315,7 @@ rtc_source_set("webrtc_sdp") { "../media:rtp_utils", "../media:stream_params", "../p2p:candidate_pair_interface", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:port_interface", @@ -1382,7 +1382,7 @@ rtc_library("ice_server_parsing") { deps = [ "../api:libjingle_peerconnection_api", "../api:rtc_error", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", @@ -1446,7 +1446,7 @@ rtc_source_set("peer_connection_factory") { "../call:rtp_interfaces", "../call:rtp_sender", "../media:rtc_media_base", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:rtc_p2p", "../pc:audio_track", "../pc:connection_context", @@ -2167,7 +2167,7 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_tests_utils", "../modules/audio_device:audio_device_api", "../modules/audio_processing:api", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:p2p_test_utils", "../p2p:port_interface", "../p2p:rtc_p2p", @@ -2220,7 +2220,7 @@ if (rtc_include_tests && !build_with_chromium) { "../api:libjingle_peerconnection_api", "../api:scoped_refptr", "../api/units:time_delta", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:p2p_server_utils", "../p2p:p2p_test_utils", "../p2p:port_interface", @@ -2403,7 +2403,7 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_device:audio_device_api", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:connection_info", "../p2p:fake_port_allocator", "../p2p:ice_transport_internal", @@ -2619,7 +2619,7 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing:audio_processing_statistics", "../modules/audio_processing:audioproc_test_utils", "../modules/rtp_rtcp:rtp_rtcp_format", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", "../p2p:ice_transport_internal", @@ -2773,7 +2773,7 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing", "../modules/audio_processing:api", "../modules/rtp_rtcp:rtp_rtcp_format", - "../p2p:connection_and_port", + "../p2p:connection", "../p2p:fake_port_allocator", "../p2p:p2p_test_utils", "../p2p:rtc_p2p", From 9c166e064fb2da8273e2d997ce182de49091dbd5 Mon Sep 17 00:00:00 2001 From: Per K Date: Fri, 26 Jan 2024 08:34:34 +0100 Subject: [PATCH 023/170] Remove VideoSendStream::StartPerRtpStream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, always use VideoSendStream::Start. VideoSendStream::StartPerRtpStream was used for controlling if individual rtp stream for a RtpEncodingParameter should be able to send RTP packets. It was not used for controlling the actual encoder layers. With this change RtpEncodingParameter.active still controls actual encoder layers but it does not control if RTP packets can be sent or not. The cleanup is done to simplify code and in the future allow sending probe packet on a RtpTransceiver that allows sending, regardless of the RtpEncodingParameter.active flag. Bug: webrtc:14928 Change-Id: I896c055ed4de76db58d76f452147c29783f77ae1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335042 Reviewed-by: Henrik Boström Reviewed-by: Erik Språng Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/main@{#41619} --- call/video_send_stream.h | 19 +- media/engine/fake_webrtc_call.cc | 11 -- media/engine/fake_webrtc_call.h | 1 - media/engine/webrtc_video_engine.cc | 28 +-- media/engine/webrtc_video_engine.h | 3 +- media/engine/webrtc_video_engine_unittest.cc | 140 -------------- ...er_connection_encodings_integrationtest.cc | 89 +++++++++ test/call_test.cc | 4 +- test/scenario/video_stream.cc | 4 - video/video_send_stream_impl.cc | 64 ++++--- video/video_send_stream_impl.h | 5 +- video/video_send_stream_impl_unittest.cc | 179 +++++++++--------- 12 files changed, 229 insertions(+), 318 deletions(-) diff --git a/call/video_send_stream.h b/call/video_send_stream.h index c305d60bcc..2c3fe55f8d 100644 --- a/call/video_send_stream.h +++ b/call/video_send_stream.h @@ -212,20 +212,8 @@ class VideoSendStream { Config(const Config&); }; - // Updates the sending state for all simulcast layers that the video send - // stream owns. This can mean updating the activity one or for multiple - // layers. The ordering of active layers is the order in which the - // rtp modules are stored in the VideoSendStream. - // Note: This starts stream activity if it is inactive and one of the layers - // is active. This stops stream activity if it is active and all layers are - // inactive. - // `active_layers` should have the same size as the number of configured - // simulcast layers or one if only one rtp stream is used. - virtual void StartPerRtpStream(std::vector active_layers) = 0; - // Starts stream activity. // When a stream is active, it can receive, process and deliver packets. - // Prefer to use StartPerRtpStream. virtual void Start() = 0; // Stops stream activity. @@ -234,11 +222,8 @@ class VideoSendStream { // Accessor for determining if the stream is active. This is an inexpensive // call that must be made on the same thread as `Start()` and `Stop()` methods - // are called on and will return `true` iff activity has been started either - // via `Start()` or `StartPerRtpStream()`. If activity is either - // stopped or is in the process of being stopped as a result of a call to - // either `Stop()` or `StartPerRtpStream()` where all layers were - // deactivated, the return value will be `false`. + // are called on and will return `true` iff activity has been started + // via `Start()`. virtual bool started() = 0; // If the resource is overusing, the VideoSendStream will try to reduce diff --git a/media/engine/fake_webrtc_call.cc b/media/engine/fake_webrtc_call.cc index 16e7169b21..2536c9dd85 100644 --- a/media/engine/fake_webrtc_call.cc +++ b/media/engine/fake_webrtc_call.cc @@ -339,17 +339,6 @@ void FakeVideoSendStream::ReconfigureVideoEncoder( webrtc::InvokeSetParametersCallback(callback, webrtc::RTCError::OK()); } -void FakeVideoSendStream::StartPerRtpStream( - const std::vector active_layers) { - sending_ = false; - for (const bool active_layer : active_layers) { - if (active_layer) { - sending_ = true; - break; - } - } -} - void FakeVideoSendStream::Start() { sending_ = true; } diff --git a/media/engine/fake_webrtc_call.h b/media/engine/fake_webrtc_call.h index 3dd6bdf397..d67a7ee452 100644 --- a/media/engine/fake_webrtc_call.h +++ b/media/engine/fake_webrtc_call.h @@ -199,7 +199,6 @@ class FakeVideoSendStream final void OnFrame(const webrtc::VideoFrame& frame) override; // webrtc::VideoSendStream implementation. - void StartPerRtpStream(std::vector active_layers) override; void Start() override; void Stop() override; bool started() override { return IsSending(); } diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index a5b46d3344..902b5365d1 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -2013,6 +2013,7 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::SetRtpParameters( new_send_state = true; } } + rtp_parameters_ = new_parameters; // Codecs are currently handled at the WebRtcVideoSendChannel level. rtp_parameters_.codecs.clear(); @@ -2021,9 +2022,6 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::SetRtpParameters( ReconfigureEncoder(std::move(callback)); callback = nullptr; } - if (new_send_state) { - UpdateSendState(); - } if (new_degradation_preference) { if (source_ && stream_) { stream_->SetSource(source_, GetDegradationPreference()); @@ -2082,27 +2080,9 @@ void WebRtcVideoSendChannel::WebRtcVideoSendStream::UpdateSendState() { RTC_DCHECK_RUN_ON(&thread_checker_); if (sending_) { RTC_DCHECK(stream_ != nullptr); - size_t num_layers = rtp_parameters_.encodings.size(); - if (parameters_.encoder_config.number_of_streams == 1) { - // SVC is used. Only one simulcast layer is present. - num_layers = 1; - } - std::vector active_layers(num_layers); - for (size_t i = 0; i < num_layers; ++i) { - active_layers[i] = IsLayerActive(rtp_parameters_.encodings[i]); - } - if (parameters_.encoder_config.number_of_streams == 1 && - rtp_parameters_.encodings.size() > 1) { - // SVC is used. - // The only present simulcast layer should be active if any of the - // configured SVC layers is active. - active_layers[0] = - absl::c_any_of(rtp_parameters_.encodings, - [](const auto& encoding) { return encoding.active; }); - } - // This updates what simulcast layers are sending, and possibly starts - // or stops the VideoSendStream. - stream_->StartPerRtpStream(active_layers); + // This allows the the Stream to be used. Ie, DTLS is connected and the + // RtpTransceiver direction allows sending. + stream_->Start(); } else { if (stream_ != nullptr) { stream_->Stop(); diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index e4b1b2765b..57de0b0465 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -402,8 +402,7 @@ class WebRtcVideoSendChannel : public MediaChannelUtil, const VideoCodec& codec) const; void ReconfigureEncoder(webrtc::SetParametersCallback callback); - // Calls Start or Stop according to whether or not `sending_` is true, - // and whether or not the encoding in `rtp_parameters_` is active. + // Calls Start or Stop according to whether or not `sending_` is true. void UpdateSendState(); webrtc::DegradationPreference GetDegradationPreference() const diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index 148223f497..4493c9c616 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -9078,105 +9078,6 @@ TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) { stream->GetVideoStreams()[0].target_bitrate_bps); } -// Test that a stream will not be sending if its encoding is made inactive -// through SetRtpSendParameters. -TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) { - FakeVideoSendStream* stream = AddSendStream(); - EXPECT_TRUE(send_channel_->SetSend(true)); - EXPECT_TRUE(stream->IsSending()); - - // Get current parameters and change "active" to false. - webrtc::RtpParameters parameters = - send_channel_->GetRtpSendParameters(last_ssrc_); - ASSERT_EQ(1u, parameters.encodings.size()); - ASSERT_TRUE(parameters.encodings[0].active); - parameters.encodings[0].active = false; - EXPECT_TRUE(send_channel_->SetRtpSendParameters(last_ssrc_, parameters).ok()); - EXPECT_FALSE(stream->IsSending()); - - // Now change it back to active and verify we resume sending. - parameters.encodings[0].active = true; - EXPECT_TRUE(send_channel_->SetRtpSendParameters(last_ssrc_, parameters).ok()); - EXPECT_TRUE(stream->IsSending()); -} - -// Tests that when active is updated for any simulcast layer then the send -// stream's sending state will be updated and it will be reconfigured with the -// new appropriate active simulcast streams. -TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) { - // Create the stream params with multiple ssrcs for simulcast. - const size_t kNumSimulcastStreams = 3; - std::vector ssrcs = MAKE_VECTOR(kSsrcs3); - StreamParams stream_params = CreateSimStreamParams("cname", ssrcs); - FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params); - uint32_t primary_ssrc = stream_params.first_ssrc(); - - // Using the FrameForwarder, we manually send a full size - // frame. This allows us to test that ReconfigureEncoder is called - // appropriately. - webrtc::test::FrameForwarder frame_forwarder; - VideoOptions options; - EXPECT_TRUE( - send_channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder)); - send_channel_->SetSend(true); - frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame( - 1920, 1080, webrtc::VideoRotation::kVideoRotation_0, - rtc::kNumMicrosecsPerSec / 30)); - - // Check that all encodings are initially active. - webrtc::RtpParameters parameters = - send_channel_->GetRtpSendParameters(primary_ssrc); - EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size()); - EXPECT_TRUE(parameters.encodings[0].active); - EXPECT_TRUE(parameters.encodings[1].active); - EXPECT_TRUE(parameters.encodings[2].active); - EXPECT_TRUE(fake_video_send_stream->IsSending()); - - // Only turn on only the middle stream. - parameters.encodings[0].active = false; - parameters.encodings[1].active = true; - parameters.encodings[2].active = false; - EXPECT_TRUE( - send_channel_->SetRtpSendParameters(primary_ssrc, parameters).ok()); - // Verify that the active fields are set on the VideoChannel. - parameters = send_channel_->GetRtpSendParameters(primary_ssrc); - EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size()); - EXPECT_FALSE(parameters.encodings[0].active); - EXPECT_TRUE(parameters.encodings[1].active); - EXPECT_FALSE(parameters.encodings[2].active); - // Check that the VideoSendStream is updated appropriately. This means its - // send state was updated and it was reconfigured. - EXPECT_TRUE(fake_video_send_stream->IsSending()); - std::vector simulcast_streams = - fake_video_send_stream->GetVideoStreams(); - EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size()); - EXPECT_FALSE(simulcast_streams[0].active); - EXPECT_TRUE(simulcast_streams[1].active); - EXPECT_FALSE(simulcast_streams[2].active); - - // Turn off all streams. - parameters.encodings[0].active = false; - parameters.encodings[1].active = false; - parameters.encodings[2].active = false; - EXPECT_TRUE( - send_channel_->SetRtpSendParameters(primary_ssrc, parameters).ok()); - // Verify that the active fields are set on the VideoChannel. - parameters = send_channel_->GetRtpSendParameters(primary_ssrc); - EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size()); - EXPECT_FALSE(parameters.encodings[0].active); - EXPECT_FALSE(parameters.encodings[1].active); - EXPECT_FALSE(parameters.encodings[2].active); - // Check that the VideoSendStream is off. - EXPECT_FALSE(fake_video_send_stream->IsSending()); - simulcast_streams = fake_video_send_stream->GetVideoStreams(); - EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size()); - EXPECT_FALSE(simulcast_streams[0].active); - EXPECT_FALSE(simulcast_streams[1].active); - EXPECT_FALSE(simulcast_streams[2].active); - - EXPECT_TRUE(send_channel_->SetVideoSend(primary_ssrc, nullptr, nullptr)); -} - // Tests that when some streams are disactivated then the lowest // stream min_bitrate would be reused for the first active stream. TEST_F(WebRtcVideoChannelTest, @@ -9232,47 +9133,6 @@ TEST_F(WebRtcVideoChannelTest, EXPECT_TRUE(send_channel_->SetVideoSend(primary_ssrc, nullptr, nullptr)); } -// Test that if a stream is reconfigured (due to a codec change or other -// change) while its encoding is still inactive, it doesn't start sending. -TEST_F(WebRtcVideoChannelTest, - InactiveStreamDoesntStartSendingWhenReconfigured) { - // Set an initial codec list, which will be modified later. - cricket::VideoSenderParameters parameters1; - parameters1.codecs.push_back(GetEngineCodec("VP8")); - parameters1.codecs.push_back(GetEngineCodec("VP9")); - EXPECT_TRUE(send_channel_->SetSenderParameters(parameters1)); - - FakeVideoSendStream* stream = AddSendStream(); - EXPECT_TRUE(send_channel_->SetSend(true)); - EXPECT_TRUE(stream->IsSending()); - - // Get current parameters and change "active" to false. - webrtc::RtpParameters parameters = - send_channel_->GetRtpSendParameters(last_ssrc_); - ASSERT_EQ(1u, parameters.encodings.size()); - ASSERT_TRUE(parameters.encodings[0].active); - parameters.encodings[0].active = false; - EXPECT_EQ(1u, GetFakeSendStreams().size()); - EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams()); - EXPECT_TRUE(send_channel_->SetRtpSendParameters(last_ssrc_, parameters).ok()); - EXPECT_FALSE(stream->IsSending()); - - // Reorder the codec list, causing the stream to be reconfigured. - cricket::VideoSenderParameters parameters2; - parameters2.codecs.push_back(GetEngineCodec("VP9")); - parameters2.codecs.push_back(GetEngineCodec("VP8")); - EXPECT_TRUE(send_channel_->SetSenderParameters(parameters2)); - auto new_streams = GetFakeSendStreams(); - // Assert that a new underlying stream was created due to the codec change. - // Otherwise, this test isn't testing what it set out to test. - EXPECT_EQ(1u, GetFakeSendStreams().size()); - EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams()); - - // Verify that we still are not sending anything, due to the inactive - // encoding. - EXPECT_FALSE(new_streams[0]->IsSending()); -} - // Test that GetRtpSendParameters returns the currently configured codecs. TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) { AddSendStream(); diff --git a/pc/peer_connection_encodings_integrationtest.cc b/pc/peer_connection_encodings_integrationtest.cc index 4a93e915df..06299d7029 100644 --- a/pc/peer_connection_encodings_integrationtest.cc +++ b/pc/peer_connection_encodings_integrationtest.cc @@ -9,6 +9,7 @@ */ #include +#include #include #include "absl/strings/match.h" @@ -41,6 +42,7 @@ #include "pc/test/simulcast_layer_util.h" #include "rtc_base/gunit.h" #include "rtc_base/physical_socket_server.h" +#include "rtc_base/thread.h" #include "test/gmock.h" #include "test/gtest.h" @@ -269,6 +271,34 @@ class PeerConnectionEncodingsIntegrationTest : public ::testing::Test { return num_sending_layers == num_active_layers; } + int EncodedFrames(rtc::scoped_refptr pc_wrapper, + std::string_view rid) { + rtc::scoped_refptr report = GetStats(pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + for (const auto* outbound_rtp : outbound_rtps) { + if (outbound_rtp->rid.value_or("") == rid) { + return outbound_rtp->frames_encoded.value_or(0); + } + } + return 0; + } + + bool EncodingIsActive( + rtc::scoped_refptr pc_wrapper, + std::string_view rid) { + rtc::scoped_refptr report = GetStats(pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + for (const auto* outbound_rtp : outbound_rtps) { + if (outbound_rtp->rid.value_or("") == rid) { + return *outbound_rtp->active; + } + } + RTC_CHECK(false) << "Rid not found: " << rid; + return false; + } + bool HasOutboundRtpWithRidAndScalabilityMode( rtc::scoped_refptr pc_wrapper, absl::string_view rid, @@ -1964,6 +1994,65 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, Simulcast) { EXPECT_THAT(*outbound_rtps[2]->scalability_mode, StrEq("L1T3")); } +TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, + SimulcastEncodingStopWhenRtpEncodingChangeToInactive) { + rtc::scoped_refptr local_pc_wrapper = CreatePc(); + if (SkipTestDueToAv1Missing(local_pc_wrapper)) { + return; + } + rtc::scoped_refptr remote_pc_wrapper = CreatePc(); + ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper); + + std::vector layers = + CreateLayers({"q", "h", "f"}, /*active=*/true); + rtc::scoped_refptr transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, codec_name_); + transceiver->SetCodecPreferences(codecs); + + rtc::scoped_refptr sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + ASSERT_EQ(parameters.encodings[0].rid, "q"); + parameters.encodings[0].scalability_mode = "L1T3"; + parameters.encodings[0].scale_resolution_down_by = 4; + ASSERT_EQ(parameters.encodings[1].rid, "h"); + parameters.encodings[1].scalability_mode = "L1T3"; + parameters.encodings[1].scale_resolution_down_by = 2; + ASSERT_EQ(parameters.encodings[2].rid, "f"); + parameters.encodings[2].scalability_mode = "L1T3"; + parameters.encodings[2].scale_resolution_down_by = 1; + sender->SetParameters(parameters); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "f") > 1, + kLongTimeoutForRampingUp.ms()); + + // Switch higest layer to Inactive. + parameters = sender->GetParameters(); + ASSERT_THAT(parameters.encodings, SizeIs(3)); + parameters.encodings[2].active = false; + sender->SetParameters(parameters); + ASSERT_TRUE_WAIT(!EncodingIsActive(local_pc_wrapper, "f"), + kDefaultTimeout.ms()); + + int encoded_frames_f = EncodedFrames(local_pc_wrapper, "f"); + int encoded_frames_h = EncodedFrames(local_pc_wrapper, "h"); + int encoded_frames_q = EncodedFrames(local_pc_wrapper, "q"); + + // Wait until the encoder has encoded another 10 frames on lower layers. + ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "q") > encoded_frames_q + 10, + kDefaultTimeout.ms()); + ASSERT_TRUE_WAIT(EncodedFrames(local_pc_wrapper, "h") > encoded_frames_h + 10, + kDefaultTimeout.ms()); + EXPECT_LE(EncodedFrames(local_pc_wrapper, "f") - encoded_frames_f, 2); +} + INSTANTIATE_TEST_SUITE_P(StandardPath, PeerConnectionEncodingsIntegrationParameterizedTest, ::testing::Values("VP8", diff --git a/test/call_test.cc b/test/call_test.cc index 6cdd8da133..f26a44a341 100644 --- a/test/call_test.cc +++ b/test/call_test.cc @@ -657,9 +657,7 @@ void CallTest::StartVideoSources() { void CallTest::StartVideoStreams() { StartVideoSources(); for (size_t i = 0; i < video_send_streams_.size(); ++i) { - std::vector active_rtp_streams( - video_send_configs_[i].rtp.ssrcs.size(), true); - video_send_streams_[i]->StartPerRtpStream(active_rtp_streams); + video_send_streams_[i]->Start(); } for (VideoReceiveStreamInterface* video_recv_stream : video_receive_streams_) video_recv_stream->Start(); diff --git a/test/scenario/video_stream.cc b/test/scenario/video_stream.cc index 654aed7c6c..c3f0da7cb7 100644 --- a/test/scenario/video_stream.cc +++ b/test/scenario/video_stream.cc @@ -491,10 +491,6 @@ void SendVideoStream::UpdateConfig( void SendVideoStream::UpdateActiveLayers(std::vector active_layers) { sender_->task_queue_.PostTask([=] { MutexLock lock(&mutex_); - if (config_.encoder.codec == - VideoStreamConfig::Encoder::Codec::kVideoCodecVP8) { - send_stream_->StartPerRtpStream(active_layers); - } VideoEncoderConfig encoder_config = CreateVideoEncoderConfig(config_); RTC_CHECK_EQ(encoder_config.simulcast_layers.size(), active_layers.size()); for (size_t i = 0; i < encoder_config.simulcast_layers.size(); ++i) diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc index 23dbb7177f..e5ff2cd727 100644 --- a/video/video_send_stream_impl.cc +++ b/video/video_send_stream_impl.cc @@ -362,6 +362,15 @@ std::unique_ptr CreateVideoStreamEncoder( encoder_selector); } +bool HasActiveEncodings(const VideoEncoderConfig& config) { + for (const VideoStream& stream : config.simulcast_layers) { + if (stream.active) { + return true; + } + } + return false; +} + } // namespace PacingConfig::PacingConfig(const FieldTrialsView& field_trials) @@ -438,6 +447,7 @@ VideoSendStreamImpl::VideoSendStreamImpl( timed_out_(false), bitrate_allocator_(bitrate_allocator), + has_active_encodings_(HasActiveEncodings(encoder_config)), disable_padding_(true), max_padding_bitrate_(0), encoder_min_bitrate_bps_(0), @@ -545,6 +555,13 @@ void VideoSendStreamImpl::ReconfigureVideoEncoder( RTC_DCHECK_EQ(content_type_, config.content_type); RTC_LOG(LS_VERBOSE) << "Encoder config: " << config.ToString() << " VideoSendStream config: " << config_.ToString(); + + has_active_encodings_ = HasActiveEncodings(config); + if (has_active_encodings_ && rtp_video_sender_->IsActive() && !IsRunning()) { + StartupVideoSendStream(); + } else if (!has_active_encodings_ && IsRunning()) { + StopVideoSendStream(); + } video_stream_encoder_->ConfigureEncoder( std::move(config), config_.rtp.max_packet_size - CalculateMaxHeaderSize(config_.rtp), @@ -609,40 +626,25 @@ bool VideoSendStreamImpl::started() { } void VideoSendStreamImpl::Start() { - const std::vector active_layers(config_.rtp.ssrcs.size(), true); - StartPerRtpStream(active_layers); -} - -void VideoSendStreamImpl::StartPerRtpStream( - const std::vector active_layers) { RTC_DCHECK_RUN_ON(&thread_checker_); - - rtc::StringBuilder active_layers_string; - active_layers_string << "{"; - for (size_t i = 0; i < active_layers.size(); ++i) { - if (active_layers[i]) { - active_layers_string << "1"; - } else { - active_layers_string << "0"; - } - if (i < active_layers.size() - 1) { - active_layers_string << ", "; - } - } - active_layers_string << "}"; - RTC_LOG(LS_INFO) << "StartPerRtpStream: " << active_layers_string.str(); - - bool previously_active = rtp_video_sender_->IsActive(); + const std::vector active_layers(config_.rtp.ssrcs.size(), true); + // This sender is allowed to send RTP packets. Start monitoring and allocating + // a rate if there is also active encodings. (has_active_encodings_). rtp_video_sender_->SetActiveModules(active_layers); - if (!rtp_video_sender_->IsActive() && previously_active) { - StopVideoSendStream(); - } else if (rtp_video_sender_->IsActive() && !previously_active) { + if (!IsRunning() && has_active_encodings_) { StartupVideoSendStream(); } } +bool VideoSendStreamImpl::IsRunning() const { + RTC_DCHECK_RUN_ON(&thread_checker_); + return check_encoder_activity_task_.Running(); +} + void VideoSendStreamImpl::StartupVideoSendStream() { RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK(rtp_video_sender_->IsActive()); + RTC_DCHECK(has_active_encodings_); bitrate_allocator_->AddObserver(this, GetAllocationConfig()); // Start monitoring encoder activity. @@ -680,7 +682,9 @@ void VideoSendStreamImpl::Stop() { TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop"); rtp_video_sender_->Stop(); - StopVideoSendStream(); + if (IsRunning()) { + StopVideoSendStream(); + } } void VideoSendStreamImpl::StopVideoSendStream() { @@ -805,7 +809,9 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged( double stream_bitrate_priority_sum = 0; for (const auto& stream : streams) { // We don't want to allocate more bitrate than needed to inactive streams. - encoder_max_bitrate_bps_ += stream.active ? stream.max_bitrate_bps : 0; + if (stream.active) { + encoder_max_bitrate_bps_ += stream.max_bitrate_bps; + } if (stream.bitrate_priority) { RTC_DCHECK_GT(*stream.bitrate_priority, 0); stream_bitrate_priority_sum += *stream.bitrate_priority; @@ -833,7 +839,7 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged( rtp_video_sender_->SetEncodingData(streams[0].width, streams[0].height, num_temporal_layers); - if (rtp_video_sender_->IsActive()) { + if (IsRunning()) { // The send stream is started already. Update the allocator with new // bitrate limits. bitrate_allocator_->AddObserver(this, GetAllocationConfig()); diff --git a/video/video_send_stream_impl.h b/video/video_send_stream_impl.h index 758e12c095..8cff4b8822 100644 --- a/video/video_send_stream_impl.h +++ b/video/video_send_stream_impl.h @@ -96,7 +96,6 @@ class VideoSendStreamImpl : public webrtc::VideoSendStream, // webrtc::VideoSendStream implementation. void Start() override; - void StartPerRtpStream(std::vector active_layers) override; void Stop() override; bool started() override; @@ -182,6 +181,9 @@ class VideoSendStreamImpl : public webrtc::VideoSendStream, void ConfigureSsrcs(); void SignalEncoderTimedOut(); void SignalEncoderActive(); + // A video send stream is running if VideoSendStream::Start has been invoked + // and there is an active encoding. + bool IsRunning() const; MediaStreamAllocationConfig GetAllocationConfig() const RTC_RUN_ON(thread_checker_); @@ -212,6 +214,7 @@ class VideoSendStreamImpl : public webrtc::VideoSendStream, BitrateAllocatorInterface* const bitrate_allocator_; + bool has_active_encodings_ RTC_GUARDED_BY(thread_checker_); bool disable_padding_ RTC_GUARDED_BY(thread_checker_); int max_padding_bitrate_ RTC_GUARDED_BY(thread_checker_); int encoder_min_bitrate_bps_ RTC_GUARDED_BY(thread_checker_); diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc index ba492ae66f..e3a1618939 100644 --- a/video/video_send_stream_impl_unittest.cc +++ b/video/video_send_stream_impl_unittest.cc @@ -54,6 +54,7 @@ #include "video/send_delay_stats.h" #include "video/send_statistics_proxy.h" #include "video/test/mock_video_stream_encoder.h" +#include "video/video_stream_encoder.h" #include "video/video_stream_encoder_interface.h" namespace webrtc { @@ -71,6 +72,7 @@ using ::testing::_; using ::testing::AllOf; using ::testing::Field; using ::testing::Invoke; +using ::testing::Mock; using ::testing::NiceMock; using ::testing::Return; @@ -172,21 +174,23 @@ class VideoSendStreamImplTest : public ::testing::Test { } ~VideoSendStreamImplTest() {} - std::unique_ptr CreateVideoSendStreamImpl( - int initial_encoder_max_bitrate, - double initial_encoder_bitrate_priority, - VideoEncoderConfig::ContentType content_type, - absl::optional codec = std::nullopt) { - EXPECT_CALL(bitrate_allocator_, GetStartBitrate(_)) - .WillOnce(Return(123000)); - + VideoEncoderConfig TestVideoEncoderConfig( + VideoEncoderConfig::ContentType content_type = + VideoEncoderConfig::ContentType::kRealtimeVideo, + int initial_encoder_max_bitrate = kDefaultInitialBitrateBps, + double initial_encoder_bitrate_priority = kDefaultBitratePriority) { VideoEncoderConfig encoder_config; encoder_config.max_bitrate_bps = initial_encoder_max_bitrate; encoder_config.bitrate_priority = initial_encoder_bitrate_priority; encoder_config.content_type = content_type; - if (codec) { - config_.rtp.payload_name = *codec; - } + encoder_config.simulcast_layers.push_back(VideoStream()); + encoder_config.simulcast_layers.back().active = true; + return encoder_config; + } + + std::unique_ptr CreateVideoSendStreamImpl( + VideoEncoderConfig encoder_config) { + EXPECT_CALL(bitrate_allocator_, GetStartBitrate).WillOnce(Return(123000)); std::map suspended_ssrcs; std::map suspended_payload_states; @@ -200,7 +204,7 @@ class VideoSendStreamImplTest : public ::testing::Test { /*num_cpu_cores=*/1, time_controller_.GetTaskQueueFactory(), /*call_stats=*/nullptr, &transport_controller_, /*metronome=*/nullptr, &bitrate_allocator_, &send_delay_stats_, - /*event_log=*/nullptr, config_.Copy(), encoder_config.Copy(), + /*event_log=*/nullptr, config_.Copy(), std::move(encoder_config), suspended_ssrcs, suspended_payload_states, /*fec_controller=*/nullptr, field_trials_, std::move(video_stream_encoder)); @@ -231,26 +235,50 @@ class VideoSendStreamImplTest : public ::testing::Test { PacketRouter packet_router_; }; -TEST_F(VideoSendStreamImplTest, RegistersAsBitrateObserverOnStart) { - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); - const bool kSuspend = false; - config_.suspend_below_min_bitrate = kSuspend; - EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) - .WillOnce(Invoke( - [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { - EXPECT_EQ(config.min_bitrate_bps, 0u); - EXPECT_EQ(config.max_bitrate_bps, kDefaultInitialBitrateBps); - EXPECT_EQ(config.pad_up_bitrate_bps, 0u); - EXPECT_EQ(config.enforce_min_bitrate, !kSuspend); - EXPECT_EQ(config.bitrate_priority, kDefaultBitratePriority); - })); - vss_impl->StartPerRtpStream({true}); +TEST_F(VideoSendStreamImplTest, + NotRegistersAsBitrateObserverOnStartIfNoActiveEncodings) { + VideoEncoderConfig encoder_config = TestVideoEncoderConfig(); + encoder_config.simulcast_layers[0].active = false; + auto vss_impl = CreateVideoSendStreamImpl(std::move(encoder_config)); + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)).Times(0); + EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(0); + + vss_impl->Start(); + time_controller_.AdvanceTime(TimeDelta::Zero()); + vss_impl->Stop(); +} + +TEST_F(VideoSendStreamImplTest, + RegistersAsBitrateObserverOnStartIfHasActiveEncodings) { + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); + + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)); + vss_impl->Start(); + time_controller_.AdvanceTime(TimeDelta::Zero()); + EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); vss_impl->Stop(); } +TEST_F(VideoSendStreamImplTest, + DeRegistersAsBitrateObserverIfNoActiveEncodings) { + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)); + vss_impl->Start(); + time_controller_.AdvanceTime(TimeDelta::Zero()); + + EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); + VideoEncoderConfig no_active_encodings = TestVideoEncoderConfig(); + no_active_encodings.simulcast_layers[0].active = false; + + vss_impl->ReconfigureVideoEncoder(std::move(no_active_encodings)); + + time_controller_.AdvanceTime(TimeDelta::Zero()); + ::testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_); + + vss_impl->Stop(); +} + TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { const bool kSuspend = false; config_.suspend_below_min_bitrate = kSuspend; @@ -259,11 +287,9 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { config_.rtp.ssrcs.emplace_back(1); config_.rtp.ssrcs.emplace_back(2); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); // QVGA + VGA configuration matching defaults in // media/engine/simulcast.cc. @@ -326,9 +352,8 @@ TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChangeWithAlr) { config_.rtp.ssrcs.emplace_back(2); auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->StartPerRtpStream({true}); + TestVideoEncoderConfig(VideoEncoderConfig::ContentType::kScreen)); + vss_impl->Start(); // Simulcast screenshare. VideoStream low_stream; @@ -388,11 +413,9 @@ TEST_F(VideoSendStreamImplTest, config_.rtp.ssrcs.emplace_back(1); config_.rtp.ssrcs.emplace_back(2); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); // 2-layer video simulcast. VideoStream low_stream; low_stream.width = 320; @@ -451,31 +474,28 @@ TEST_F(VideoSendStreamImplTest, SetsScreensharePacingFactorWithFeedback) { SetPacingFactor(kAlrProbingExperimentPaceMultiplier)) .Times(1); auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->StartPerRtpStream({true}); + TestVideoEncoderConfig(VideoEncoderConfig::ContentType::kScreen)); + vss_impl->Start(); vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, DoesNotSetPacingFactorWithoutFeedback) { test::ScopedFieldTrials alr_experiment(GetAlrProbingExperimentString()); auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); + TestVideoEncoderConfig(VideoEncoderConfig::ContentType::kScreen)); EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); vss_impl->Stop(); } TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) { auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); + TestVideoEncoderConfig(VideoEncoderConfig::ContentType::kScreen)); EXPECT_CALL(transport_controller_, SetPacingFactor(_)).Times(0); VideoStreamEncoderInterface::EncoderSink* const sink = static_cast(vss_impl.get()); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); // Populate a test instance of video bitrate allocation. VideoBitrateAllocation alloc; alloc.SetBitrate(0, 0, 10000); @@ -515,9 +535,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationWhenEnabled) { TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) { auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->StartPerRtpStream({true}); + TestVideoEncoderConfig(VideoEncoderConfig::ContentType::kScreen)); + vss_impl->Start(); // Unpause encoder, to allows allocations to be passed through. const uint32_t kBitrateBps = 100000; EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) @@ -574,10 +593,9 @@ TEST_F(VideoSendStreamImplTest, ThrottlesVideoBitrateAllocationWhenTooSimilar) { TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) { auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); + TestVideoEncoderConfig(VideoEncoderConfig::ContentType::kScreen)); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); // Unpause encoder, to allows allocations to be passed through. const uint32_t kBitrateBps = 100000; EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) @@ -616,9 +634,8 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationOnLayerChange) { TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) { auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kScreen); - vss_impl->StartPerRtpStream({true}); + TestVideoEncoderConfig(VideoEncoderConfig::ContentType::kScreen)); + vss_impl->Start(); const uint32_t kBitrateBps = 100000; // Unpause encoder, to allows allocations to be passed through. EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) @@ -720,15 +737,13 @@ TEST_F(VideoSendStreamImplTest, ForwardsVideoBitrateAllocationAfterTimeout) { } TEST_F(VideoSendStreamImplTest, PriorityBitrateConfigInactiveByDefault) { - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); EXPECT_CALL( bitrate_allocator_, AddObserver( vss_impl.get(), Field(&MediaStreamAllocationConfig::priority_bitrate_bps, 0))); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); vss_impl->Stop(); } @@ -736,15 +751,14 @@ TEST_F(VideoSendStreamImplTest, PriorityBitrateConfigInactiveByDefault) { TEST_F(VideoSendStreamImplTest, PriorityBitrateConfigAffectsAV1) { test::ScopedFieldTrials override_priority_bitrate( "WebRTC-AV1-OverridePriorityBitrate/bitrate:20000/"); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo, "AV1"); + config_.rtp.payload_name = "AV1"; + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); EXPECT_CALL( bitrate_allocator_, AddObserver( vss_impl.get(), Field(&MediaStreamAllocationConfig::priority_bitrate_bps, 20000))); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); vss_impl->Stop(); } @@ -765,16 +779,15 @@ TEST_F(VideoSendStreamImplTest, test::ScopedFieldTrials override_priority_bitrate( "WebRTC-AV1-OverridePriorityBitrate/bitrate:20000/"); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo, "AV1"); + config_.rtp.payload_name = "AV1"; + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); EXPECT_CALL( bitrate_allocator_, AddObserver( vss_impl.get(), Field(&MediaStreamAllocationConfig::priority_bitrate_bps, 20000))) .Times(2); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); encoder_queue_->PostTask([&] { static_cast(vss_impl.get()) @@ -794,10 +807,9 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { config_.suspend_below_min_bitrate = kSuspend; config_.rtp.extensions.emplace_back(RtpExtension::kTransportSequenceNumberUri, 1); - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); - vss_impl->StartPerRtpStream({true}); + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); + + vss_impl->Start(); VideoStream qvga_stream; qvga_stream.width = 320; qvga_stream.height = 180; @@ -893,9 +905,7 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) { TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { int padding_bitrate = 0; - std::unique_ptr vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); // Capture padding bitrate for testing. EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) @@ -928,7 +938,7 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { int min_transmit_bitrate_bps = 30000; config_.rtp.ssrcs.emplace_back(1); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); // Starts without padding. EXPECT_EQ(0, padding_bitrate); encoder_queue_->PostTask([&] { @@ -972,11 +982,9 @@ TEST_F(VideoSendStreamImplTest, DisablesPaddingOnPausedEncoder) { } TEST_F(VideoSendStreamImplTest, KeepAliveOnDroppedFrame) { - std::unique_ptr vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, - VideoEncoderConfig::ContentType::kRealtimeVideo); + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(0); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); const uint32_t kBitrateBps = 100000; EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) .Times(1) @@ -1015,13 +1023,12 @@ TEST_F(VideoSendStreamImplTest, ConfiguresBitratesForSvc) { config_.rtp.extensions.emplace_back( RtpExtension::kTransportSequenceNumberUri, 1); config_.periodic_alr_bandwidth_probing = test_config.alr; - auto vss_impl = CreateVideoSendStreamImpl( - kDefaultInitialBitrateBps, kDefaultBitratePriority, + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig( test_config.screenshare ? VideoEncoderConfig::ContentType::kScreen - : VideoEncoderConfig::ContentType::kRealtimeVideo); + : VideoEncoderConfig::ContentType::kRealtimeVideo)); - vss_impl->StartPerRtpStream({true}); + vss_impl->Start(); // Svc VideoStream stream; @@ -1100,7 +1107,7 @@ TEST_F(VideoSendStreamImplTest, ConfiguresBitratesForSvc) { ->OnEncodedImage(encoded_image, &codec_specific); }); time_controller_.AdvanceTime(TimeDelta::Zero()); - ::testing::Mock::VerifyAndClearExpectations(&bitrate_allocator_); + Mock::VerifyAndClearExpectations(&bitrate_allocator_); vss_impl->Stop(); } From 979b6d62a8ad2d47f043dceb86d74fcfb6c8dfc7 Mon Sep 17 00:00:00 2001 From: Per K Date: Fri, 26 Jan 2024 11:18:26 +0100 Subject: [PATCH 024/170] Refactor RtpVideoSender::SetActiveModules. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename RtpVideoSender::SetActiveModules to SetSending to better match what it does. When a RtpVideoSender::SetSending(true) RTP packets can be sent on all associcated RTP streams (simulcast streams). Move registration of RtpRtcpModules to RtpTransportControllerSend to allow RtpTransportControllerSend to know when there are sending RTP streams. Purpose is to in later CLs allow RtpTransportControllerSend to trigger BWE probes. Bug: webrtc:14928 Change-Id: Ibf6c040b86713cdc4763c4691b7fd794b251eb49 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335961 Reviewed-by: Erik Språng Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/main@{#41620} --- call/rtp_transport_controller_send.cc | 25 ++++++ call/rtp_transport_controller_send.h | 2 + .../rtp_transport_controller_send_interface.h | 7 ++ call/rtp_video_sender.cc | 88 +++++-------------- call/rtp_video_sender.h | 9 +- call/rtp_video_sender_interface.h | 8 +- call/rtp_video_sender_unittest.cc | 79 ++++++----------- .../test/mock_rtp_transport_controller_send.h | 5 ++ video/video_send_stream_impl.cc | 5 +- video/video_send_stream_impl_unittest.cc | 22 ++--- 10 files changed, 102 insertions(+), 148 deletions(-) diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc index 600d4e2620..5ed1d6a0f3 100644 --- a/call/rtp_transport_controller_send.cc +++ b/call/rtp_transport_controller_send.cc @@ -159,6 +159,31 @@ void RtpTransportControllerSend::DestroyRtpVideoSender( video_rtp_senders_.erase(it); } +void RtpTransportControllerSend::RegisterSendingRtpStream( + RtpRtcpInterface& rtp_module) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + // Allow pacer to send packets using this module. + packet_router_.AddSendRtpModule(&rtp_module, + /*remb_candidate=*/true); +} + +void RtpTransportControllerSend::DeRegisterSendingRtpStream( + RtpRtcpInterface& rtp_module) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + // Disabling media, remove from packet router map to reduce size and + // prevent any stray packets in the pacer from asynchronously arriving + // to a disabled module. + packet_router_.RemoveSendRtpModule(&rtp_module); + // Clear the pacer queue of any packets pertaining to this module. + pacer_.RemovePacketsForSsrc(rtp_module.SSRC()); + if (rtp_module.RtxSsrc().has_value()) { + pacer_.RemovePacketsForSsrc(*rtp_module.RtxSsrc()); + } + if (rtp_module.FlexfecSsrc().has_value()) { + pacer_.RemovePacketsForSsrc(*rtp_module.FlexfecSsrc()); + } +} + void RtpTransportControllerSend::UpdateControlState() { absl::optional update = control_handler_->GetUpdate(); if (!update) diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h index c0bca41a2b..6f6f0809a3 100644 --- a/call/rtp_transport_controller_send.h +++ b/call/rtp_transport_controller_send.h @@ -75,6 +75,8 @@ class RtpTransportControllerSend final RtpVideoSenderInterface* rtp_video_sender) override; // Implements RtpTransportControllerSendInterface + void RegisterSendingRtpStream(RtpRtcpInterface& rtp_module) override; + void DeRegisterSendingRtpStream(RtpRtcpInterface& rtp_module) override; PacketRouter* packet_router() override; NetworkStateEstimateObserver* network_state_estimate_observer() override; diff --git a/call/rtp_transport_controller_send_interface.h b/call/rtp_transport_controller_send_interface.h index 7edc135037..1938d86c57 100644 --- a/call/rtp_transport_controller_send_interface.h +++ b/call/rtp_transport_controller_send_interface.h @@ -47,6 +47,7 @@ class Transport; class PacketRouter; class RtpVideoSenderInterface; class RtpPacketSender; +class RtpRtcpInterface; struct RtpSenderObservers { RtcpRttStats* rtcp_rtt_stats; @@ -108,6 +109,12 @@ class RtpTransportControllerSendInterface { virtual void DestroyRtpVideoSender( RtpVideoSenderInterface* rtp_video_sender) = 0; + // Register a specific RTP stream as sending. This means that the pacer and + // packet router can send packets using this RTP stream. + virtual void RegisterSendingRtpStream(RtpRtcpInterface& rtp_module) = 0; + // Pacer and PacketRouter stop using this RTP stream. + virtual void DeRegisterSendingRtpStream(RtpRtcpInterface& rtp_module) = 0; + virtual NetworkStateEstimateObserver* network_state_estimate_observer() = 0; virtual TransportFeedbackObserver* transport_feedback_observer() = 0; diff --git a/call/rtp_video_sender.cc b/call/rtp_video_sender.cc index 1ace08fa32..580850359c 100644 --- a/call/rtp_video_sender.cc +++ b/call/rtp_video_sender.cc @@ -470,85 +470,41 @@ RtpVideoSender::RtpVideoSender( } RtpVideoSender::~RtpVideoSender() { - // TODO(bugs.webrtc.org/13517): Remove once RtpVideoSender gets deleted on the - // transport task queue. - transport_checker_.Detach(); - + RTC_DCHECK_RUN_ON(&transport_checker_); SetActiveModulesLocked( - std::vector(rtp_streams_.size(), /*active=*/false)); - - RTC_DCHECK(!registered_for_feedback_); + /*sending=*/false); } -void RtpVideoSender::Stop() { +void RtpVideoSender::SetSending(bool enabled) { RTC_DCHECK_RUN_ON(&transport_checker_); MutexLock lock(&mutex_); - if (!active_) + if (enabled == active_) { return; - - const std::vector active_modules(rtp_streams_.size(), false); - SetActiveModulesLocked(active_modules); + } + SetActiveModulesLocked(/*sending=*/enabled); } -void RtpVideoSender::SetActiveModules(const std::vector& active_modules) { +void RtpVideoSender::SetActiveModulesLocked(bool sending) { RTC_DCHECK_RUN_ON(&transport_checker_); - MutexLock lock(&mutex_); - return SetActiveModulesLocked(active_modules); -} - -void RtpVideoSender::SetActiveModulesLocked( - const std::vector& active_modules) { - RTC_DCHECK_RUN_ON(&transport_checker_); - RTC_CHECK_EQ(rtp_streams_.size(), active_modules.size()); - active_ = false; - for (size_t i = 0; i < active_modules.size(); ++i) { - if (active_modules[i]) { - active_ = true; - } - + if (active_ == sending) { + return; + } + active_ = sending; + for (size_t i = 0; i < rtp_streams_.size(); ++i) { RtpRtcpInterface& rtp_module = *rtp_streams_[i].rtp_rtcp; - const bool was_active = rtp_module.Sending(); - const bool should_be_active = active_modules[i]; - - rtp_module.SetSendingStatus(active_modules[i]); - - if (was_active && !should_be_active) { - // Disabling media, remove from packet router map to reduce size and - // prevent any stray packets in the pacer from asynchronously arriving - // to a disabled module. - transport_->packet_router()->RemoveSendRtpModule(&rtp_module); - - // Clear the pacer queue of any packets pertaining to this module. - transport_->packet_sender()->RemovePacketsForSsrc(rtp_module.SSRC()); - if (rtp_module.RtxSsrc().has_value()) { - transport_->packet_sender()->RemovePacketsForSsrc( - *rtp_module.RtxSsrc()); - } - if (rtp_module.FlexfecSsrc().has_value()) { - transport_->packet_sender()->RemovePacketsForSsrc( - *rtp_module.FlexfecSsrc()); - } - } - - // If set to false this module won't send media. - rtp_module.SetSendingMediaStatus(active_modules[i]); - - if (!was_active && should_be_active) { - // Turning on media, register with packet router. - transport_->packet_router()->AddSendRtpModule(&rtp_module, - /*remb_candidate=*/true); + rtp_module.SetSendingStatus(sending); + rtp_module.SetSendingMediaStatus(sending); + if (sending) { + transport_->RegisterSendingRtpStream(rtp_module); + } else { + transport_->DeRegisterSendingRtpStream(rtp_module); } } - if (!active_) { - auto* feedback_provider = transport_->GetStreamFeedbackProvider(); - if (registered_for_feedback_) { - feedback_provider->DeRegisterStreamFeedbackObserver(this); - registered_for_feedback_ = false; - } - } else if (!registered_for_feedback_) { - auto* feedback_provider = transport_->GetStreamFeedbackProvider(); + auto* feedback_provider = transport_->GetStreamFeedbackProvider(); + if (!sending) { + feedback_provider->DeRegisterStreamFeedbackObserver(this); + } else { feedback_provider->RegisterStreamFeedbackObserver(rtp_config_.ssrcs, this); - registered_for_feedback_ = true; } } diff --git a/call/rtp_video_sender.h b/call/rtp_video_sender.h index 10b0d19d05..957b46e560 100644 --- a/call/rtp_video_sender.h +++ b/call/rtp_video_sender.h @@ -95,11 +95,7 @@ class RtpVideoSender : public RtpVideoSenderInterface, RtpVideoSender(const RtpVideoSender&) = delete; RtpVideoSender& operator=(const RtpVideoSender&) = delete; - // Sets the sending status of the rtp modules and appropriately sets the - // payload router to active if any rtp modules are active. - void SetActiveModules(const std::vector& active_modules) - RTC_LOCKS_EXCLUDED(mutex_) override; - void Stop() RTC_LOCKS_EXCLUDED(mutex_) override; + void SetSending(bool enabled) RTC_LOCKS_EXCLUDED(mutex_) override; bool IsActive() RTC_LOCKS_EXCLUDED(mutex_) override; void OnNetworkAvailability(bool network_available) @@ -160,7 +156,7 @@ class RtpVideoSender : public RtpVideoSenderInterface, private: bool IsActiveLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); - void SetActiveModulesLocked(const std::vector& active_modules) + void SetActiveModulesLocked(bool sending) RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); void UpdateModuleSendingState() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); void ConfigureProtection(); @@ -184,7 +180,6 @@ class RtpVideoSender : public RtpVideoSenderInterface, // transport task queue. mutable Mutex mutex_; bool active_ RTC_GUARDED_BY(mutex_); - bool registered_for_feedback_ RTC_GUARDED_BY(transport_checker_) = false; const std::unique_ptr fec_controller_; bool fec_allowed_ RTC_GUARDED_BY(mutex_); diff --git a/call/rtp_video_sender_interface.h b/call/rtp_video_sender_interface.h index 3f2877155a..6bbcb7f46e 100644 --- a/call/rtp_video_sender_interface.h +++ b/call/rtp_video_sender_interface.h @@ -31,12 +31,8 @@ struct FecProtectionParams; class RtpVideoSenderInterface : public EncodedImageCallback, public FecControllerOverride { public: - // Sets the sending status of the rtp modules and appropriately sets the - // RtpVideoSender to active if any rtp modules are active. - // A module will only send packet if beeing active. - virtual void SetActiveModules(const std::vector& active_modules) = 0; - // Set the sending status of all rtp modules to inactive. - virtual void Stop() = 0; + // Sets weather or not RTP packets is allowed to be sent on this sender. + virtual void SetSending(bool enabled) = 0; virtual bool IsActive() = 0; virtual void OnNetworkAvailability(bool network_available) = 0; diff --git a/call/rtp_video_sender_unittest.cc b/call/rtp_video_sender_unittest.cc index cf099afaa3..72234aa409 100644 --- a/call/rtp_video_sender_unittest.cc +++ b/call/rtp_video_sender_unittest.cc @@ -180,17 +180,13 @@ class RtpVideoSenderTestFixture { /*frame_transformer=*/nullptr, field_trials) {} - ~RtpVideoSenderTestFixture() { Stop(); } + ~RtpVideoSenderTestFixture() { SetSending(false); } RtpVideoSender* router() { return router_.get(); } MockTransport& transport() { return transport_; } void AdvanceTime(TimeDelta delta) { time_controller_.AdvanceTime(delta); } - void Stop() { router_->Stop(); } - - void SetActiveModules(const std::vector& active_modules) { - router_->SetActiveModules(active_modules); - } + void SetSending(bool sending) { router_->SetSending(sending); } private: test::ScopedKeyValueConfig field_trials_; @@ -227,20 +223,20 @@ TEST(RtpVideoSenderTest, SendOnOneModule) { EXPECT_NE(EncodedImageCallback::Result::OK, test.router()->OnEncodedImage(encoded_image, nullptr).error); - test.SetActiveModules({true}); + test.SetSending(true); EXPECT_EQ(EncodedImageCallback::Result::OK, test.router()->OnEncodedImage(encoded_image, nullptr).error); - test.SetActiveModules({false}); + test.SetSending(false); EXPECT_NE(EncodedImageCallback::Result::OK, test.router()->OnEncodedImage(encoded_image, nullptr).error); - test.SetActiveModules({true}); + test.SetSending(true); EXPECT_EQ(EncodedImageCallback::Result::OK, test.router()->OnEncodedImage(encoded_image, nullptr).error); } -TEST(RtpVideoSenderTest, SendSimulcastSetActive) { +TEST(RtpVideoSenderTest, OnEncodedImageReturnOkWhenSendingTrue) { constexpr uint8_t kPayload = 'a'; EncodedImage encoded_image_1; encoded_image_1.SetRtpTimestamp(1); @@ -254,7 +250,7 @@ TEST(RtpVideoSenderTest, SendSimulcastSetActive) { CodecSpecificInfo codec_info; codec_info.codecType = kVideoCodecVP8; - test.SetActiveModules({true, true}); + test.SetSending(true); EXPECT_EQ(EncodedImageCallback::Result::OK, test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); @@ -262,20 +258,9 @@ TEST(RtpVideoSenderTest, SendSimulcastSetActive) { encoded_image_2.SetSimulcastIndex(1); EXPECT_EQ(EncodedImageCallback::Result::OK, test.router()->OnEncodedImage(encoded_image_2, &codec_info).error); - - // Inactive. - test.Stop(); - EXPECT_NE(EncodedImageCallback::Result::OK, - test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); - EXPECT_NE(EncodedImageCallback::Result::OK, - test.router()->OnEncodedImage(encoded_image_2, &codec_info).error); } -// Tests how setting individual rtp modules to active affects the overall -// behavior of the payload router. First sets one module to active and checks -// that outgoing data can be sent on this module, and checks that no data can -// be sent if both modules are inactive. -TEST(RtpVideoSenderTest, SendSimulcastSetActiveModules) { +TEST(RtpVideoSenderTest, OnEncodedImageReturnErrorCodeWhenSendingFalse) { constexpr uint8_t kPayload = 'a'; EncodedImage encoded_image_1; encoded_image_1.SetRtpTimestamp(1); @@ -291,23 +276,15 @@ TEST(RtpVideoSenderTest, SendSimulcastSetActiveModules) { CodecSpecificInfo codec_info; codec_info.codecType = kVideoCodecVP8; - // Only setting one stream to active will still set the payload router to - // active and allow sending data on the active stream. - std::vector active_modules({true, false}); - test.SetActiveModules(active_modules); - EXPECT_EQ(EncodedImageCallback::Result::OK, - test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); - - // Setting both streams to inactive will turn the payload router to + // Setting rtp streams to inactive will turn the payload router to // inactive. - active_modules = {false, false}; - test.SetActiveModules(active_modules); + test.SetSending(false); // An incoming encoded image will not ask the module to send outgoing data // because the payload router is inactive. EXPECT_NE(EncodedImageCallback::Result::OK, test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); EXPECT_NE(EncodedImageCallback::Result::OK, - test.router()->OnEncodedImage(encoded_image_1, &codec_info).error); + test.router()->OnEncodedImage(encoded_image_2, &codec_info).error); } TEST(RtpVideoSenderTest, @@ -324,7 +301,7 @@ TEST(RtpVideoSenderTest, codec_info.codecType = kVideoCodecVP8; RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, kPayloadType, {}); - test.SetActiveModules({true, true}); + test.SetSending(true); // A layer is sent on both rtp streams. test.router()->OnVideoLayersAllocationUpdated( {.active_spatial_layers = {{.rtp_stream_index = 0}, @@ -347,7 +324,7 @@ TEST(RtpVideoSenderTest, TEST(RtpVideoSenderTest, CreateWithNoPreviousStates) { RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, kPayloadType, {}); - test.SetActiveModules({true, true}); + test.SetSending(true); std::map initial_states = test.router()->GetRtpPayloadStates(); @@ -372,7 +349,7 @@ TEST(RtpVideoSenderTest, CreateWithPreviousStates) { RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, kPayloadType, states); - test.SetActiveModules({true, true}); + test.SetSending(true); std::map initial_states = test.router()->GetRtpPayloadStates(); @@ -412,7 +389,7 @@ TEST(RtpVideoSenderTest, FrameCountCallbacks) { test.router()->OnEncodedImage(encoded_image, nullptr).error); ::testing::Mock::VerifyAndClearExpectations(&callback); - test.SetActiveModules({true}); + test.SetSending(true); FrameCounts frame_counts; EXPECT_CALL(callback, FrameCountUpdated(_, kSsrc1)) @@ -441,7 +418,7 @@ TEST(RtpVideoSenderTest, FrameCountCallbacks) { TEST(RtpVideoSenderTest, DoesNotRetrasmitAckedPackets) { RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, kPayloadType, {}); - test.SetActiveModules({true, true}); + test.SetSending(true); constexpr uint8_t kPayload = 'a'; EncodedImage encoded_image; @@ -606,7 +583,7 @@ TEST(RtpVideoSenderTest, RetransmitsOnTransportWideLossInfo) { TEST(RtpVideoSenderTest, EarlyRetransmits) { RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, kPayloadType, {}); - test.SetActiveModules({true, true}); + test.SetSending(true); const uint8_t kPayload[1] = {'a'}; EncodedImage encoded_image; @@ -701,7 +678,7 @@ TEST(RtpVideoSenderTest, EarlyRetransmits) { TEST(RtpVideoSenderTest, SupportsDependencyDescriptor) { RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); - test.SetActiveModules({true}); + test.SetSending(true); RtpHeaderExtensionMap extensions; extensions.Register( @@ -773,7 +750,7 @@ TEST(RtpVideoSenderTest, EXPECT_TRUE(sent_packets.emplace_back(&extensions).Parse(packet)); return true; }); - test.SetActiveModules({true}); + test.SetSending(true); EncodedImage key_frame_image; key_frame_image._frameType = VideoFrameType::kVideoFrameKey; @@ -807,7 +784,7 @@ TEST(RtpVideoSenderTest, TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9) { RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); - test.SetActiveModules({true}); + test.SetSending(true); RtpHeaderExtensionMap extensions; extensions.Register( @@ -863,7 +840,7 @@ TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9) { TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9NotProvidedByEncoder) { RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); - test.SetActiveModules({true}); + test.SetSending(true); RtpHeaderExtensionMap extensions; extensions.Register( @@ -918,7 +895,7 @@ TEST(RtpVideoSenderTest, GenerateDependecyDescriptorForGenericCodecs) { test::ScopedKeyValueConfig field_trials( "WebRTC-GenericCodecDependencyDescriptor/Enabled/"); RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials); - test.SetActiveModules({true}); + test.SetSending(true); RtpHeaderExtensionMap extensions; extensions.Register( @@ -964,7 +941,7 @@ TEST(RtpVideoSenderTest, GenerateDependecyDescriptorForGenericCodecs) { TEST(RtpVideoSenderTest, SupportsStoppingUsingDependencyDescriptor) { RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}); - test.SetActiveModules({true}); + test.SetSending(true); RtpHeaderExtensionMap extensions; extensions.Register( @@ -1049,7 +1026,7 @@ TEST(RtpVideoSenderTest, OverheadIsSubtractedFromTargetBitrate) { kRtpHeaderSizeBytes + kTransportPacketOverheadBytes; RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials); test.router()->OnTransportOverheadChanged(kTransportPacketOverheadBytes); - test.SetActiveModules({true}); + test.SetSending(true); { test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(300000), @@ -1076,7 +1053,7 @@ TEST(RtpVideoSenderTest, OverheadIsSubtractedFromTargetBitrate) { TEST(RtpVideoSenderTest, ClearsPendingPacketsOnInactivation) { RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {}); - test.SetActiveModules({true}); + test.SetSending(true); RtpHeaderExtensionMap extensions; extensions.Register( @@ -1127,13 +1104,13 @@ TEST(RtpVideoSenderTest, ClearsPendingPacketsOnInactivation) { // Disable the sending module and advance time slightly. No packets should be // sent. - test.SetActiveModules({false}); + test.SetSending(false); test.AdvanceTime(TimeDelta::Millis(20)); EXPECT_TRUE(sent_packets.empty()); // Reactive the send module - any packets should have been removed, so nothing // should be transmitted. - test.SetActiveModules({true}); + test.SetSending(true); test.AdvanceTime(TimeDelta::Millis(33)); EXPECT_TRUE(sent_packets.empty()); @@ -1156,7 +1133,7 @@ TEST(RtpVideoSenderTest, ClearsPendingPacketsOnInactivation) { TEST(RtpVideoSenderTest, RetransmitsBaseLayerOnly) { RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2}, kPayloadType, {}); - test.SetActiveModules({true, true}); + test.SetSending(true); test.router()->SetRetransmissionMode(kRetransmitBaseLayer); constexpr uint8_t kPayload = 'a'; diff --git a/call/test/mock_rtp_transport_controller_send.h b/call/test/mock_rtp_transport_controller_send.h index b24e5a59ec..2a0bc233ff 100644 --- a/call/test/mock_rtp_transport_controller_send.h +++ b/call/test/mock_rtp_transport_controller_send.h @@ -50,6 +50,11 @@ class MockRtpTransportControllerSend DestroyRtpVideoSender, (RtpVideoSenderInterface*), (override)); + MOCK_METHOD(void, RegisterSendingRtpStream, (RtpRtcpInterface&), (override)); + MOCK_METHOD(void, + DeRegisterSendingRtpStream, + (RtpRtcpInterface&), + (override)); MOCK_METHOD(PacketRouter*, packet_router, (), (override)); MOCK_METHOD(NetworkStateEstimateObserver*, network_state_estimate_observer, diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc index e5ff2cd727..8c748dd81d 100644 --- a/video/video_send_stream_impl.cc +++ b/video/video_send_stream_impl.cc @@ -627,10 +627,9 @@ bool VideoSendStreamImpl::started() { void VideoSendStreamImpl::Start() { RTC_DCHECK_RUN_ON(&thread_checker_); - const std::vector active_layers(config_.rtp.ssrcs.size(), true); // This sender is allowed to send RTP packets. Start monitoring and allocating // a rate if there is also active encodings. (has_active_encodings_). - rtp_video_sender_->SetActiveModules(active_layers); + rtp_video_sender_->SetSending(true); if (!IsRunning() && has_active_encodings_) { StartupVideoSendStream(); } @@ -681,7 +680,7 @@ void VideoSendStreamImpl::Stop() { return; TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop"); - rtp_video_sender_->Stop(); + rtp_video_sender_->SetSending(false); if (IsRunning()) { StopVideoSendStream(); } diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc index e3a1618939..fe5f999a39 100644 --- a/video/video_send_stream_impl_unittest.cc +++ b/video/video_send_stream_impl_unittest.cc @@ -75,6 +75,7 @@ using ::testing::Invoke; using ::testing::Mock; using ::testing::NiceMock; using ::testing::Return; +using ::testing::SaveArg; constexpr int64_t kDefaultInitialBitrateBps = 333000; const double kDefaultBitratePriority = 0.5; @@ -87,8 +88,7 @@ std::string GetAlrProbingExperimentString() { } class MockRtpVideoSender : public RtpVideoSenderInterface { public: - MOCK_METHOD(void, SetActiveModules, (const std::vector&), (override)); - MOCK_METHOD(void, Stop, (), (override)); + MOCK_METHOD(void, SetSending, (bool sending), (override)); MOCK_METHOD(bool, IsActive, (), (override)); MOCK_METHOD(void, OnNetworkAvailability, (bool), (override)); MOCK_METHOD((std::map), @@ -158,19 +158,11 @@ class VideoSendStreamImplTest : public ::testing::Test { .WillRepeatedly(Return(&packet_router_)); EXPECT_CALL(transport_controller_, CreateRtpVideoSender) .WillRepeatedly(Return(&rtp_video_sender_)); - ON_CALL(rtp_video_sender_, Stop()).WillByDefault(::testing::Invoke([&] { - active_modules_.clear(); + ON_CALL(rtp_video_sender_, IsActive()).WillByDefault(Invoke([&]() { + return rtp_sending_; })); - ON_CALL(rtp_video_sender_, IsActive()) - .WillByDefault(::testing::Invoke([&]() { - for (bool enabled : active_modules_) { - if (enabled) - return true; - } - return false; - })); - ON_CALL(rtp_video_sender_, SetActiveModules) - .WillByDefault(::testing::SaveArg<0>(&active_modules_)); + ON_CALL(rtp_video_sender_, SetSending) + .WillByDefault(SaveArg<0>(&rtp_sending_)); } ~VideoSendStreamImplTest() {} @@ -225,7 +217,7 @@ class VideoSendStreamImplTest : public ::testing::Test { NiceMock bitrate_allocator_; NiceMock* video_stream_encoder_ = nullptr; NiceMock rtp_video_sender_; - std::vector active_modules_; + bool rtp_sending_ = false; RtcEventLogNull event_log_; VideoSendStream::Config config_; From 1dccfeb39589abbe5cafe3cd1fd81addab9a36fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=85sa=20Persson?= Date: Fri, 26 Jan 2024 09:50:23 +0100 Subject: [PATCH 025/170] Set InterLayerPredMode based on scalability mode for VP9. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:15673 Change-Id: I7d3cdcda537c85f3be578cb00452e0611759704f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336280 Commit-Queue: Åsa Persson Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/main@{#41621} --- modules/video_coding/codecs/vp9/svc_config.cc | 3 +++ .../codecs/vp9/svc_config_unittest.cc | 20 ++++++++++++++++++ .../video_codec_initializer_unittest.cc | 21 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/modules/video_coding/codecs/vp9/svc_config.cc b/modules/video_coding/codecs/vp9/svc_config.cc index 7af8cab3cb..555af835a5 100644 --- a/modules/video_coding/codecs/vp9/svc_config.cc +++ b/modules/video_coding/codecs/vp9/svc_config.cc @@ -190,6 +190,9 @@ std::vector GetVp9SvcConfig(VideoCodec& codec) { codec.SetScalabilityMode(limited_scalability_mode); } + codec.VP9()->interLayerPred = + ScalabilityModeToInterLayerPredMode(*scalability_mode); + absl::optional info = ScalabilityStructureConfig(*scalability_mode); if (!info.has_value()) { diff --git a/modules/video_coding/codecs/vp9/svc_config_unittest.cc b/modules/video_coding/codecs/vp9/svc_config_unittest.cc index 1b1abe0f6d..2515b1ce4b 100644 --- a/modules/video_coding/codecs/vp9/svc_config_unittest.cc +++ b/modules/video_coding/codecs/vp9/svc_config_unittest.cc @@ -13,6 +13,7 @@ #include #include +#include "api/video_codecs/video_encoder.h" #include "modules/video_coding/codecs/vp9/include/vp9_globals.h" #include "test/gmock.h" #include "test/gtest.h" @@ -65,6 +66,25 @@ TEST(SvcConfig, NumSpatialLayersWithScalabilityMode) { EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL3T3_KEY); } +TEST(SvcConfig, UpdatesInterLayerPredModeBasedOnScalabilityMode) { + VideoCodec codec; + codec.codecType = kVideoCodecVP9; + codec.width = 1280; + codec.height = 720; + codec.SetScalabilityMode(ScalabilityMode::kL3T3_KEY); + + std::vector spatial_layers = GetVp9SvcConfig(codec); + EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOnKeyPic); + + codec.SetScalabilityMode(ScalabilityMode::kL3T3); + spatial_layers = GetVp9SvcConfig(codec); + EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOn); + + codec.SetScalabilityMode(ScalabilityMode::kS3T3); + spatial_layers = GetVp9SvcConfig(codec); + EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOff); +} + TEST(SvcConfig, NumSpatialLayersLimitedWithScalabilityMode) { VideoCodec codec; codec.codecType = kVideoCodecVP9; diff --git a/modules/video_coding/video_codec_initializer_unittest.cc b/modules/video_coding/video_codec_initializer_unittest.cc index b0edab6004..60ef7aece0 100644 --- a/modules/video_coding/video_codec_initializer_unittest.cc +++ b/modules/video_coding/video_codec_initializer_unittest.cc @@ -631,4 +631,25 @@ TEST_F(VideoCodecInitializerTest, Vp9TwoSpatialLayersBitratesAreConsistent) { codec.spatialLayers[0].maxBitrate); } +TEST_F(VideoCodecInitializerTest, UpdatesVp9SpecificFieldsWithScalabilityMode) { + VideoEncoderConfig config; + config.codec_type = VideoCodecType::kVideoCodecVP9; + std::vector streams = {DefaultStream()}; + streams[0].scalability_mode = ScalabilityMode::kL2T3_KEY; + + VideoCodec codec; + EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec)); + + EXPECT_EQ(codec.VP9()->numberOfSpatialLayers, 2u); + EXPECT_EQ(codec.VP9()->numberOfTemporalLayers, 3u); + EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOnKeyPic); + + streams[0].scalability_mode = ScalabilityMode::kS3T1; + EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec)); + + EXPECT_EQ(codec.VP9()->numberOfSpatialLayers, 3u); + EXPECT_EQ(codec.VP9()->numberOfTemporalLayers, 1u); + EXPECT_EQ(codec.VP9()->interLayerPred, InterLayerPredMode::kOff); +} + } // namespace webrtc From 9c6874607aec46ed9c8ebe2af130a35f1ca36fb6 Mon Sep 17 00:00:00 2001 From: Tony Herre Date: Fri, 26 Jan 2024 11:16:45 +0100 Subject: [PATCH 026/170] Consolidate encoded transform mocks into api/test/ Includes removing the duplicate MockTransformableAudioFrame definition in test/ in favour of the existing one in api/test/ Bug: webrtc:15802 Change-Id: Ib5f86b8b2095dd4e580cd9ff0038134f8a43cd93 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336340 Auto-Submit: Tony Herre Commit-Queue: Stefan Holmer Reviewed-by: Stefan Holmer Cr-Commit-Position: refs/heads/main@{#41622} --- api/BUILD.gn | 10 +++++ {test => api/test}/mock_frame_transformer.h | 6 +-- audio/BUILD.gn | 6 +-- ...ive_frame_transformer_delegate_unittest.cc | 4 +- audio/channel_receive_unittest.cc | 2 +- ...end_frame_transformer_delegate_unittest.cc | 4 +- audio/channel_send_unittest.cc | 2 +- call/BUILD.gn | 2 +- call/rtp_video_sender_unittest.cc | 2 +- modules/rtp_rtcp/BUILD.gn | 4 +- .../frame_transformer_factory_unittest.cc | 2 +- ...deo_frame_transformer_delegate_unittest.cc | 2 +- .../source/rtp_sender_video_unittest.cc | 2 +- ...ver_frame_transformer_delegate_unittest.cc | 2 +- test/BUILD.gn | 22 ---------- test/mock_transformable_frame.h | 41 ------------------- video/BUILD.gn | 2 +- video/rtp_video_stream_receiver2_unittest.cc | 2 +- 18 files changed, 32 insertions(+), 85 deletions(-) rename {test => api/test}/mock_frame_transformer.h (90%) delete mode 100644 test/mock_transformable_frame.h diff --git a/api/BUILD.gn b/api/BUILD.gn index 08e33ca92e..dce687e76b 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -1151,6 +1151,16 @@ if (rtc_include_tests) { ] } + rtc_library("mock_frame_transformer") { + visibility = [ "*" ] + testonly = true + sources = [ "test/mock_frame_transformer.h" ] + deps = [ + ":frame_transformer_interface", + "../test:test_support", + ] + } + rtc_library("mock_encoder_selector") { visibility = [ "*" ] testonly = true diff --git a/test/mock_frame_transformer.h b/api/test/mock_frame_transformer.h similarity index 90% rename from test/mock_frame_transformer.h rename to api/test/mock_frame_transformer.h index 617cda8a43..8f438bdf9e 100644 --- a/test/mock_frame_transformer.h +++ b/api/test/mock_frame_transformer.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef TEST_MOCK_FRAME_TRANSFORMER_H_ -#define TEST_MOCK_FRAME_TRANSFORMER_H_ +#ifndef API_TEST_MOCK_FRAME_TRANSFORMER_H_ +#define API_TEST_MOCK_FRAME_TRANSFORMER_H_ #include #include @@ -42,4 +42,4 @@ class MockFrameTransformer : public FrameTransformerInterface { } // namespace webrtc -#endif // TEST_MOCK_FRAME_TRANSFORMER_H_ +#endif // API_TEST_MOCK_FRAME_TRANSFORMER_H_ diff --git a/audio/BUILD.gn b/audio/BUILD.gn index 7ece107407..8679790903 100644 --- a/audio/BUILD.gn +++ b/audio/BUILD.gn @@ -167,6 +167,8 @@ if (rtc_include_tests) { "../api:mock_audio_mixer", "../api:mock_frame_decryptor", "../api:mock_frame_encryptor", + "../api:mock_frame_transformer", + "../api:mock_transformable_audio_frame", "../api:scoped_refptr", "../api/audio:audio_frame_api", "../api/audio_codecs:audio_codecs_api", @@ -210,8 +212,6 @@ if (rtc_include_tests) { "../system_wrappers", "../test:audio_codec_mocks", "../test:field_trial", - "../test:mock_frame_transformer", - "../test:mock_transformable_frame", "../test:mock_transport", "../test:rtp_test_utils", "../test:run_loop", @@ -234,6 +234,7 @@ if (rtc_include_tests) { sources = [ "channel_receive_unittest.cc" ] deps = [ ":audio", + "../api:mock_frame_transformer", "../api/audio_codecs:builtin_audio_decoder_factory", "../api/crypto:frame_decryptor_interface", "../api/task_queue:default_task_queue_factory", @@ -245,7 +246,6 @@ if (rtc_include_tests) { "../rtc_base:logging", "../rtc_base:threading", "../test:audio_codec_mocks", - "../test:mock_frame_transformer", "../test:mock_transport", "../test:test_support", "../test/time_controller", diff --git a/audio/channel_receive_frame_transformer_delegate_unittest.cc b/audio/channel_receive_frame_transformer_delegate_unittest.cc index 8bdf217d5a..a206a09f99 100644 --- a/audio/channel_receive_frame_transformer_delegate_unittest.cc +++ b/audio/channel_receive_frame_transformer_delegate_unittest.cc @@ -13,11 +13,11 @@ #include #include +#include "api/test/mock_frame_transformer.h" +#include "api/test/mock_transformable_audio_frame.h" #include "audio/channel_send_frame_transformer_delegate.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" -#include "test/mock_transformable_frame.h" namespace webrtc { namespace { diff --git a/audio/channel_receive_unittest.cc b/audio/channel_receive_unittest.cc index aab8a95d8b..8ca1e9e32b 100644 --- a/audio/channel_receive_unittest.cc +++ b/audio/channel_receive_unittest.cc @@ -14,6 +14,7 @@ #include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/crypto/frame_decryptor_interface.h" #include "api/task_queue/default_task_queue_factory.h" +#include "api/test/mock_frame_transformer.h" #include "logging/rtc_event_log/mock/mock_rtc_event_log.h" #include "modules/audio_device/include/audio_device.h" #include "modules/audio_device/include/mock_audio_device.h" @@ -29,7 +30,6 @@ #include "test/gmock.h" #include "test/gtest.h" #include "test/mock_audio_decoder_factory.h" -#include "test/mock_frame_transformer.h" #include "test/mock_transport.h" #include "test/time_controller/simulated_time_controller.h" diff --git a/audio/channel_send_frame_transformer_delegate_unittest.cc b/audio/channel_send_frame_transformer_delegate_unittest.cc index 483a2cce78..5295e2657f 100644 --- a/audio/channel_send_frame_transformer_delegate_unittest.cc +++ b/audio/channel_send_frame_transformer_delegate_unittest.cc @@ -15,11 +15,11 @@ #include #include "absl/memory/memory.h" +#include "api/test/mock_frame_transformer.h" +#include "api/test/mock_transformable_audio_frame.h" #include "rtc_base/task_queue_for_test.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" -#include "test/mock_transformable_frame.h" namespace webrtc { namespace { diff --git a/audio/channel_send_unittest.cc b/audio/channel_send_unittest.cc index c86dcefadc..77d8479519 100644 --- a/audio/channel_send_unittest.cc +++ b/audio/channel_send_unittest.cc @@ -17,12 +17,12 @@ #include "api/environment/environment.h" #include "api/environment/environment_factory.h" #include "api/scoped_refptr.h" +#include "api/test/mock_frame_transformer.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "call/rtp_transport_controller_send.h" #include "rtc_base/gunit.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" #include "test/mock_transport.h" #include "test/scoped_key_value_config.h" #include "test/time_controller/simulated_time_controller.h" diff --git a/call/BUILD.gn b/call/BUILD.gn index 32ebc2e9cf..8af3eac754 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -481,6 +481,7 @@ if (rtc_include_tests) { "../api:array_view", "../api:create_frame_generator", "../api:mock_audio_mixer", + "../api:mock_frame_transformer", "../api:rtp_headers", "../api:rtp_parameters", "../api:transport_api", @@ -525,7 +526,6 @@ if (rtc_include_tests) { "../test:fake_video_codecs", "../test:field_trial", "../test:frame_generator_capturer", - "../test:mock_frame_transformer", "../test:mock_transport", "../test:run_loop", "../test:scoped_key_value_config", diff --git a/call/rtp_video_sender_unittest.cc b/call/rtp_video_sender_unittest.cc index 72234aa409..cd525f0d61 100644 --- a/call/rtp_video_sender_unittest.cc +++ b/call/rtp_video_sender_unittest.cc @@ -18,6 +18,7 @@ #include "absl/functional/any_invocable.h" #include "api/environment/environment.h" #include "api/environment/environment_factory.h" +#include "api/test/mock_frame_transformer.h" #include "call/rtp_transport_controller_send.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/byte_io.h" @@ -29,7 +30,6 @@ #include "rtc_base/rate_limiter.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" #include "test/mock_transport.h" #include "test/scenario/scenario.h" #include "test/scoped_key_value_config.h" diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index b471c2fa76..2c0a19e995 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -652,6 +652,7 @@ if (rtc_include_tests) { "../../api:frame_transformer_factory", "../../api:make_ref_counted", "../../api:mock_frame_encryptor", + "../../api:mock_frame_transformer", "../../api:mock_transformable_video_frame", "../../api:rtp_headers", "../../api:rtp_packet_info", @@ -698,7 +699,6 @@ if (rtc_include_tests) { "../../rtc_base:timeutils", "../../system_wrappers", "../../test:explicit_key_value_config", - "../../test:mock_frame_transformer", "../../test:mock_transport", "../../test:rtp_test_utils", "../../test:run_loop", @@ -720,13 +720,13 @@ if (rtc_include_tests) { sources = [ "source/frame_transformer_factory_unittest.cc" ] deps = [ "../../api:frame_transformer_factory", + "../../api:mock_frame_transformer", "../../api:mock_transformable_audio_frame", "../../api:mock_transformable_video_frame", "../../api:transport_api", "../../call:video_stream_api", "../../modules/rtp_rtcp", "../../rtc_base:rtc_event", - "../../test:mock_frame_transformer", "../../test:test_support", "../../video", ] diff --git a/modules/rtp_rtcp/source/frame_transformer_factory_unittest.cc b/modules/rtp_rtcp/source/frame_transformer_factory_unittest.cc index a61179e9d3..788052da39 100644 --- a/modules/rtp_rtcp/source/frame_transformer_factory_unittest.cc +++ b/modules/rtp_rtcp/source/frame_transformer_factory_unittest.cc @@ -17,6 +17,7 @@ #include "absl/memory/memory.h" #include "api/call/transport.h" +#include "api/test/mock_frame_transformer.h" #include "api/test/mock_transformable_audio_frame.h" #include "api/test/mock_transformable_video_frame.h" #include "call/video_receive_stream.h" @@ -24,7 +25,6 @@ #include "rtc_base/event.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" namespace webrtc { namespace { diff --git a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc index 6790fc3a71..586836a90e 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video_frame_transformer_delegate_unittest.cc @@ -12,11 +12,11 @@ #include +#include "api/test/mock_frame_transformer.h" #include "api/test/mock_transformable_video_frame.h" #include "rtc_base/event.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" #include "test/time_controller/simulated_time_controller.h" namespace webrtc { diff --git a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc index 9641d617d9..112a2979fd 100644 --- a/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_sender_video_unittest.cc @@ -21,6 +21,7 @@ #include "api/task_queue/task_queue_base.h" #include "api/task_queue/task_queue_factory.h" #include "api/test/mock_frame_encryptor.h" +#include "api/test/mock_frame_transformer.h" #include "api/transport/rtp/dependency_descriptor.h" #include "api/units/timestamp.h" #include "api/video/video_codec_constants.h" @@ -46,7 +47,6 @@ #include "test/explicit_key_value_config.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" #include "test/time_controller/simulated_time_controller.h" namespace webrtc { diff --git a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc index cf3062610f..192e239535 100644 --- a/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_video_stream_receiver_frame_transformer_delegate_unittest.cc @@ -17,6 +17,7 @@ #include "absl/memory/memory.h" #include "api/call/transport.h" +#include "api/test/mock_frame_transformer.h" #include "api/test/mock_transformable_video_frame.h" #include "api/units/timestamp.h" #include "call/video_receive_stream.h" @@ -24,7 +25,6 @@ #include "rtc_base/event.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" namespace webrtc { namespace { diff --git a/test/BUILD.gn b/test/BUILD.gn index d6b2b989ad..185f12c3ed 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -1101,28 +1101,6 @@ rtc_source_set("test_renderer") { } } -rtc_library("mock_frame_transformer") { - visibility = [ "*" ] - testonly = true - sources = [ "mock_frame_transformer.h" ] - deps = [ - "../api:frame_transformer_interface", - "../test:test_support", - ] -} - -rtc_library("mock_transformable_frame") { - visibility = [ "*" ] - - testonly = true - sources = [ "mock_transformable_frame.h" ] - - deps = [ - "../api:frame_transformer_interface", - "../test:test_support", - ] -} - if (is_mac) { rtc_library("test_renderer_objc") { testonly = true diff --git a/test/mock_transformable_frame.h b/test/mock_transformable_frame.h deleted file mode 100644 index 26eb6b7030..0000000000 --- a/test/mock_transformable_frame.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef TEST_MOCK_TRANSFORMABLE_FRAME_H_ -#define TEST_MOCK_TRANSFORMABLE_FRAME_H_ - -#include "api/frame_transformer_interface.h" -#include "test/gmock.h" - -namespace webrtc { - -class MockTransformableAudioFrame : public TransformableAudioFrameInterface { - public: - MOCK_METHOD(rtc::ArrayView, GetData, (), (const, override)); - MOCK_METHOD(rtc::ArrayView, - GetContributingSources, - (), - (const, override)); - MOCK_METHOD(absl::optional, - AbsoluteCaptureTimestamp, - (), - (const, override)); - MOCK_METHOD(void, SetData, (rtc::ArrayView), (override)); - MOCK_METHOD(uint8_t, GetPayloadType, (), (const, override)); - MOCK_METHOD(uint32_t, GetSsrc, (), (const, override)); - MOCK_METHOD(uint32_t, GetTimestamp, (), (const, override)); - MOCK_METHOD(void, SetRTPTimestamp, (uint32_t), (override)); - MOCK_METHOD(Direction, GetDirection, (), (const, override)); - MOCK_METHOD(std::string, GetMimeType, (), (const, override)); -}; - -} // namespace webrtc - -#endif // TEST_MOCK_TRANSFORMABLE_FRAME_H_ diff --git a/video/BUILD.gn b/video/BUILD.gn index 0891a31f7b..5a114c5fb7 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -830,6 +830,7 @@ if (rtc_include_tests) { "../api:libjingle_peerconnection_api", "../api:mock_fec_controller_override", "../api:mock_frame_decryptor", + "../api:mock_frame_transformer", "../api:mock_video_codec_factory", "../api:mock_video_decoder", "../api:mock_video_encoder", @@ -947,7 +948,6 @@ if (rtc_include_tests) { "../test:fileutils", "../test:frame_generator_capturer", "../test:frame_utils", - "../test:mock_frame_transformer", "../test:mock_transport", "../test:null_transport", "../test:rtp_test_utils", diff --git a/video/rtp_video_stream_receiver2_unittest.cc b/video/rtp_video_stream_receiver2_unittest.cc index f039bf29b1..6962540152 100644 --- a/video/rtp_video_stream_receiver2_unittest.cc +++ b/video/rtp_video_stream_receiver2_unittest.cc @@ -14,6 +14,7 @@ #include #include "api/task_queue/task_queue_base.h" +#include "api/test/mock_frame_transformer.h" #include "api/video/video_codec_type.h" #include "api/video/video_frame_type.h" #include "call/test/mock_rtp_packet_sink_interface.h" @@ -35,7 +36,6 @@ #include "system_wrappers/include/clock.h" #include "test/gmock.h" #include "test/gtest.h" -#include "test/mock_frame_transformer.h" #include "test/mock_transport.h" #include "test/rtcp_packet_parser.h" #include "test/scoped_key_value_config.h" From 698b4e7087899211e400e4a77debc22f1994d3ff Mon Sep 17 00:00:00 2001 From: Tommi Date: Wed, 24 Jan 2024 08:36:45 +0100 Subject: [PATCH 027/170] Update more Candidate type checkers to use Candidate::is_* This is a follow up to a previous CL that removed direct dependency on the `cricket::` string globals. Bug: none Change-Id: I4d839a36739fc4694ce81b72ee036e83dae580df Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335420 Reviewed-by: Harald Alvestrand Commit-Queue: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41623} --- p2p/base/basic_ice_controller.cc | 4 +- p2p/base/connection.cc | 16 +- p2p/base/p2p_transport_channel_unittest.cc | 199 +++++++++----------- p2p/base/port.cc | 20 +- p2p/base/port.h | 9 +- p2p/base/stun_port_unittest.cc | 2 +- p2p/base/tcp_port.cc | 3 +- p2p/client/basic_port_allocator_unittest.cc | 43 ++--- pc/jsep_transport_controller.cc | 2 +- pc/peer_connection.cc | 71 +++---- pc/peer_connection_integrationtest.cc | 14 +- pc/rtc_stats_collector.cc | 8 +- 12 files changed, 174 insertions(+), 217 deletions(-) diff --git a/p2p/base/basic_ice_controller.cc b/p2p/base/basic_ice_controller.cc index 182845cdd7..f5b3eca3a4 100644 --- a/p2p/base/basic_ice_controller.cc +++ b/p2p/base/basic_ice_controller.cc @@ -16,8 +16,8 @@ namespace { const int kMinImprovement = 10; bool IsRelayRelay(const cricket::Connection* conn) { - return conn->local_candidate().type() == cricket::RELAY_PORT_TYPE && - conn->remote_candidate().type() == cricket::RELAY_PORT_TYPE; + return conn->local_candidate().is_relay() && + conn->remote_candidate().is_relay(); } bool IsUdp(const cricket::Connection* conn) { diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc index 9dd8a80631..a2e3dfce41 100644 --- a/p2p/base/connection.cc +++ b/p2p/base/connection.cc @@ -75,14 +75,14 @@ inline bool TooLongWithoutResponse( // Helper methods for converting string values of log description fields to // enum. -webrtc::IceCandidateType GetCandidateTypeByString(absl::string_view type) { - if (type == LOCAL_PORT_TYPE) { +webrtc::IceCandidateType GetRtcEventLogCandidateType(const Candidate& c) { + if (c.is_local()) { return webrtc::IceCandidateType::kLocal; - } else if (type == STUN_PORT_TYPE) { + } else if (c.is_stun()) { return webrtc::IceCandidateType::kStun; - } else if (type == PRFLX_PORT_TYPE) { + } else if (c.is_prflx()) { return webrtc::IceCandidateType::kPrflx; - } else if (type == RELAY_PORT_TYPE) { + } else if (c.is_relay()) { return webrtc::IceCandidateType::kRelay; } return webrtc::IceCandidateType::kUnknown; @@ -1367,15 +1367,13 @@ const webrtc::IceCandidatePairDescription& Connection::ToLogDescription() { const Candidate& remote = remote_candidate(); const rtc::Network* network = port()->Network(); log_description_ = webrtc::IceCandidatePairDescription(); - log_description_->local_candidate_type = - GetCandidateTypeByString(local.type()); + log_description_->local_candidate_type = GetRtcEventLogCandidateType(local); log_description_->local_relay_protocol = GetProtocolByString(local.relay_protocol()); log_description_->local_network_type = ConvertNetworkType(network->type()); log_description_->local_address_family = GetAddressFamilyByInt(local.address().family()); - log_description_->remote_candidate_type = - GetCandidateTypeByString(remote.type()); + log_description_->remote_candidate_type = GetRtcEventLogCandidateType(remote); log_description_->remote_address_family = GetAddressFamilyByInt(remote.address().family()); log_description_->candidate_pair_protocol = diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index a0446c7965..e701998e27 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -599,7 +599,7 @@ class P2PTransportChannelTestBase : public ::testing::Test, return GetEndpoint(endpoint)->SetAllowTcpListen(allow_tcp_listen); } - // Return true if the approprite parts of the expected Result, based + // Return true if the appropriate parts of the expected Result, based // on the local and remote candidate of ep1_ch1, match. This can be // used in an EXPECT_TRUE_WAIT. bool CheckCandidate1(const Result& expected) { @@ -613,7 +613,7 @@ class P2PTransportChannelTestBase : public ::testing::Test, remote_type == expected.controlled_type); } - // EXPECT_EQ on the approprite parts of the expected Result, based + // EXPECT_EQ on the appropriate parts of the expected Result, based // on the local and remote candidate of ep1_ch1. This is like // CheckCandidate1, except that it will provide more detail about // what didn't match. @@ -632,7 +632,7 @@ class P2PTransportChannelTestBase : public ::testing::Test, EXPECT_EQ(expected.controlled_protocol, remote_protocol); } - // Return true if the approprite parts of the expected Result, based + // Return true if the appropriate parts of the expected Result, based // on the local and remote candidate of ep2_ch1, match. This can be // used in an EXPECT_TRUE_WAIT. bool CheckCandidate2(const Result& expected) { @@ -646,7 +646,7 @@ class P2PTransportChannelTestBase : public ::testing::Test, remote_type == expected.controlling_type); } - // EXPECT_EQ on the approprite parts of the expected Result, based + // EXPECT_EQ on the appropriate parts of the expected Result, based // on the local and remote candidate of ep2_ch1. This is like // CheckCandidate2, except that it will provide more detail about // what didn't match. @@ -839,7 +839,7 @@ class P2PTransportChannelTestBase : public ::testing::Test, // We pass the candidates directly to the other side. void OnCandidateGathered(IceTransportInternal* ch, const Candidate& c) { - if (force_relay_ && c.type() != RELAY_PORT_TYPE) + if (force_relay_ && !c.is_relay()) return; if (GetEndpoint(ch)->save_candidates_) { @@ -1571,16 +1571,16 @@ TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignaling) { ASSERT_TRUE_WAIT( (selected_connection = ep1_ch1()->selected_connection()) != nullptr, kMediumTimeout); - EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type()); + EXPECT_TRUE(selected_connection->remote_candidate().is_prflx()); EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username()); EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password()); EXPECT_EQ(1u, selected_connection->remote_candidate().generation()); ResumeCandidates(1); // Verify ep1's selected connection is updated to use the 'local' candidate. - EXPECT_EQ_WAIT(LOCAL_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type(), - kMediumTimeout); + EXPECT_TRUE_WAIT( + ep1_ch1()->selected_connection()->remote_candidate().is_local(), + kMediumTimeout); EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection()); DestroyChannels(); } @@ -1608,15 +1608,15 @@ TEST_F(P2PTransportChannelTest, PeerReflexiveRemoteCandidateIsSanitized) { // Check the selected candidate pair. auto pair_ep1 = ep1_ch1()->GetSelectedCandidatePair(); ASSERT_TRUE(pair_ep1.has_value()); - EXPECT_EQ(PRFLX_PORT_TYPE, pair_ep1->remote_candidate().type()); + EXPECT_TRUE(pair_ep1->remote_candidate().is_prflx()); EXPECT_TRUE(pair_ep1->remote_candidate().address().ipaddr().IsNil()); IceTransportStats ice_transport_stats; ep1_ch1()->GetStats(&ice_transport_stats); // Check the candidate pair stats. ASSERT_EQ(1u, ice_transport_stats.connection_infos.size()); - EXPECT_EQ(PRFLX_PORT_TYPE, - ice_transport_stats.connection_infos[0].remote_candidate.type()); + EXPECT_TRUE( + ice_transport_stats.connection_infos[0].remote_candidate.is_prflx()); EXPECT_TRUE(ice_transport_stats.connection_infos[0] .remote_candidate.address() .ipaddr() @@ -1626,8 +1626,7 @@ TEST_F(P2PTransportChannelTest, PeerReflexiveRemoteCandidateIsSanitized) { ResumeCandidates(1); ASSERT_TRUE_WAIT( ep1_ch1()->selected_connection() != nullptr && - ep1_ch1()->selected_connection()->remote_candidate().type() == - LOCAL_PORT_TYPE, + ep1_ch1()->selected_connection()->remote_candidate().is_local(), kMediumTimeout); // We should be able to reveal the address after it is learnt via @@ -1636,14 +1635,14 @@ TEST_F(P2PTransportChannelTest, PeerReflexiveRemoteCandidateIsSanitized) { // Check the selected candidate pair. auto updated_pair_ep1 = ep1_ch1()->GetSelectedCandidatePair(); ASSERT_TRUE(updated_pair_ep1.has_value()); - EXPECT_EQ(LOCAL_PORT_TYPE, updated_pair_ep1->remote_candidate().type()); + EXPECT_TRUE(updated_pair_ep1->remote_candidate().is_local()); EXPECT_TRUE(HasRemoteAddress(&updated_pair_ep1.value(), kPublicAddrs[1])); ep1_ch1()->GetStats(&ice_transport_stats); // Check the candidate pair stats. ASSERT_EQ(1u, ice_transport_stats.connection_infos.size()); - EXPECT_EQ(LOCAL_PORT_TYPE, - ice_transport_stats.connection_infos[0].remote_candidate.type()); + EXPECT_TRUE( + ice_transport_stats.connection_infos[0].remote_candidate.is_local()); EXPECT_TRUE(ice_transport_stats.connection_infos[0] .remote_candidate.address() .EqualIPs(kPublicAddrs[1])); @@ -1679,16 +1678,16 @@ TEST_F(P2PTransportChannelTest, PeerReflexiveCandidateBeforeSignalingWithNAT) { ASSERT_TRUE_WAIT( (selected_connection = ep1_ch1()->selected_connection()) != nullptr, kMediumTimeout); - EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type()); + EXPECT_TRUE(selected_connection->remote_candidate().is_prflx()); EXPECT_EQ(kIceUfrag[1], selected_connection->remote_candidate().username()); EXPECT_EQ(kIcePwd[1], selected_connection->remote_candidate().password()); EXPECT_EQ(1u, selected_connection->remote_candidate().generation()); ResumeCandidates(1); - EXPECT_EQ_WAIT(PRFLX_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type(), - kMediumTimeout); + EXPECT_TRUE_WAIT( + ep1_ch1()->selected_connection()->remote_candidate().is_prflx(), + kMediumTimeout); EXPECT_EQ(selected_connection, ep1_ch1()->selected_connection()); DestroyChannels(); } @@ -1728,9 +1727,9 @@ TEST_F(P2PTransportChannelTest, // The caller should have the selected connection connected to the peer // reflexive candidate. - EXPECT_EQ_WAIT(PRFLX_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type(), - kDefaultTimeout); + EXPECT_TRUE_WAIT( + ep1_ch1()->selected_connection()->remote_candidate().is_prflx(), + kDefaultTimeout); const Connection* prflx_selected_connection = ep1_ch1()->selected_connection(); @@ -1744,9 +1743,9 @@ TEST_F(P2PTransportChannelTest, // their information to update the peer reflexive candidate. ResumeCandidates(1); - EXPECT_EQ_WAIT(RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type(), - kDefaultTimeout); + EXPECT_TRUE_WAIT( + ep1_ch1()->selected_connection()->remote_candidate().is_relay(), + kDefaultTimeout); EXPECT_EQ(prflx_selected_connection, ep1_ch1()->selected_connection()); DestroyChannels(); } @@ -2021,10 +2020,10 @@ TEST_F(P2PTransportChannelTest, TestForceTurn) { EXPECT_TRUE(ep1_ch1()->selected_connection() && ep2_ch1()->selected_connection()); - EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type()); - EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type()); - EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep2_ch1())->type()); - EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep2_ch1())->type()); + EXPECT_TRUE(RemoteCandidate(ep1_ch1())->is_relay()); + EXPECT_TRUE(LocalCandidate(ep1_ch1())->is_relay()); + EXPECT_TRUE(RemoteCandidate(ep2_ch1())->is_relay()); + EXPECT_TRUE(LocalCandidate(ep2_ch1())->is_relay()); TestSendRecv(&clock); DestroyChannels(); @@ -2172,8 +2171,8 @@ TEST_F(P2PTransportChannelTest, TurnToTurnPresumedWritable) { // Expect that the TURN-TURN candidate pair will be prioritized since it's // "probably writable". EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kShortTimeout); - EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type()); - EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type()); + EXPECT_TRUE(LocalCandidate(ep1_ch1())->is_relay()); + EXPECT_TRUE(RemoteCandidate(ep1_ch1())->is_relay()); // Also expect that the channel instantly indicates that it's writable since // it has a TURN-TURN pair. EXPECT_TRUE(ep1_ch1()->writable()); @@ -2220,8 +2219,8 @@ TEST_F(P2PTransportChannelTest, TurnToPrflxPresumedWritable) { EXPECT_TRUE_SIMULATED_WAIT(ep1_ch1()->receiving() && ep1_ch1()->writable(), kShortTimeout, fake_clock); ASSERT_NE(nullptr, ep1_ch1()->selected_connection()); - EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type()); - EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type()); + EXPECT_TRUE(LocalCandidate(ep1_ch1())->is_relay()); + EXPECT_TRUE(RemoteCandidate(ep1_ch1())->is_prflx()); // Make sure that at this point the connection is only presumed writable, // not fully writable. EXPECT_FALSE(ep1_ch1()->selected_connection()->writable()); @@ -2265,8 +2264,8 @@ TEST_F(P2PTransportChannelTest, PresumedWritablePreferredOverUnreliable) { // port available to make a TURN<->TURN pair that's presumed writable. ep1_ch1()->AddRemoteCandidate( CreateUdpCandidate(RELAY_PORT_TYPE, "2.2.2.2", 2, 0)); - EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type()); - EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type()); + EXPECT_TRUE(LocalCandidate(ep1_ch1())->is_relay()); + EXPECT_TRUE(RemoteCandidate(ep1_ch1())->is_relay()); EXPECT_TRUE(ep1_ch1()->writable()); EXPECT_TRUE(GetEndpoint(0)->ready_to_send_); EXPECT_NE(old_selected_connection, ep1_ch1()->selected_connection()); @@ -2293,8 +2292,8 @@ TEST_F(P2PTransportChannelTest, SignalReadyToSendWithPresumedWritable) { CreateUdpCandidate(RELAY_PORT_TYPE, "1.1.1.1", 1, 0)); // Sanity checking the type of the connection. EXPECT_TRUE_WAIT(ep1_ch1()->selected_connection() != nullptr, kShortTimeout); - EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type()); - EXPECT_EQ(RELAY_PORT_TYPE, RemoteCandidate(ep1_ch1())->type()); + EXPECT_TRUE(LocalCandidate(ep1_ch1())->is_relay()); + EXPECT_TRUE(RemoteCandidate(ep1_ch1())->is_relay()); // Tell the socket server to block packets (returning EWOULDBLOCK). virtual_socket_server()->SetSendingBlocked(true); @@ -2349,8 +2348,8 @@ TEST_F(P2PTransportChannelTest, ASSERT_NE(nullptr, ep1_ch1()->selected_connection()); - EXPECT_EQ(RELAY_PORT_TYPE, LocalCandidate(ep1_ch1())->type()); - EXPECT_EQ(PRFLX_PORT_TYPE, RemoteCandidate(ep1_ch1())->type()); + EXPECT_TRUE(LocalCandidate(ep1_ch1())->is_relay()); + EXPECT_TRUE(RemoteCandidate(ep1_ch1())->is_prflx()); DestroyChannels(); } @@ -5041,22 +5040,22 @@ TEST_F(P2PTransportChannelMostLikelyToWorkFirstTest, // Relay/Relay should be the first pingable connection. Connection* conn = FindNextPingableConnectionAndPingIt(&ch); ASSERT_TRUE(conn != nullptr); - EXPECT_EQ(conn->local_candidate().type(), RELAY_PORT_TYPE); - EXPECT_EQ(conn->remote_candidate().type(), RELAY_PORT_TYPE); + EXPECT_TRUE(conn->local_candidate().is_relay()); + EXPECT_TRUE(conn->remote_candidate().is_relay()); // Unless that we have a trigger check waiting to be pinged. Connection* conn2 = WaitForConnectionTo(&ch, "2.2.2.2", 2); ASSERT_TRUE(conn2 != nullptr); - EXPECT_EQ(conn2->local_candidate().type(), LOCAL_PORT_TYPE); - EXPECT_EQ(conn2->remote_candidate().type(), LOCAL_PORT_TYPE); + EXPECT_TRUE(conn2->local_candidate().is_local()); + EXPECT_TRUE(conn2->remote_candidate().is_local()); conn2->ReceivedPing(); EXPECT_EQ(conn2, FindNextPingableConnectionAndPingIt(&ch)); // Make conn3 the selected connection. Connection* conn3 = WaitForConnectionTo(&ch, "1.1.1.1", 1); ASSERT_TRUE(conn3 != nullptr); - EXPECT_EQ(conn3->local_candidate().type(), LOCAL_PORT_TYPE); - EXPECT_EQ(conn3->remote_candidate().type(), RELAY_PORT_TYPE); + EXPECT_TRUE(conn3->local_candidate().is_local()); + EXPECT_TRUE(conn3->remote_candidate().is_relay()); conn3->ReceivedPingResponse(LOW_RTT, "id"); ASSERT_TRUE(conn3->writable()); conn3->ReceivedPing(); @@ -5266,16 +5265,16 @@ TEST_F(P2PTransportChannelTest, ASSERT_TRUE_WAIT( (selected_connection = ep2_ch1()->selected_connection()) != nullptr, kMediumTimeout); - EXPECT_EQ(PRFLX_PORT_TYPE, selected_connection->remote_candidate().type()); + EXPECT_TRUE(selected_connection->remote_candidate().is_prflx()); EXPECT_EQ(kIceUfrag[0], selected_connection->remote_candidate().username()); EXPECT_EQ(kIcePwd[0], selected_connection->remote_candidate().password()); // Set expectation before ep1 signals a hostname candidate. resolver_fixture.SetAddressToReturn(local_address); ResumeCandidates(0); // Verify ep2's selected connection is updated to use the 'local' candidate. - EXPECT_EQ_WAIT(LOCAL_PORT_TYPE, - ep2_ch1()->selected_connection()->remote_candidate().type(), - kMediumTimeout); + EXPECT_TRUE_WAIT( + ep2_ch1()->selected_connection()->remote_candidate().is_local(), + kMediumTimeout); EXPECT_EQ(selected_connection, ep2_ch1()->selected_connection()); DestroyChannels(); @@ -5328,16 +5327,15 @@ TEST_F(P2PTransportChannelTest, // There is a caveat in our implementation associated with this expectation. // See the big comment in P2PTransportChannel::OnUnknownAddress. ASSERT_TRUE_WAIT(ep2_ch1()->selected_connection() != nullptr, kMediumTimeout); - EXPECT_EQ(PRFLX_PORT_TYPE, - ep2_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep2_ch1()->selected_connection()->remote_candidate().is_prflx()); // ep2 should also be able resolve the hostname candidate. The resolved remote // host candidate should be merged with the prflx remote candidate. resolver_fixture.FireDelayedResolution(); - EXPECT_EQ_WAIT(LOCAL_PORT_TYPE, - ep2_ch1()->selected_connection()->remote_candidate().type(), - kMediumTimeout); + EXPECT_TRUE_WAIT( + ep2_ch1()->selected_connection()->remote_candidate().is_local(), + kMediumTimeout); EXPECT_EQ(1u, ep2_ch1()->remote_candidates().size()); DestroyChannels(); @@ -5380,10 +5378,8 @@ TEST_F(P2PTransportChannelTest, CanConnectWithHostCandidateWithMdnsName) { // with a peer reflexive candidate from ep2. ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr, kMediumTimeout); - EXPECT_EQ(LOCAL_PORT_TYPE, - ep1_ch1()->selected_connection()->local_candidate().type()); - EXPECT_EQ(PRFLX_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->local_candidate().is_local()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->remote_candidate().is_prflx()); DestroyChannels(); } @@ -5713,10 +5709,8 @@ TEST_F(P2PTransportChannelTest, // We should be able to form a srflx-host connection to ep2. ASSERT_TRUE_WAIT((ep1_ch1()->selected_connection()) != nullptr, kMediumTimeout); - EXPECT_EQ(STUN_PORT_TYPE, - ep1_ch1()->selected_connection()->local_candidate().type()); - EXPECT_EQ(LOCAL_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->local_candidate().is_stun()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->remote_candidate().is_local()); DestroyChannels(); } @@ -5747,31 +5741,25 @@ TEST_F(P2PTransportChannelTest, kDefaultTimeout, clock); ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr, kDefaultTimeout, clock); - EXPECT_EQ(RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->local_candidate().type()); - EXPECT_EQ(RELAY_PORT_TYPE, - ep2_ch1()->selected_connection()->local_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->local_candidate().is_relay()); + EXPECT_TRUE(ep2_ch1()->selected_connection()->local_candidate().is_relay()); // Loosen the candidate filter at ep1. ep1->allocator_->SetCandidateFilter(CF_ALL); EXPECT_TRUE_SIMULATED_WAIT( ep1_ch1()->selected_connection() != nullptr && - ep1_ch1()->selected_connection()->local_candidate().type() == - LOCAL_PORT_TYPE, + ep1_ch1()->selected_connection()->local_candidate().is_local(), kDefaultTimeout, clock); - EXPECT_EQ(RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->remote_candidate().is_relay()); // Loosen the candidate filter at ep2. ep2->allocator_->SetCandidateFilter(CF_ALL); EXPECT_TRUE_SIMULATED_WAIT( ep2_ch1()->selected_connection() != nullptr && - ep2_ch1()->selected_connection()->local_candidate().type() == - LOCAL_PORT_TYPE, + ep2_ch1()->selected_connection()->local_candidate().is_local(), kDefaultTimeout, clock); // We have migrated to a host-host candidate pair. - EXPECT_EQ(LOCAL_PORT_TYPE, - ep2_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep2_ch1()->selected_connection()->remote_candidate().is_local()); // Block the traffic over non-relay-to-relay routes and expect a route change. fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[0], kPublicAddrs[1]); @@ -5780,12 +5768,10 @@ TEST_F(P2PTransportChannelTest, fw()->AddRule(false, rtc::FP_ANY, kPublicAddrs[1], kTurnUdpExtAddr); // We should be able to reuse the previously gathered relay candidates. - EXPECT_EQ_SIMULATED_WAIT( - RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->local_candidate().type(), + EXPECT_TRUE_SIMULATED_WAIT( + ep1_ch1()->selected_connection()->local_candidate().is_relay(), kDefaultTimeout, clock); - EXPECT_EQ(RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->remote_candidate().is_relay()); DestroyChannels(); } @@ -5824,22 +5810,18 @@ TEST_F(P2PTransportChannelTest, ep1->allocator_->SetCandidateFilter(kCandidateFilterNoHost); EXPECT_TRUE_SIMULATED_WAIT( ep1_ch1()->selected_connection() != nullptr && - ep1_ch1()->selected_connection()->local_candidate().type() == - STUN_PORT_TYPE, + ep1_ch1()->selected_connection()->local_candidate().is_stun(), kDefaultTimeout, clock); - EXPECT_EQ(RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->remote_candidate().is_relay()); // Loosen the candidate filter at ep2. ep2->allocator_->SetCandidateFilter(kCandidateFilterNoHost); EXPECT_TRUE_SIMULATED_WAIT( ep2_ch1()->selected_connection() != nullptr && - ep2_ch1()->selected_connection()->local_candidate().type() == - STUN_PORT_TYPE, + ep2_ch1()->selected_connection()->local_candidate().is_stun(), kDefaultTimeout, clock); // We have migrated to a srflx-srflx candidate pair. - EXPECT_EQ(STUN_PORT_TYPE, - ep2_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep2_ch1()->selected_connection()->remote_candidate().is_stun()); // Block the traffic over non-relay-to-relay routes and expect a route change. fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kPublicAddrs[1]); @@ -5847,12 +5829,10 @@ TEST_F(P2PTransportChannelTest, fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[0], kTurnUdpExtAddr); fw()->AddRule(false, rtc::FP_ANY, kPrivateAddrs[1], kTurnUdpExtAddr); // We should be able to reuse the previously gathered relay candidates. - EXPECT_EQ_SIMULATED_WAIT( - RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->local_candidate().type(), + EXPECT_TRUE_SIMULATED_WAIT( + ep1_ch1()->selected_connection()->local_candidate().is_relay(), kDefaultTimeout, clock); - EXPECT_EQ(RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->remote_candidate().is_relay()); DestroyChannels(); } @@ -5885,13 +5865,11 @@ TEST_F(P2PTransportChannelTest, ep1->allocator_->SetCandidateFilter(CF_ALL); // Wait for a period for any potential surfacing of new candidates. SIMULATED_WAIT(false, kDefaultTimeout, clock); - EXPECT_EQ(RELAY_PORT_TYPE, - ep1_ch1()->selected_connection()->local_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->local_candidate().is_relay()); // Loosen the candidate filter at ep2. ep2->allocator_->SetCandidateFilter(CF_ALL); - EXPECT_EQ(RELAY_PORT_TYPE, - ep2_ch1()->selected_connection()->local_candidate().type()); + EXPECT_TRUE(ep2_ch1()->selected_connection()->local_candidate().is_relay()); DestroyChannels(); } @@ -5928,21 +5906,18 @@ TEST_F(P2PTransportChannelTest, ResumeCandidates(1); ASSERT_TRUE_SIMULATED_WAIT( ep1_ch1()->selected_connection() != nullptr && - LOCAL_PORT_TYPE == - ep1_ch1()->selected_connection()->local_candidate().type() && + ep1_ch1()->selected_connection()->local_candidate().is_local() && ep2_ch1()->selected_connection() != nullptr && - LOCAL_PORT_TYPE == - ep1_ch1()->selected_connection()->remote_candidate().type(), + ep1_ch1()->selected_connection()->remote_candidate().is_local(), kDefaultTimeout, clock); ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr, kDefaultTimeout, clock); // Test that we have a host-host candidate pair selected and the number of // candidates signaled to the remote peer stays the same. auto test_invariants = [this]() { - EXPECT_EQ(LOCAL_PORT_TYPE, - ep1_ch1()->selected_connection()->local_candidate().type()); - EXPECT_EQ(LOCAL_PORT_TYPE, - ep1_ch1()->selected_connection()->remote_candidate().type()); + EXPECT_TRUE(ep1_ch1()->selected_connection()->local_candidate().is_local()); + EXPECT_TRUE( + ep1_ch1()->selected_connection()->remote_candidate().is_local()); EXPECT_THAT(ep2_ch1()->remote_candidates(), SizeIs(3)); }; @@ -6005,11 +5980,9 @@ TEST_F(P2PTransportChannelTest, SurfaceRequiresCoordination) { ResumeCandidates(1); ASSERT_TRUE_SIMULATED_WAIT( ep1_ch1()->selected_connection() != nullptr && - RELAY_PORT_TYPE == - ep1_ch1()->selected_connection()->local_candidate().type() && + ep1_ch1()->selected_connection()->local_candidate().is_relay() && ep2_ch1()->selected_connection() != nullptr && - RELAY_PORT_TYPE == - ep1_ch1()->selected_connection()->remote_candidate().type(), + ep1_ch1()->selected_connection()->remote_candidate().is_relay(), kDefaultTimeout, clock); ASSERT_TRUE_SIMULATED_WAIT(ep2_ch1()->selected_connection() != nullptr, kDefaultTimeout, clock); @@ -6025,11 +5998,9 @@ TEST_F(P2PTransportChannelTest, SurfaceRequiresCoordination) { // No p2p connection will be made, it will remain on relay. EXPECT_TRUE(ep1_ch1()->selected_connection() != nullptr && - RELAY_PORT_TYPE == - ep1_ch1()->selected_connection()->local_candidate().type() && + ep1_ch1()->selected_connection()->local_candidate().is_relay() && ep2_ch1()->selected_connection() != nullptr && - RELAY_PORT_TYPE == - ep1_ch1()->selected_connection()->remote_candidate().type()); + ep1_ch1()->selected_connection()->remote_candidate().is_relay()); DestroyChannels(); } diff --git a/p2p/base/port.cc b/p2p/base/port.cc index aacfef0ede..f49bfe524c 100644 --- a/p2p/base/port.cc +++ b/p2p/base/port.cc @@ -259,14 +259,18 @@ void Port::AddAddress(const rtc::SocketAddress& address, absl::string_view url, bool is_final) { RTC_DCHECK_RUN_ON(thread_); - if (protocol == TCP_PROTOCOL_NAME && type == LOCAL_PORT_TYPE) { - RTC_DCHECK(!tcptype.empty()); - } std::string foundation = ComputeFoundation(type, protocol, relay_protocol, base_address); Candidate c(component_, protocol, address, 0U, username_fragment(), password_, type, generation_, foundation, network_->id(), network_cost_); + +#if RTC_DCHECK_IS_ON + if (protocol == TCP_PROTOCOL_NAME && c.is_local()) { + RTC_DCHECK(!tcptype.empty()); + } +#endif + c.set_relay_protocol(relay_protocol); c.set_priority( c.GetPriority(type_preference, network_->preference(), relay_preference, @@ -279,26 +283,24 @@ void Port::AddAddress(const rtc::SocketAddress& address, c.set_url(url); c.set_related_address(related_address); - bool pending = MaybeObfuscateAddress(&c, type, is_final); + bool pending = MaybeObfuscateAddress(c, is_final); if (!pending) { FinishAddingAddress(c, is_final); } } -bool Port::MaybeObfuscateAddress(Candidate* c, - absl::string_view type, - bool is_final) { +bool Port::MaybeObfuscateAddress(const Candidate& c, bool is_final) { // TODO(bugs.webrtc.org/9723): Use a config to control the feature of IP // handling with mDNS. if (network_->GetMdnsResponder() == nullptr) { return false; } - if (type != LOCAL_PORT_TYPE) { + if (!c.is_local()) { return false; } - auto copy = *c; + auto copy = c; auto weak_ptr = weak_factory_.GetWeakPtr(); auto callback = [weak_ptr, copy, is_final](const rtc::IPAddress& addr, absl::string_view name) mutable { diff --git a/p2p/base/port.h b/p2p/base/port.h index e0fccd3907..a3214af1b8 100644 --- a/p2p/base/port.h +++ b/p2p/base/port.h @@ -199,8 +199,8 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { // Note that the port type does NOT uniquely identify different subclasses of // Port. Use the 2-tuple of the port type AND the protocol (GetProtocol()) to // uniquely identify subclasses. Whenever a new subclass of Port introduces a - // conflit in the value of the 2-tuple, make sure that the implementation that - // relies on this 2-tuple for RTTI is properly changed. + // conflict in the value of the 2-tuple, make sure that the implementation + // that relies on this 2-tuple for RTTI is properly changed. const absl::string_view Type() const override; const rtc::Network* Network() const override; @@ -525,9 +525,8 @@ class RTC_EXPORT Port : public PortInterface, public sigslot::has_slots<> { webrtc::FieldTrialBasedConfig> field_trials_; - bool MaybeObfuscateAddress(Candidate* c, - absl::string_view type, - bool is_final) RTC_RUN_ON(thread_); + bool MaybeObfuscateAddress(const Candidate& c, bool is_final) + RTC_RUN_ON(thread_); webrtc::CallbackList port_destroyed_callback_list_; }; diff --git a/p2p/base/stun_port_unittest.cc b/p2p/base/stun_port_unittest.cc index 9167081afb..7bc151ee03 100644 --- a/p2p/base/stun_port_unittest.cc +++ b/p2p/base/stun_port_unittest.cc @@ -426,7 +426,7 @@ TEST_F(StunPortTest, TestStunCandidateDiscardedWithMdnsObfuscationNotEnabled) { EXPECT_TRUE_SIMULATED_WAIT(done(), kTimeoutMs, fake_clock); ASSERT_EQ(1U, port()->Candidates().size()); EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address())); - EXPECT_EQ(port()->Candidates()[0].type(), cricket::LOCAL_PORT_TYPE); + EXPECT_TRUE(port()->Candidates()[0].is_local()); } // Test that a stun candidate (srflx candidate) is generated whose address is diff --git a/p2p/base/tcp_port.cc b/p2p/base/tcp_port.cc index ce61416979..948849800c 100644 --- a/p2p/base/tcp_port.cc +++ b/p2p/base/tcp_port.cc @@ -134,8 +134,7 @@ Connection* TCPPort::CreateConnection(const Candidate& address, return NULL; } - if ((address.tcptype() == TCPTYPE_ACTIVE_STR && - address.type() != PRFLX_PORT_TYPE) || + if ((address.tcptype() == TCPTYPE_ACTIVE_STR && !address.is_prflx()) || (address.tcptype().empty() && address.address().port() == 0)) { // It's active only candidate, we should not try to create connections // for these candidates. diff --git a/p2p/client/basic_port_allocator_unittest.cc b/p2p/client/basic_port_allocator_unittest.cc index 0c3bf6bc23..77443eedbb 100644 --- a/p2p/client/basic_port_allocator_unittest.cc +++ b/p2p/client/basic_port_allocator_unittest.cc @@ -328,17 +328,6 @@ class BasicPortAllocatorTestBase : public ::testing::Test, }); } - static int CountCandidates(const std::vector& candidates, - absl::string_view type, - absl::string_view proto, - const SocketAddress& addr) { - return absl::c_count_if( - candidates, [type, proto, addr](const Candidate& c) { - return c.type() == type && c.protocol() == proto && - AddressMatch(c.address(), addr); - }); - } - // Find a candidate and return it. static bool FindCandidate(const std::vector& candidates, absl::string_view type, @@ -1237,7 +1226,7 @@ TEST_F(BasicPortAllocatorTest, TestGetAllPortsPortRange) { int num_nonrelay_candidates = 0; for (const Candidate& candidate : candidates_) { // Check the port number for the UDP/STUN/TCP port objects. - if (candidate.type() != RELAY_PORT_TYPE) { + if (!candidate.is_relay()) { EXPECT_TRUE(CheckPort(candidate.address(), kMinPort, kMaxPort)); ++num_nonrelay_candidates; } @@ -1272,9 +1261,11 @@ TEST_F(BasicPortAllocatorTest, TestGetAllPortsNoAdapters) { rtc::SocketAddress(kNatUdpAddr.ipaddr(), 0))); // Again, two TURN candidates, using UDP/TCP for the first hop to the TURN // server. - EXPECT_EQ(2, - CountCandidates(candidates_, "relay", "udp", - rtc::SocketAddress(kTurnUdpExtAddr.ipaddr(), 0))); + rtc::SocketAddress addr(kTurnUdpExtAddr.ipaddr(), 0); + EXPECT_EQ(2, absl::c_count_if(candidates_, [&](const Candidate& c) { + return c.is_relay() && c.protocol() == "udp" && + AddressMatch(c.address(), addr); + })); } // Test that when enumeration is disabled, we should not have any ports when @@ -1548,7 +1539,7 @@ TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithRelayOnly) { EXPECT_EQ(1U, candidates_.size()); EXPECT_EQ(1U, ports_.size()); // Only Relay port will be in ready state. - EXPECT_EQ(std::string(RELAY_PORT_TYPE), candidates_[0].type()); + EXPECT_TRUE(candidates_[0].is_relay()); EXPECT_EQ( candidates_[0].related_address(), rtc::EmptySocketAddressWithFamily(candidates_[0].address().family())); @@ -1565,7 +1556,7 @@ TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithHostOnly) { EXPECT_EQ(2U, candidates_.size()); // Host UDP/TCP candidates only. EXPECT_EQ(2U, ports_.size()); // UDP/TCP ports only. for (const Candidate& candidate : candidates_) { - EXPECT_EQ(std::string(LOCAL_PORT_TYPE), candidate.type()); + EXPECT_TRUE(candidate.is_local()); } } @@ -1584,7 +1575,7 @@ TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithReflexiveOnly) { // port with STUN candidate will be sent outside. EXPECT_EQ(1U, candidates_.size()); // Only STUN candidate. EXPECT_EQ(1U, ports_.size()); // Only UDP port will be in ready state. - EXPECT_EQ(std::string(STUN_PORT_TYPE), candidates_[0].type()); + EXPECT_TRUE(candidates_[0].is_stun()); EXPECT_EQ( candidates_[0].related_address(), rtc::EmptySocketAddressWithFamily(candidates_[0].address().family())); @@ -1603,7 +1594,7 @@ TEST_F(BasicPortAllocatorTest, TestCandidateFilterWithReflexiveOnlyAndNoNAT) { EXPECT_EQ(2U, candidates_.size()); // Local UDP + TCP candidate. EXPECT_EQ(2U, ports_.size()); // UDP and TCP ports will be in ready state. for (const Candidate& candidate : candidates_) { - EXPECT_EQ(std::string(LOCAL_PORT_TYPE), candidate.type()); + EXPECT_TRUE(candidate.is_local()); } } @@ -2174,7 +2165,7 @@ TEST_F(BasicPortAllocatorTest, TestSetCandidateFilterAfterCandidatesGathered) { } for (const Candidate& candidate : candidates) { // Expect only relay candidates now that the filter is applied. - EXPECT_EQ(std::string(RELAY_PORT_TYPE), candidate.type()); + EXPECT_TRUE(candidate.is_relay()); // Expect that the raddr is emptied due to the CF_RELAY filter. EXPECT_EQ(candidate.related_address(), rtc::EmptySocketAddressWithFamily(candidate.address().family())); @@ -2210,21 +2201,21 @@ TEST_F(BasicPortAllocatorTest, session_->SetCandidateFilter(CF_RELAY); ASSERT_EQ_SIMULATED_WAIT(1u, candidates_.size(), kDefaultAllocationTimeout, fake_clock); - EXPECT_EQ(RELAY_PORT_TYPE, candidates_.back().type()); + EXPECT_TRUE(candidates_.back().is_relay()); EXPECT_EQ(1u, ports_.size()); // Surface the srflx candidate previously gathered but not signaled. session_->SetCandidateFilter(CF_RELAY | CF_REFLEXIVE); ASSERT_EQ_SIMULATED_WAIT(2u, candidates_.size(), kDefaultAllocationTimeout, fake_clock); - EXPECT_EQ(STUN_PORT_TYPE, candidates_.back().type()); + EXPECT_TRUE(candidates_.back().is_stun()); EXPECT_EQ(2u, ports_.size()); // Surface the srflx candidate previously gathered but not signaled. session_->SetCandidateFilter(CF_ALL); ASSERT_EQ_SIMULATED_WAIT(3u, candidates_.size(), kDefaultAllocationTimeout, fake_clock); - EXPECT_EQ(LOCAL_PORT_TYPE, candidates_.back().type()); + EXPECT_TRUE(candidates_.back().is_local()); EXPECT_EQ(2u, ports_.size()); } @@ -2260,21 +2251,21 @@ TEST_F( session_->SetCandidateFilter(CF_RELAY); EXPECT_EQ_SIMULATED_WAIT(1u, candidates_.size(), kDefaultAllocationTimeout, fake_clock); - EXPECT_EQ(RELAY_PORT_TYPE, candidates_.back().type()); + EXPECT_TRUE(candidates_.back().is_relay()); EXPECT_EQ(1u, ports_.size()); // Surface the srflx candidate previously gathered but not signaled. session_->SetCandidateFilter(CF_REFLEXIVE); EXPECT_EQ_SIMULATED_WAIT(2u, candidates_.size(), kDefaultAllocationTimeout, fake_clock); - EXPECT_EQ(STUN_PORT_TYPE, candidates_.back().type()); + EXPECT_TRUE(candidates_.back().is_stun()); EXPECT_EQ(2u, ports_.size()); // Surface the host candidate previously gathered but not signaled. session_->SetCandidateFilter(CF_HOST); EXPECT_EQ_SIMULATED_WAIT(3u, candidates_.size(), kDefaultAllocationTimeout, fake_clock); - EXPECT_EQ(LOCAL_PORT_TYPE, candidates_.back().type()); + EXPECT_TRUE(candidates_.back().is_local()); // We use a shared socket and cricket::UDPPort handles the srflx candidate. EXPECT_EQ(2u, ports_.size()); } diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index d5d1cd24a9..ff0abc0c57 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -1214,7 +1214,7 @@ void JsepTransportController::OnTransportCandidateGathered_n( cricket::IceTransportInternal* transport, const cricket::Candidate& candidate) { // We should never signal peer-reflexive candidates. - if (candidate.type() == cricket::PRFLX_PORT_TYPE) { + if (candidate.is_prflx()) { RTC_DCHECK_NOTREACHED(); return; } diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 8c9b0cbab6..dc784771f8 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -104,13 +104,7 @@ uint32_t ConvertIceTransportTypeToCandidateFilter( IceCandidatePairType GetIceCandidatePairCounter( const cricket::Candidate& local, const cricket::Candidate& remote) { - const auto& l = local.type(); - const auto& r = remote.type(); - const auto& host = cricket::LOCAL_PORT_TYPE; - const auto& srflx = cricket::STUN_PORT_TYPE; - const auto& relay = cricket::RELAY_PORT_TYPE; - const auto& prflx = cricket::PRFLX_PORT_TYPE; - if (l == host && r == host) { + if (local.is_local() && remote.is_local()) { bool local_hostname = !local.address().hostname().empty() && local.address().IsUnresolvedIP(); bool remote_hostname = !remote.address().hostname().empty() && @@ -143,34 +137,41 @@ IceCandidatePairType GetIceCandidatePairCounter( } } } - if (l == host && r == srflx) - return kIceCandidatePairHostSrflx; - if (l == host && r == relay) - return kIceCandidatePairHostRelay; - if (l == host && r == prflx) - return kIceCandidatePairHostPrflx; - if (l == srflx && r == host) - return kIceCandidatePairSrflxHost; - if (l == srflx && r == srflx) - return kIceCandidatePairSrflxSrflx; - if (l == srflx && r == relay) - return kIceCandidatePairSrflxRelay; - if (l == srflx && r == prflx) - return kIceCandidatePairSrflxPrflx; - if (l == relay && r == host) - return kIceCandidatePairRelayHost; - if (l == relay && r == srflx) - return kIceCandidatePairRelaySrflx; - if (l == relay && r == relay) - return kIceCandidatePairRelayRelay; - if (l == relay && r == prflx) - return kIceCandidatePairRelayPrflx; - if (l == prflx && r == host) - return kIceCandidatePairPrflxHost; - if (l == prflx && r == srflx) - return kIceCandidatePairPrflxSrflx; - if (l == prflx && r == relay) - return kIceCandidatePairPrflxRelay; + + if (local.is_local()) { + if (remote.is_stun()) + return kIceCandidatePairHostSrflx; + if (remote.is_relay()) + return kIceCandidatePairHostRelay; + if (remote.is_prflx()) + return kIceCandidatePairHostPrflx; + } else if (local.is_stun()) { + if (remote.is_local()) + return kIceCandidatePairSrflxHost; + if (remote.is_stun()) + return kIceCandidatePairSrflxSrflx; + if (remote.is_relay()) + return kIceCandidatePairSrflxRelay; + if (remote.is_prflx()) + return kIceCandidatePairSrflxPrflx; + } else if (local.is_relay()) { + if (remote.is_local()) + return kIceCandidatePairRelayHost; + if (remote.is_stun()) + return kIceCandidatePairRelaySrflx; + if (remote.is_relay()) + return kIceCandidatePairRelayRelay; + if (remote.is_prflx()) + return kIceCandidatePairRelayPrflx; + } else if (local.is_prflx()) { + if (remote.is_local()) + return kIceCandidatePairPrflxHost; + if (remote.is_stun()) + return kIceCandidatePairPrflxSrflx; + if (remote.is_relay()) + return kIceCandidatePairPrflxRelay; + } + return kIceCandidatePairMax; } diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc index c960a36b5e..23c8b1690f 100644 --- a/pc/peer_connection_integrationtest.cc +++ b/pc/peer_connection_integrationtest.cc @@ -3087,25 +3087,23 @@ TEST_P(PeerConnectionIntegrationTest, RegatherAfterChangingIceTransportType) { // `WebRTC.PeerConnection.CandidatePairType_UDP` in this test since this // metric is only populated when we reach kIceConnectionComplete in the // current implementation. - EXPECT_EQ(cricket::RELAY_PORT_TYPE, - caller()->last_candidate_gathered().type()); - EXPECT_EQ(cricket::RELAY_PORT_TYPE, - callee()->last_candidate_gathered().type()); + EXPECT_TRUE(caller()->last_candidate_gathered().is_relay()); + EXPECT_TRUE(callee()->last_candidate_gathered().is_relay()); // Loosen the caller's candidate filter. caller_config = caller()->pc()->GetConfiguration(); caller_config.type = PeerConnectionInterface::kAll; caller()->pc()->SetConfiguration(caller_config); // We should have gathered a new host candidate. - EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE, - caller()->last_candidate_gathered().type(), kDefaultTimeout); + EXPECT_TRUE_WAIT(caller()->last_candidate_gathered().is_local(), + kDefaultTimeout); // Loosen the callee's candidate filter. callee_config = callee()->pc()->GetConfiguration(); callee_config.type = PeerConnectionInterface::kAll; callee()->pc()->SetConfiguration(callee_config); - EXPECT_EQ_WAIT(cricket::LOCAL_PORT_TYPE, - callee()->last_candidate_gathered().type(), kDefaultTimeout); + EXPECT_TRUE_WAIT(callee()->last_candidate_gathered().is_local(), + kDefaultTimeout); // Create an offer and verify that it does not contain an ICE restart (i.e new // ice credentials). diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index 6de174b065..b9492c904b 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -961,12 +961,10 @@ const std::string& ProduceIceCandidateStats(Timestamp timestamp, if (is_local) { candidate_stats->network_type = NetworkTypeToStatsType(candidate.network_type()); - const std::string& candidate_type = candidate.type(); const std::string& relay_protocol = candidate.relay_protocol(); const std::string& url = candidate.url(); - if (candidate_type == cricket::RELAY_PORT_TYPE || - (candidate_type == cricket::PRFLX_PORT_TYPE && - !relay_protocol.empty())) { + if (candidate.is_relay() || + (candidate.is_prflx() && !relay_protocol.empty())) { RTC_DCHECK(relay_protocol.compare("udp") == 0 || relay_protocol.compare("tcp") == 0 || relay_protocol.compare("tls") == 0); @@ -974,7 +972,7 @@ const std::string& ProduceIceCandidateStats(Timestamp timestamp, if (!url.empty()) { candidate_stats->url = url; } - } else if (candidate_type == cricket::STUN_PORT_TYPE) { + } else if (candidate.is_stun()) { if (!url.empty()) { candidate_stats->url = url; } From 0c4165e667751972c7d39c81d8993e8617cb7e13 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Fri, 26 Jan 2024 20:11:17 -0800 Subject: [PATCH 028/170] Update WebRTC code version (2024-01-27T04:11:16). Bug: None Change-Id: Ie5987348df4aaa42192031d15864a582c2745dc2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336500 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41624} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 4c8c9194b1..e5183d29f5 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-26T04:12:47"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-27T04:11:16"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 89db1c5827fe2413e9a18e24d298cf887e1b6b22 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Sun, 28 Jan 2024 20:16:28 -0800 Subject: [PATCH 029/170] Update WebRTC code version (2024-01-29T04:16:27). Bug: None Change-Id: I798f906c0d24d8062d080e6c92c62d988b064a94 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336702 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41625} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index e5183d29f5..2e4e80dae9 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-27T04:11:16"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-29T04:16:27"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 98db63cfb6ad428d07995967f39c134c587b0287 Mon Sep 17 00:00:00 2001 From: Per K Date: Fri, 26 Jan 2024 12:57:01 +0100 Subject: [PATCH 030/170] Introduce RtpTransportConfig:allow_bandwidht_estimation_probe_without_media MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If allow_bandwidht_estimation_probe_without_media is true and a writable video rtp stream with RTX exist, a probe can be sent immediately without waiting for a large media packet. Bug: webrtc:14928 Change-Id: Ie2204734f9fe3e6bff9aed4a1f7f8995956d35cb Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336000 Commit-Queue: Per Kjellander Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/main@{#41626} --- call/rtp_transport_config.h | 4 ++ call/rtp_transport_controller_send.cc | 8 ++++ call/rtp_transport_controller_send.h | 1 + modules/pacing/bitrate_prober.cc | 32 +++++++++------ modules/pacing/bitrate_prober.h | 6 +++ modules/pacing/pacing_controller.cc | 4 ++ modules/pacing/pacing_controller.h | 3 ++ modules/pacing/pacing_controller_unittest.cc | 41 +++++++++++++++++--- modules/pacing/packet_router.cc | 10 +++++ modules/pacing/packet_router.h | 2 + modules/pacing/packet_router_unittest.cc | 25 ++++++++++++ modules/pacing/task_queue_paced_sender.cc | 5 +++ modules/pacing/task_queue_paced_sender.h | 3 ++ 13 files changed, 127 insertions(+), 17 deletions(-) diff --git a/call/rtp_transport_config.h b/call/rtp_transport_config.h index cce5214fc8..412ff78e08 100644 --- a/call/rtp_transport_config.h +++ b/call/rtp_transport_config.h @@ -38,6 +38,10 @@ struct RtpTransportConfig { // The burst interval of the pacer, see TaskQueuePacedSender constructor. absl::optional pacer_burst_interval; + + // A bandwith estimation probe may be sent on a writable Rtp stream that have + // RTX configured. It can be sent without first sending media packets. + bool allow_bandwidth_estimation_probe_without_media = false; }; } // namespace webrtc diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc index 5ed1d6a0f3..d439a2f898 100644 --- a/call/rtp_transport_controller_send.cc +++ b/call/rtp_transport_controller_send.cc @@ -70,6 +70,8 @@ bool IsRelayed(const rtc::NetworkRoute& route) { RtpTransportControllerSend::RtpTransportControllerSend( const RtpTransportConfig& config) : env_(config.env), + allow_bandwidth_estimation_probe_without_media_( + config.allow_bandwidth_estimation_probe_without_media), task_queue_(TaskQueueBase::Current()), bitrate_configurator_(config.bitrate_config), pacer_started_(false), @@ -165,6 +167,9 @@ void RtpTransportControllerSend::RegisterSendingRtpStream( // Allow pacer to send packets using this module. packet_router_.AddSendRtpModule(&rtp_module, /*remb_candidate=*/true); + pacer_.SetAllowProbeWithoutMediaPacket( + allow_bandwidth_estimation_probe_without_media_ && + packet_router_.SupportsRtxPayloadPadding()); } void RtpTransportControllerSend::DeRegisterSendingRtpStream( @@ -182,6 +187,9 @@ void RtpTransportControllerSend::DeRegisterSendingRtpStream( if (rtp_module.FlexfecSsrc().has_value()) { pacer_.RemovePacketsForSsrc(*rtp_module.FlexfecSsrc()); } + pacer_.SetAllowProbeWithoutMediaPacket( + allow_bandwidth_estimation_probe_without_media_ && + packet_router_.SupportsRtxPayloadPadding()); } void RtpTransportControllerSend::UpdateControlState() { diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h index 6f6f0809a3..3c84beb65f 100644 --- a/call/rtp_transport_controller_send.h +++ b/call/rtp_transport_controller_send.h @@ -150,6 +150,7 @@ class RtpTransportControllerSend final const Environment env_; SequenceChecker sequence_checker_; + const bool allow_bandwidth_estimation_probe_without_media_; TaskQueueBase* task_queue_; PacketRouter packet_router_; std::vector> video_rtp_senders_ diff --git a/modules/pacing/bitrate_prober.cc b/modules/pacing/bitrate_prober.cc index e60a1e5283..17729b5775 100644 --- a/modules/pacing/bitrate_prober.cc +++ b/modules/pacing/bitrate_prober.cc @@ -52,6 +52,18 @@ void BitrateProber::SetEnabled(bool enable) { } } +void BitrateProber::SetAllowProbeWithoutMediaPacket(bool allow) { + config_.allow_start_probing_immediately = allow; + MaybeSetActiveState(/*packet_size=*/DataSize::Zero()); +} + +void BitrateProber::MaybeSetActiveState(DataSize packet_size) { + if (ReadyToSetActiveState(packet_size)) { + next_probe_time_ = Timestamp::MinusInfinity(); + probing_state_ = ProbingState::kActive; + } +} + bool BitrateProber::ReadyToSetActiveState(DataSize packet_size) const { if (clusters_.empty()) { RTC_DCHECK(probing_state_ == ProbingState::kDisabled || @@ -63,19 +75,19 @@ bool BitrateProber::ReadyToSetActiveState(DataSize packet_size) const { case ProbingState::kActive: return false; case ProbingState::kInactive: - // If config_.min_packet_size > 0, a "large enough" packet must be sent - // first, before a probe can be generated and sent. Otherwise, send the - // probe asap. + if (config_.allow_start_probing_immediately) { + return true; + } + // If config_.min_packet_size > 0, a "large enough" packet must be + // sent first, before a probe can be generated and sent. Otherwise, + // send the probe asap. return packet_size >= std::min(RecommendedMinProbeSize(), config_.min_packet_size.Get()); } } void BitrateProber::OnIncomingPacket(DataSize packet_size) { - if (ReadyToSetActiveState(packet_size)) { - next_probe_time_ = Timestamp::MinusInfinity(); - probing_state_ = ProbingState::kActive; - } + MaybeSetActiveState(packet_size); } void BitrateProber::CreateProbeCluster( @@ -101,10 +113,8 @@ void BitrateProber::CreateProbeCluster( cluster.pace_info.probe_cluster_id = cluster_config.id; clusters_.push(cluster); - if (ReadyToSetActiveState(/*packet_size=*/DataSize::Zero())) { - next_probe_time_ = Timestamp::MinusInfinity(); - probing_state_ = ProbingState::kActive; - } + MaybeSetActiveState(/*packet_size=*/DataSize::Zero()); + RTC_DCHECK(probing_state_ == ProbingState::kActive || probing_state_ == ProbingState::kInactive); diff --git a/modules/pacing/bitrate_prober.h b/modules/pacing/bitrate_prober.h index 82aba6ee3a..821bbf32eb 100644 --- a/modules/pacing/bitrate_prober.h +++ b/modules/pacing/bitrate_prober.h @@ -38,6 +38,9 @@ struct BitrateProberConfig { // This defines the max min packet size, meaning that on high bitrates // a packet of at least this size is needed to trigger sending a probe. FieldTrialParameter min_packet_size; + + // If true, `min_packet_size` is ignored. + bool allow_start_probing_immediately = false; }; // Note that this class isn't thread-safe by itself and therefore relies @@ -48,6 +51,7 @@ class BitrateProber { ~BitrateProber() = default; void SetEnabled(bool enable); + void SetAllowProbeWithoutMediaPacket(bool allow); // Returns true if the prober is in a probing session, i.e., it currently // wants packets to be sent out according to the time returned by @@ -105,6 +109,8 @@ class BitrateProber { }; Timestamp CalculateNextProbeTime(const ProbeCluster& cluster) const; + + void MaybeSetActiveState(DataSize packet_size); bool ReadyToSetActiveState(DataSize packet_size) const; ProbingState probing_state_; diff --git a/modules/pacing/pacing_controller.cc b/modules/pacing/pacing_controller.cc index 41f97a37fb..a45c5d8f63 100644 --- a/modules/pacing/pacing_controller.cc +++ b/modules/pacing/pacing_controller.cc @@ -252,6 +252,10 @@ void PacingController::SetSendBurstInterval(TimeDelta burst_interval) { send_burst_interval_ = burst_interval; } +void PacingController::SetAllowProbeWithoutMediaPacket(bool allow) { + prober_.SetAllowProbeWithoutMediaPacket(allow); +} + TimeDelta PacingController::ExpectedQueueTime() const { RTC_DCHECK_GT(adjusted_media_rate_, DataRate::Zero()); return QueueSizeData() / adjusted_media_rate_; diff --git a/modules/pacing/pacing_controller.h b/modules/pacing/pacing_controller.h index fe6ee737a9..bdf8bef392 100644 --- a/modules/pacing/pacing_controller.h +++ b/modules/pacing/pacing_controller.h @@ -160,6 +160,9 @@ class PacingController { // 'burst_interval'. void SetSendBurstInterval(TimeDelta burst_interval); + // A probe may be sent without first waing for a media packet. + void SetAllowProbeWithoutMediaPacket(bool allow); + // Returns the time when the oldest packet was queued. Timestamp OldestPacketEnqueueTime() const; diff --git a/modules/pacing/pacing_controller_unittest.cc b/modules/pacing/pacing_controller_unittest.cc index 2c3a71b369..8a37292b95 100644 --- a/modules/pacing/pacing_controller_unittest.cc +++ b/modules/pacing/pacing_controller_unittest.cc @@ -1366,10 +1366,9 @@ TEST_F(PacingControllerTest, CanProbeWithPaddingBeforeFirstMediaPacket) { const int kInitialBitrateBps = 300000; PacingControllerProbing packet_sender; - const test::ExplicitKeyValueConfig trials( - "WebRTC-Bwe-ProbingBehavior/min_packet_size:0/"); auto pacer = - std::make_unique(&clock_, &packet_sender, trials); + std::make_unique(&clock_, &packet_sender, trials_); + pacer->SetAllowProbeWithoutMediaPacket(true); std::vector probe_clusters = { {.at_time = clock_.CurrentTime(), .target_data_rate = kFirstClusterRate, @@ -1393,16 +1392,46 @@ TEST_F(PacingControllerTest, CanProbeWithPaddingBeforeFirstMediaPacket) { EXPECT_GT(packet_sender.padding_packets_sent(), 5); } +TEST_F(PacingControllerTest, ProbeSentAfterSetAllowProbeWithoutMediaPacket) { + const int kInitialBitrateBps = 300000; + + PacingControllerProbing packet_sender; + auto pacer = + std::make_unique(&clock_, &packet_sender, trials_); + std::vector probe_clusters = { + {.at_time = clock_.CurrentTime(), + .target_data_rate = kFirstClusterRate, + .target_duration = TimeDelta::Millis(15), + .target_probe_count = 5, + .id = 0}}; + pacer->CreateProbeClusters(probe_clusters); + + pacer->SetPacingRates( + DataRate::BitsPerSec(kInitialBitrateBps * kPaceMultiplier), + DataRate::Zero()); + + pacer->SetAllowProbeWithoutMediaPacket(true); + + Timestamp start = clock_.CurrentTime(); + Timestamp next_process = pacer->NextSendTime(); + while (clock_.CurrentTime() < start + TimeDelta::Millis(100) && + next_process.IsFinite()) { + AdvanceTimeUntil(next_process); + pacer->ProcessPackets(); + next_process = pacer->NextSendTime(); + } + EXPECT_GT(packet_sender.padding_packets_sent(), 5); +} + TEST_F(PacingControllerTest, CanNotProbeWithPaddingIfGeneratePaddingFails) { // const size_t kPacketSize = 1200; const int kInitialBitrateBps = 300000; PacingControllerProbing packet_sender; packet_sender.SetCanGeneratePadding(false); - const test::ExplicitKeyValueConfig trials( - "WebRTC-Bwe-ProbingBehavior/min_packet_size:0/"); auto pacer = - std::make_unique(&clock_, &packet_sender, trials); + std::make_unique(&clock_, &packet_sender, trials_); + pacer->SetAllowProbeWithoutMediaPacket(true); std::vector probe_clusters = { {.at_time = clock_.CurrentTime(), .target_data_rate = kFirstClusterRate, diff --git a/modules/pacing/packet_router.cc b/modules/pacing/packet_router.cc index 4c986ad027..0ad64f212d 100644 --- a/modules/pacing/packet_router.cc +++ b/modules/pacing/packet_router.cc @@ -65,6 +65,16 @@ void PacketRouter::AddSendRtpModule(RtpRtcpInterface* rtp_module, } } +bool PacketRouter::SupportsRtxPayloadPadding() const { + RTC_DCHECK_RUN_ON(&thread_checker_); + for (RtpRtcpInterface* rtp_module : send_modules_list_) { + if (rtp_module->SupportsRtxPayloadPadding()) { + return true; + } + } + return false; +} + void PacketRouter::AddSendRtpModuleToMap(RtpRtcpInterface* rtp_module, uint32_t ssrc) { RTC_DCHECK_RUN_ON(&thread_checker_); diff --git a/modules/pacing/packet_router.h b/modules/pacing/packet_router.h index 61779f49e5..4c5747f7e3 100644 --- a/modules/pacing/packet_router.h +++ b/modules/pacing/packet_router.h @@ -50,6 +50,8 @@ class PacketRouter : public PacingController::PacketSender { void AddSendRtpModule(RtpRtcpInterface* rtp_module, bool remb_candidate); void RemoveSendRtpModule(RtpRtcpInterface* rtp_module); + bool SupportsRtxPayloadPadding() const; + void AddReceiveRtpModule(RtcpFeedbackSenderInterface* rtcp_sender, bool remb_candidate); void RemoveReceiveRtpModule(RtcpFeedbackSenderInterface* rtcp_sender); diff --git a/modules/pacing/packet_router_unittest.cc b/modules/pacing/packet_router_unittest.cc index af8534316c..b91c309eec 100644 --- a/modules/pacing/packet_router_unittest.cc +++ b/modules/pacing/packet_router_unittest.cc @@ -125,6 +125,31 @@ TEST_F(PacketRouterTest, GeneratePaddingPrioritizesRtx) { packet_router_.RemoveSendRtpModule(&rtp_2); } +TEST_F(PacketRouterTest, SupportsRtxPayloadPaddingFalseIfNoRtxSendModule) { + EXPECT_FALSE(packet_router_.SupportsRtxPayloadPadding()); + + NiceMock none_rtx_module; + ON_CALL(none_rtx_module, SupportsRtxPayloadPadding()) + .WillByDefault(Return(false)); + + packet_router_.AddSendRtpModule(&none_rtx_module, false); + EXPECT_FALSE(packet_router_.SupportsRtxPayloadPadding()); + + packet_router_.RemoveSendRtpModule(&none_rtx_module); + EXPECT_FALSE(packet_router_.SupportsRtxPayloadPadding()); +} + +TEST_F(PacketRouterTest, SupportsRtxPayloadPaddingTrueIfRtxSendModule) { + NiceMock rtx_module; + ON_CALL(rtx_module, SupportsRtxPayloadPadding()).WillByDefault(Return(true)); + + packet_router_.AddSendRtpModule(&rtx_module, false); + EXPECT_TRUE(packet_router_.SupportsRtxPayloadPadding()); + + packet_router_.RemoveSendRtpModule(&rtx_module); + EXPECT_FALSE(packet_router_.SupportsRtxPayloadPadding()); +} + TEST_F(PacketRouterTest, GeneratePaddingPrioritizesVideo) { // Two RTP modules. Neither support RTX, both support padding, // but the first one is for audio and second for video. diff --git a/modules/pacing/task_queue_paced_sender.cc b/modules/pacing/task_queue_paced_sender.cc index f7218e48a1..5559153251 100644 --- a/modules/pacing/task_queue_paced_sender.cc +++ b/modules/pacing/task_queue_paced_sender.cc @@ -52,6 +52,11 @@ void TaskQueuePacedSender::SetSendBurstInterval(TimeDelta burst_interval) { pacing_controller_.SetSendBurstInterval(burst_interval); } +void TaskQueuePacedSender::SetAllowProbeWithoutMediaPacket(bool allow) { + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.SetAllowProbeWithoutMediaPacket(allow); +} + void TaskQueuePacedSender::EnsureStarted() { RTC_DCHECK_RUN_ON(task_queue_); is_started_ = true; diff --git a/modules/pacing/task_queue_paced_sender.h b/modules/pacing/task_queue_paced_sender.h index e29acdf878..a1d2474ca1 100644 --- a/modules/pacing/task_queue_paced_sender.h +++ b/modules/pacing/task_queue_paced_sender.h @@ -60,6 +60,9 @@ class TaskQueuePacedSender : public RtpPacketPacer, public RtpPacketSender { // 'burst_interval'. void SetSendBurstInterval(TimeDelta burst_interval); + // A probe may be sent without first waing for a media packet. + void SetAllowProbeWithoutMediaPacket(bool allow); + // Ensure that necessary delayed tasks are scheduled. void EnsureStarted(); From 6adf2243b564b1b3e7abba6c4f3aa144edf3ddb6 Mon Sep 17 00:00:00 2001 From: Ilya Nikolaevskiy Date: Fri, 26 Jan 2024 15:01:51 +0100 Subject: [PATCH 031/170] Compute scaling factors for not-explicitly configured layers in VP9 encoder The division by 2 has been accidentally removed in https://webrtc-review.googlesource.com/c/src/+/76921 The code and comment are out of sync now. Bug: None Change-Id: If43a40461878ffe58dd9ed0ab8a6244ad79c4f6b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336283 Reviewed-by: Sergey Silkin Auto-Submit: Ilya Nikolaevskiy Commit-Queue: Sergey Silkin Cr-Commit-Position: refs/heads/main@{#41627} --- modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc index e26169fd3d..b73fd100cf 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -836,6 +836,8 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) { // 1:2 scaling in each dimension. svc_params_.scaling_factor_num[i] = scaling_factor_num; svc_params_.scaling_factor_den[i] = 256; + if (inst->mode != VideoCodecMode::kScreensharing) + scaling_factor_num /= 2; } } From f43e8ebab9ee0a4c380e943127e8ea1fb593948d Mon Sep 17 00:00:00 2001 From: qwu16 Date: Fri, 19 Jan 2024 11:32:17 +0800 Subject: [PATCH 032/170] Add RTP depacketizer for H265 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Depacketize single nalu packet/AP/FU 2. Insert start code before each nalu Bug: webrtc:13485 Change-Id: I8346f9c31e61e5d3c2c7e1bf5fdaae4018a1ff78 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/325660 Reviewed-by: Sergey Silkin Commit-Queue: Sergey Silkin Reviewed-by: Erik Språng Reviewed-by: Philip Eliasson Cr-Commit-Position: refs/heads/main@{#41628} --- common_video/h265/h265_common.h | 10 +- modules/rtp_rtcp/BUILD.gn | 8 +- .../source/create_video_rtp_depacketizer.cc | 8 +- .../rtp_rtcp/source/rtp_packet_h265_common.h | 54 +++ .../rtp_rtcp/source/rtp_packetizer_h265.cc | 58 +-- .../source/rtp_packetizer_h265_unittest.cc | 91 ++-- .../source/video_rtp_depacketizer_h265.cc | 244 +++++++++++ .../source/video_rtp_depacketizer_h265.h | 28 ++ .../video_rtp_depacketizer_h265_unittest.cc | 400 ++++++++++++++++++ test/fuzzers/BUILD.gn | 5 + test/fuzzers/h265_depacketizer_fuzzer.cc | 19 + video/rtp_video_stream_receiver2.cc | 1 + 12 files changed, 830 insertions(+), 96 deletions(-) create mode 100644 modules/rtp_rtcp/source/rtp_packet_h265_common.h create mode 100644 modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc create mode 100644 modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h create mode 100644 modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc create mode 100644 test/fuzzers/h265_depacketizer_fuzzer.cc diff --git a/common_video/h265/h265_common.h b/common_video/h265/h265_common.h index 643726f701..d32de7f059 100644 --- a/common_video/h265/h265_common.h +++ b/common_video/h265/h265_common.h @@ -55,11 +55,15 @@ enum NaluType : uint8_t { kAud = 35, kPrefixSei = 39, kSuffixSei = 40, + // Aggregation packets, refer to section 4.4.2 in RFC 7798. kAp = 48, - kFu = 49 + // Fragmentation units, refer to section 4.4.3 in RFC 7798. + kFu = 49, + // PACI packets, refer to section 4.4.4 in RFC 7798. + kPaci = 50 }; -// Slice type definition. See table 7-7 of the H265 spec +// Slice type definition. See table 7-7 of the H.265 spec enum SliceType : uint8_t { kB = 0, kP = 1, kI = 2 }; struct NaluIndex { @@ -78,7 +82,7 @@ std::vector FindNaluIndices(const uint8_t* buffer, // Get the NAL type from the header byte immediately following start sequence. NaluType ParseNaluType(uint8_t data); -// Methods for parsing and writing RBSP. See section 7.4.2 of the H265 spec. +// Methods for parsing and writing RBSP. See section 7.4.2 of the H.265 spec. // // The following sequences are illegal, and need to be escaped when encoding: // 00 00 00 -> 00 00 03 00 diff --git a/modules/rtp_rtcp/BUILD.gn b/modules/rtp_rtcp/BUILD.gn index 2c0a19e995..2c42e53d36 100644 --- a/modules/rtp_rtcp/BUILD.gn +++ b/modules/rtp_rtcp/BUILD.gn @@ -260,8 +260,11 @@ rtc_library("rtp_rtcp") { if (rtc_use_h265) { sources += [ + "source/rtp_packet_h265_common.h", "source/rtp_packetizer_h265.cc", "source/rtp_packetizer_h265.h", + "source/video_rtp_depacketizer_h265.cc", + "source/video_rtp_depacketizer_h265.h", ] } @@ -632,7 +635,10 @@ if (rtc_include_tests) { "source/video_rtp_depacketizer_vp9_unittest.cc", ] if (rtc_use_h265) { - sources += [ "source/rtp_packetizer_h265_unittest.cc" ] + sources += [ + "source/rtp_packetizer_h265_unittest.cc", + "source/video_rtp_depacketizer_h265_unittest.cc", + ] } deps = [ diff --git a/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc b/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc index 95db212bef..598a86d4ad 100644 --- a/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc +++ b/modules/rtp_rtcp/source/create_video_rtp_depacketizer.cc @@ -19,6 +19,9 @@ #include "modules/rtp_rtcp/source/video_rtp_depacketizer_h264.h" #include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp8.h" #include "modules/rtp_rtcp/source/video_rtp_depacketizer_vp9.h" +#ifdef RTC_ENABLE_H265 +#include "modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h" +#endif namespace webrtc { @@ -34,8 +37,11 @@ std::unique_ptr CreateVideoRtpDepacketizer( case kVideoCodecAV1: return std::make_unique(); case kVideoCodecH265: - // TODO(bugs.webrtc.org/13485): Implement VideoRtpDepacketizerH265. +#ifdef RTC_ENABLE_H265 + return std::make_unique(); +#else return nullptr; +#endif case kVideoCodecGeneric: case kVideoCodecMultiplex: return std::make_unique(); diff --git a/modules/rtp_rtcp/source/rtp_packet_h265_common.h b/modules/rtp_rtcp/source/rtp_packet_h265_common.h new file mode 100644 index 0000000000..8655a02001 --- /dev/null +++ b/modules/rtp_rtcp/source/rtp_packet_h265_common.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024 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 MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H265_COMMON_H_ +#define MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H265_COMMON_H_ + +#include +#include + +namespace webrtc { +// The payload header consists of the same +// fields (F, Type, LayerId and TID) as the NAL unit header. Refer to +// section 4.4 in RFC 7798. +constexpr size_t kH265PayloadHeaderSizeBytes = 2; +// Unlike H.264, H.265 NAL header is 2-bytes. +constexpr size_t kH265NalHeaderSizeBytes = 2; +// H.265's FU is constructed of 2-byte payload header, 1-byte FU header and FU +// payload. +constexpr size_t kH265FuHeaderSizeBytes = 1; +// The NALU size for H.265 RTP aggregated packet indicates the size of the NAL +// unit is 2-bytes. +constexpr size_t kH265LengthFieldSizeBytes = 2; +constexpr size_t kH265ApHeaderSizeBytes = + kH265NalHeaderSizeBytes + kH265LengthFieldSizeBytes; + +// Bit masks for NAL headers. +enum NalHdrMasks { + kH265FBit = 0x80, + kH265TypeMask = 0x7E, + kH265LayerIDHMask = 0x1, + kH265LayerIDLMask = 0xF8, + kH265TIDMask = 0x7, + kH265TypeMaskN = 0x81, + kH265TypeMaskInFuHeader = 0x3F +}; + +// Bit masks for FU headers. +enum FuBitmasks { + kH265SBitMask = 0x80, + kH265EBitMask = 0x40, + kH265FuTypeBitMask = 0x3F +}; + +constexpr uint8_t kStartCode[] = {0, 0, 0, 1}; + +} // namespace webrtc + +#endif // MODULES_RTP_RTCP_SOURCE_RTP_PACKET_H265_COMMON_H_ diff --git a/modules/rtp_rtcp/source/rtp_packetizer_h265.cc b/modules/rtp_rtcp/source/rtp_packetizer_h265.cc index 313680cc87..5f10120d81 100644 --- a/modules/rtp_rtcp/source/rtp_packetizer_h265.cc +++ b/modules/rtp_rtcp/source/rtp_packetizer_h265.cc @@ -16,42 +16,10 @@ #include "common_video/h264/h264_common.h" #include "common_video/h265/h265_common.h" #include "modules/rtp_rtcp/source/byte_io.h" +#include "modules/rtp_rtcp/source/rtp_packet_h265_common.h" #include "rtc_base/logging.h" namespace webrtc { -namespace { - -// The payload header consists of the same -// fields (F, Type, LayerId and TID) as the NAL unit header. Refer to -// section 4.2 in RFC 7798. -constexpr size_t kH265PayloadHeaderSize = 2; -// Unlike H.264, H265 NAL header is 2-bytes. -constexpr size_t kH265NalHeaderSize = 2; -// H265's FU is constructed of 2-byte payload header, 1-byte FU header and FU -// payload. -constexpr size_t kH265FuHeaderSize = 1; -// The NALU size for H265 RTP aggregated packet indicates the size of the NAL -// unit is 2-bytes. -constexpr size_t kH265LengthFieldSize = 2; - -enum H265NalHdrMasks { - kH265FBit = 0x80, - kH265TypeMask = 0x7E, - kH265LayerIDHMask = 0x1, - kH265LayerIDLMask = 0xF8, - kH265TIDMask = 0x7, - kH265TypeMaskN = 0x81, - kH265TypeMaskInFuHeader = 0x3F -}; - -// Bit masks for FU headers. -enum H265FuBitmasks { - kH265SBitMask = 0x80, - kH265EBitMask = 0x40, - kH265FuTypeBitMask = 0x3F -}; - -} // namespace RtpPacketizerH265::RtpPacketizerH265(rtc::ArrayView payload, PayloadSizeLimits limits) @@ -112,7 +80,8 @@ bool RtpPacketizerH265::PacketizeFu(size_t fragment_index) { // Refer to section 4.4.3 in RFC7798, each FU fragment will have a 2-bytes // payload header and a one-byte FU header. DONL is not supported so ignore // its size when calculating max_payload_len. - limits.max_payload_len -= kH265FuHeaderSize + kH265PayloadHeaderSize; + limits.max_payload_len -= + kH265FuHeaderSizeBytes + kH265PayloadHeaderSizeBytes; // Update single/first/last packet reductions unless it is single/first/last // fragment. @@ -135,8 +104,8 @@ bool RtpPacketizerH265::PacketizeFu(size_t fragment_index) { } // Strip out the original header. - size_t payload_left = fragment.size() - kH265NalHeaderSize; - int offset = kH265NalHeaderSize; + size_t payload_left = fragment.size() - kH265NalHeaderSizeBytes; + int offset = kH265NalHeaderSizeBytes; std::vector payload_sizes = SplitAboutEqually(payload_left, limits); if (payload_sizes.empty()) { @@ -198,12 +167,13 @@ int RtpPacketizerH265::PacketizeAp(size_t fragment_index) { payload_size_left -= fragment.size(); payload_size_left -= fragment_headers_length; - fragment_headers_length = kH265LengthFieldSize; + fragment_headers_length = kH265LengthFieldSizeBytes; // If we are going to try to aggregate more fragments into this packet // we need to add the AP NALU header and a length field for the first // NALU of this packet. if (aggregated_fragments == 0) { - fragment_headers_length += kH265PayloadHeaderSize + kH265LengthFieldSize; + fragment_headers_length += + kH265PayloadHeaderSizeBytes + kH265LengthFieldSizeBytes; } ++aggregated_fragments; @@ -248,7 +218,7 @@ bool RtpPacketizerH265::NextPacket(RtpPacketToSend* rtp_packet) { void RtpPacketizerH265::NextAggregatePacket(RtpPacketToSend* rtp_packet) { size_t payload_capacity = rtp_packet->FreeCapacity(); - RTC_CHECK_GE(payload_capacity, kH265PayloadHeaderSize); + RTC_CHECK_GE(payload_capacity, kH265PayloadHeaderSizeBytes); uint8_t* buffer = rtp_packet->AllocatePayload(payload_capacity); RTC_CHECK(buffer); PacketUnit* packet = &packets_.front(); @@ -272,13 +242,13 @@ void RtpPacketizerH265::NextAggregatePacket(RtpPacketToSend* rtp_packet) { buffer[0] = payload_hdr_h; buffer[1] = payload_hdr_l; - int index = kH265PayloadHeaderSize; + int index = kH265PayloadHeaderSizeBytes; bool is_last_fragment = packet->last_fragment; while (packet->aggregated) { // Add NAL unit length field. rtc::ArrayView fragment = packet->source_fragment; ByteWriter::WriteBigEndian(&buffer[index], fragment.size()); - index += kH265LengthFieldSize; + index += kH265LengthFieldSizeBytes; // Add NAL unit. memcpy(&buffer[index], fragment.data(), fragment.size()); index += fragment.size(); @@ -332,15 +302,15 @@ void RtpPacketizerH265::NextFragmentPacket(RtpPacketToSend* rtp_packet) { (H265::NaluType::kFu << 1) | layer_id_h; rtc::ArrayView fragment = packet->source_fragment; uint8_t* buffer = rtp_packet->AllocatePayload( - kH265FuHeaderSize + kH265PayloadHeaderSize + fragment.size()); + kH265FuHeaderSizeBytes + kH265PayloadHeaderSizeBytes + fragment.size()); RTC_CHECK(buffer); buffer[0] = payload_hdr_h; buffer[1] = payload_hdr_l; buffer[2] = fu_header; // Do not support DONL for fragmentation units, DONL field is not present. - memcpy(buffer + kH265FuHeaderSize + kH265PayloadHeaderSize, fragment.data(), - fragment.size()); + memcpy(buffer + kH265FuHeaderSizeBytes + kH265PayloadHeaderSizeBytes, + fragment.data(), fragment.size()); if (packet->last_fragment) { input_fragments_.pop_front(); } diff --git a/modules/rtp_rtcp/source/rtp_packetizer_h265_unittest.cc b/modules/rtp_rtcp/source/rtp_packetizer_h265_unittest.cc index cb1de334c0..8f739e8618 100644 --- a/modules/rtp_rtcp/source/rtp_packetizer_h265_unittest.cc +++ b/modules/rtp_rtcp/source/rtp_packetizer_h265_unittest.cc @@ -15,6 +15,7 @@ #include "common_video/h265/h265_common.h" #include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" #include "modules/rtp_rtcp/source/byte_io.h" +#include "modules/rtp_rtcp/source/rtp_packet_h265_common.h" #include "test/gmock.h" #include "test/gtest.h" @@ -29,18 +30,12 @@ using ::testing::IsEmpty; using ::testing::SizeIs; constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr; -constexpr size_t kMaxPayloadSize = 1200; -constexpr size_t kLengthFieldLength = 2; +constexpr size_t kMaxPayloadSizeBytes = 1200; +constexpr size_t kH265LengthFieldSizeBytes = 2; constexpr RtpPacketizer::PayloadSizeLimits kNoLimits; -constexpr size_t kNalHeaderSize = 2; -constexpr size_t kFuHeaderSize = 3; - -constexpr uint8_t kNaluTypeMask = 0x7E; - -// Bit masks for FU headers. -constexpr uint8_t kH265SBit = 0x80; -constexpr uint8_t kH265EBit = 0x40; +constexpr size_t kFuHeaderSizeBytes = + kH265FuHeaderSizeBytes + kH265PayloadHeaderSizeBytes; // Creates Buffer that looks like nal unit of given size. rtc::Buffer GenerateNalUnit(size_t size) { @@ -127,8 +122,8 @@ TEST(RtpPacketizerH265Test, SingleNalu) { TEST(RtpPacketizerH265Test, SingleNaluTwoPackets) { RtpPacketizer::PayloadSizeLimits limits; - limits.max_payload_len = kMaxPayloadSize; - rtc::Buffer nalus[] = {GenerateNalUnit(kMaxPayloadSize), + limits.max_payload_len = kMaxPayloadSizeBytes; + rtc::Buffer nalus[] = {GenerateNalUnit(kMaxPayloadSizeBytes), GenerateNalUnit(100)}; rtc::Buffer frame = CreateFrame(nalus); @@ -205,27 +200,28 @@ TEST(RtpPacketizerH265Test, ApRespectsNoPacketReduction) { ASSERT_THAT(packets, SizeIs(1)); auto payload = packets[0].payload(); int type = H265::ParseNaluType(payload[0]); - EXPECT_EQ(payload.size(), - kNalHeaderSize + 3 * kLengthFieldLength + 2 + 2 + 0x123); + EXPECT_EQ(payload.size(), kH265NalHeaderSizeBytes + + 3 * kH265LengthFieldSizeBytes + 2 + 2 + 0x123); EXPECT_EQ(type, H265::NaluType::kAp); - payload = payload.subview(kNalHeaderSize); + payload = payload.subview(kH265NalHeaderSizeBytes); // 1st fragment. - EXPECT_THAT(payload.subview(0, kLengthFieldLength), + EXPECT_THAT(payload.subview(0, kH265LengthFieldSizeBytes), ElementsAre(0, 2)); // Size. - EXPECT_THAT(payload.subview(kLengthFieldLength, 2), + EXPECT_THAT(payload.subview(kH265LengthFieldSizeBytes, 2), ElementsAreArray(nalus[0])); - payload = payload.subview(kLengthFieldLength + 2); + payload = payload.subview(kH265LengthFieldSizeBytes + 2); // 2nd fragment. - EXPECT_THAT(payload.subview(0, kLengthFieldLength), + EXPECT_THAT(payload.subview(0, kH265LengthFieldSizeBytes), ElementsAre(0, 2)); // Size. - EXPECT_THAT(payload.subview(kLengthFieldLength, 2), + EXPECT_THAT(payload.subview(kH265LengthFieldSizeBytes, 2), ElementsAreArray(nalus[1])); - payload = payload.subview(kLengthFieldLength + 2); + payload = payload.subview(kH265LengthFieldSizeBytes + 2); // 3rd fragment. - EXPECT_THAT(payload.subview(0, kLengthFieldLength), + EXPECT_THAT(payload.subview(0, kH265LengthFieldSizeBytes), ElementsAre(0x1, 0x23)); // Size. - EXPECT_THAT(payload.subview(kLengthFieldLength), ElementsAreArray(nalus[2])); + EXPECT_THAT(payload.subview(kH265LengthFieldSizeBytes), + ElementsAreArray(nalus[2])); } TEST(RtpPacketizerH265Test, ApRespectsFirstPacketReduction) { @@ -284,7 +280,7 @@ TEST(RtpPacketizerH265Test, TooSmallForApHeaders) { RtpPacketizer::PayloadSizeLimits limits; limits.max_payload_len = 1000; const size_t kLastFragmentSize = - limits.max_payload_len - 3 * kLengthFieldLength - 4; + limits.max_payload_len - 3 * kH265LengthFieldSizeBytes - 4; rtc::Buffer nalus[] = {GenerateNalUnit(/*size=*/2), GenerateNalUnit(/*size=*/2), GenerateNalUnit(/*size=*/kLastFragmentSize)}; @@ -326,7 +322,8 @@ TEST(RtpPacketizerH265Test, LastFragmentFitsInSingleButNotLastPacket) { // Returns sizes of the payloads excluding FU headers. std::vector TestFu(size_t frame_payload_size, const RtpPacketizer::PayloadSizeLimits& limits) { - rtc::Buffer nalu[] = {GenerateNalUnit(kNalHeaderSize + frame_payload_size)}; + rtc::Buffer nalu[] = { + GenerateNalUnit(kH265NalHeaderSizeBytes + frame_payload_size)}; rtc::Buffer frame = CreateFrame(nalu); RtpPacketizerH265 packetizer(frame, limits); @@ -338,18 +335,18 @@ std::vector TestFu(size_t frame_payload_size, for (const RtpPacketToSend& packet : packets) { auto payload = packet.payload(); - EXPECT_GT(payload.size(), kFuHeaderSize); + EXPECT_GT(payload.size(), kFuHeaderSizeBytes); // FU header is after the 2-bytes size PayloadHdr according to 4.4.3 in spec fu_header.push_back(payload[2]); - payload_sizes.push_back(payload.size() - kFuHeaderSize); + payload_sizes.push_back(payload.size() - kFuHeaderSizeBytes); } - EXPECT_TRUE(fu_header.front() & kH265SBit); - EXPECT_TRUE(fu_header.back() & kH265EBit); + EXPECT_TRUE(fu_header.front() & kH265SBitMask); + EXPECT_TRUE(fu_header.back() & kH265EBitMask); // Clear S and E bits before testing all are duplicating same original header. - fu_header.front() &= ~kH265SBit; - fu_header.back() &= ~kH265EBit; - uint8_t nalu_type = (nalu[0][0] & kNaluTypeMask) >> 1; + fu_header.front() &= ~kH265SBitMask; + fu_header.back() &= ~kH265EBitMask; + uint8_t nalu_type = (nalu[0][0] & kH265TypeMask) >> 1; EXPECT_THAT(fu_header, Each(Eq(nalu_type))); return payload_sizes; @@ -403,7 +400,7 @@ TEST(RtpPacketizerH265Test, FuBig) { limits.max_payload_len = 1200; // Generate 10 full sized packets, leave room for FU headers. EXPECT_THAT( - TestFu(10 * (1200 - kFuHeaderSize), limits), + TestFu(10 * (1200 - kFuHeaderSizeBytes), limits), ElementsAre(1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197, 1197)); } @@ -449,30 +446,30 @@ TEST_P(RtpPacketizerH265ParametrizedTest, MixedApFu) { if (expected_packet.aggregated) { int type = H265::ParseNaluType(packets[i].payload()[0]); EXPECT_THAT(type, H265::NaluType::kAp); - auto payload = packets[i].payload().subview(kNalHeaderSize); + auto payload = packets[i].payload().subview(kH265NalHeaderSizeBytes); int offset = 0; // Generated AP packet header and payload align for (int j = expected_packet.nalu_index; j < expected_packet.nalu_number; j++) { - EXPECT_THAT(payload.subview(0, kLengthFieldLength), + EXPECT_THAT(payload.subview(0, kH265LengthFieldSizeBytes), ElementsAre(0, nalus[j].size())); - EXPECT_THAT( - payload.subview(offset + kLengthFieldLength, nalus[j].size()), - ElementsAreArray(nalus[j])); - offset += kLengthFieldLength + nalus[j].size(); + EXPECT_THAT(payload.subview(offset + kH265LengthFieldSizeBytes, + nalus[j].size()), + ElementsAreArray(nalus[j])); + offset += kH265LengthFieldSizeBytes + nalus[j].size(); } } else { uint8_t fu_header = 0; - fu_header |= (expected_packet.first_fragment ? kH265SBit : 0); - fu_header |= (expected_packet.last_fragment ? kH265EBit : 0); + fu_header |= (expected_packet.first_fragment ? kH265SBitMask : 0); + fu_header |= (expected_packet.last_fragment ? kH265EBitMask : 0); fu_header |= H265::NaluType::kTrailR; - EXPECT_THAT(packets[i].payload().subview(0, kFuHeaderSize), + EXPECT_THAT(packets[i].payload().subview(0, kFuHeaderSizeBytes), ElementsAre(98, 2, fu_header)); - EXPECT_THAT( - packets[i].payload().subview(kFuHeaderSize), - ElementsAreArray(nalus[expected_packet.nalu_index].data() + - kNalHeaderSize + expected_packet.start_offset, - expected_packet.payload_size)); + EXPECT_THAT(packets[i].payload().subview(kFuHeaderSizeBytes), + ElementsAreArray(nalus[expected_packet.nalu_index].data() + + kH265NalHeaderSizeBytes + + expected_packet.start_offset, + expected_packet.payload_size)); } } } diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc new file mode 100644 index 0000000000..b54df7c271 --- /dev/null +++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.cc @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2024 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 "modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h" + +#include +#include +#include +#include +#include + +#include "absl/base/macros.h" +#include "absl/types/optional.h" +#include "absl/types/variant.h" +#include "api/video/video_codec_type.h" +#include "common_video/h264/h264_common.h" +#include "common_video/h265/h265_bitstream_parser.h" +#include "common_video/h265/h265_common.h" +#include "modules/rtp_rtcp/source/byte_io.h" +#include "modules/rtp_rtcp/source/rtp_packet_h265_common.h" +#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { +namespace { + +bool ParseApStartOffsets(const uint8_t* nalu_ptr, + size_t length_remaining, + std::vector* offsets) { + size_t offset = 0; + while (length_remaining > 0) { + // Buffer doesn't contain room for additional NALU length. + if (length_remaining < kH265LengthFieldSizeBytes) + return false; + // Read 16-bit NALU size defined in RFC7798 section 4.4.2. + uint16_t nalu_size = ByteReader::ReadBigEndian(nalu_ptr); + nalu_ptr += kH265LengthFieldSizeBytes; + length_remaining -= kH265LengthFieldSizeBytes; + if (nalu_size > length_remaining) + return false; + nalu_ptr += nalu_size; + length_remaining -= nalu_size; + + offsets->push_back(offset + kH265ApHeaderSizeBytes); + offset += kH265LengthFieldSizeBytes + nalu_size; + } + return true; +} + +absl::optional ProcessApOrSingleNalu( + rtc::CopyOnWriteBuffer rtp_payload) { + // Skip the single NALU header (payload header), aggregated packet case will + // be checked later. + if (rtp_payload.size() <= kH265PayloadHeaderSizeBytes) { + RTC_LOG(LS_ERROR) << "Single NALU header truncated."; + return absl::nullopt; + } + const uint8_t* const payload_data = rtp_payload.cdata(); + absl::optional parsed_payload( + absl::in_place); + parsed_payload->video_header.width = 0; + parsed_payload->video_header.height = 0; + parsed_payload->video_header.codec = kVideoCodecH265; + parsed_payload->video_header.is_first_packet_in_frame = true; + + const uint8_t* nalu_start = payload_data + kH265PayloadHeaderSizeBytes; + const size_t nalu_length = rtp_payload.size() - kH265PayloadHeaderSizeBytes; + uint8_t nal_type = (payload_data[0] & kH265TypeMask) >> 1; + std::vector nalu_start_offsets; + rtc::CopyOnWriteBuffer video_payload; + if (nal_type == H265::NaluType::kAp) { + // Skip the aggregated packet header (Aggregated packet NAL type + length). + if (rtp_payload.size() <= kH265ApHeaderSizeBytes) { + RTC_LOG(LS_ERROR) << "Aggregated packet header truncated."; + return absl::nullopt; + } + + if (!ParseApStartOffsets(nalu_start, nalu_length, &nalu_start_offsets)) { + RTC_LOG(LS_ERROR) + << "Aggregated packet with incorrect NALU packet lengths."; + return absl::nullopt; + } + + nal_type = (payload_data[kH265ApHeaderSizeBytes] & kH265TypeMask) >> 1; + } else { + nalu_start_offsets.push_back(0); + } + parsed_payload->video_header.frame_type = VideoFrameType::kVideoFrameDelta; + + nalu_start_offsets.push_back(rtp_payload.size() + + kH265LengthFieldSizeBytes); // End offset. + for (size_t i = 0; i < nalu_start_offsets.size() - 1; ++i) { + size_t start_offset = nalu_start_offsets[i]; + // End offset is actually start offset for next unit, excluding length field + // so remove that from this units length. + size_t end_offset = nalu_start_offsets[i + 1] - kH265LengthFieldSizeBytes; + if (end_offset - start_offset < kH265NalHeaderSizeBytes) { + RTC_LOG(LS_ERROR) << "Aggregated packet too short"; + return absl::nullopt; + } + + // Insert start code before each NALU in aggregated packet. + video_payload.AppendData(kStartCode); + video_payload.AppendData(&payload_data[start_offset], + end_offset - start_offset); + + uint8_t nalu_type = (payload_data[start_offset] & kH265TypeMask) >> 1; + start_offset += kH265NalHeaderSizeBytes; + switch (nalu_type) { + case H265::NaluType::kBlaWLp: + case H265::NaluType::kBlaWRadl: + case H265::NaluType::kBlaNLp: + case H265::NaluType::kIdrWRadl: + case H265::NaluType::kIdrNLp: + case H265::NaluType::kCra: + case H265::NaluType::kRsvIrapVcl23: + parsed_payload->video_header.frame_type = + VideoFrameType::kVideoFrameKey; + ABSL_FALLTHROUGH_INTENDED; + case H265::NaluType::kSps: { + // Copy any previous data first (likely just the first header). + std::unique_ptr output_buffer(new rtc::Buffer()); + if (start_offset) + output_buffer->AppendData(payload_data, start_offset); + + absl::optional sps = H265SpsParser::ParseSps( + &payload_data[start_offset], end_offset - start_offset); + + if (sps) { + // TODO(bugs.webrtc.org/13485): Implement the size calculation taking + // VPS->vui_parameters.def_disp_win_xx_offset into account. + parsed_payload->video_header.width = sps->width; + parsed_payload->video_header.height = sps->height; + } else { + RTC_LOG(LS_WARNING) << "Failed to parse SPS from SPS slice."; + } + } + ABSL_FALLTHROUGH_INTENDED; + case H265::NaluType::kVps: + case H265::NaluType::kPps: + case H265::NaluType::kTrailN: + case H265::NaluType::kTrailR: + // Slices below don't contain SPS or PPS ids. + case H265::NaluType::kAud: + case H265::NaluType::kTsaN: + case H265::NaluType::kTsaR: + case H265::NaluType::kStsaN: + case H265::NaluType::kStsaR: + case H265::NaluType::kRadlN: + case H265::NaluType::kRadlR: + case H265::NaluType::kPrefixSei: + case H265::NaluType::kSuffixSei: + break; + case H265::NaluType::kAp: + case H265::NaluType::kFu: + case H265::NaluType::kPaci: + RTC_LOG(LS_WARNING) << "Unexpected AP, FU or PACI received."; + return absl::nullopt; + } + } + parsed_payload->video_payload = video_payload; + return parsed_payload; +} + +absl::optional ParseFuNalu( + rtc::CopyOnWriteBuffer rtp_payload) { + if (rtp_payload.size() < kH265FuHeaderSizeBytes + kH265NalHeaderSizeBytes) { + RTC_LOG(LS_ERROR) << "FU NAL units truncated."; + return absl::nullopt; + } + absl::optional parsed_payload( + absl::in_place); + + uint8_t f = rtp_payload.cdata()[0] & kH265FBit; + uint8_t layer_id_h = rtp_payload.cdata()[0] & kH265LayerIDHMask; + uint8_t layer_id_l_unshifted = rtp_payload.cdata()[1] & kH265LayerIDLMask; + uint8_t tid = rtp_payload.cdata()[1] & kH265TIDMask; + + uint8_t original_nal_type = rtp_payload.cdata()[2] & kH265TypeMaskInFuHeader; + bool first_fragment = rtp_payload.cdata()[2] & kH265SBitMask; + if (first_fragment) { + rtp_payload = rtp_payload.Slice( + kH265FuHeaderSizeBytes, rtp_payload.size() - kH265FuHeaderSizeBytes); + rtp_payload.MutableData()[0] = f | original_nal_type << 1 | layer_id_h; + rtp_payload.MutableData()[1] = layer_id_l_unshifted | tid; + rtc::CopyOnWriteBuffer video_payload; + // Insert start code before the first fragment in FU. + video_payload.AppendData(kStartCode); + video_payload.AppendData(rtp_payload); + parsed_payload->video_payload = video_payload; + } else { + parsed_payload->video_payload = rtp_payload.Slice( + kH265NalHeaderSizeBytes + kH265FuHeaderSizeBytes, + rtp_payload.size() - kH265NalHeaderSizeBytes - kH265FuHeaderSizeBytes); + } + + if (original_nal_type == H265::NaluType::kIdrWRadl || + original_nal_type == H265::NaluType::kIdrNLp || + original_nal_type == H265::NaluType::kCra) { + parsed_payload->video_header.frame_type = VideoFrameType::kVideoFrameKey; + } else { + parsed_payload->video_header.frame_type = VideoFrameType::kVideoFrameDelta; + } + parsed_payload->video_header.width = 0; + parsed_payload->video_header.height = 0; + parsed_payload->video_header.codec = kVideoCodecH265; + parsed_payload->video_header.is_first_packet_in_frame = first_fragment; + + return parsed_payload; +} + +} // namespace + +absl::optional +VideoRtpDepacketizerH265::Parse(rtc::CopyOnWriteBuffer rtp_payload) { + if (rtp_payload.empty()) { + RTC_LOG(LS_ERROR) << "Empty payload."; + return absl::nullopt; + } + + uint8_t nal_type = (rtp_payload.cdata()[0] & kH265TypeMask) >> 1; + + if (nal_type == H265::NaluType::kFu) { + // Fragmented NAL units (FU). + return ParseFuNalu(std::move(rtp_payload)); + } else if (nal_type == H265::NaluType::kPaci) { + // TODO(bugs.webrtc.org/13485): Implement PACI parse for H265 + RTC_LOG(LS_ERROR) << "Not support type:" << nal_type; + return absl::nullopt; + } else { + // Single NAL unit packet or Aggregated packets (AP). + return ProcessApOrSingleNalu(std::move(rtp_payload)); + } +} + +} // namespace webrtc diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h new file mode 100644 index 0000000000..ed5290d1cb --- /dev/null +++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 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 MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H265_H_ +#define MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H265_H_ + +#include "absl/types/optional.h" +#include "modules/rtp_rtcp/source/video_rtp_depacketizer.h" +#include "rtc_base/copy_on_write_buffer.h" + +namespace webrtc { +class VideoRtpDepacketizerH265 : public VideoRtpDepacketizer { + public: + ~VideoRtpDepacketizerH265() override = default; + + absl::optional Parse( + rtc::CopyOnWriteBuffer rtp_payload) override; +}; +} // namespace webrtc + +#endif // MODULES_RTP_RTCP_SOURCE_VIDEO_RTP_DEPACKETIZER_H265_H_ diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc new file mode 100644 index 0000000000..a630671a71 --- /dev/null +++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_h265_unittest.cc @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2024 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 "modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h" + +#include +#include + +#include "absl/types/optional.h" +#include "api/array_view.h" +#include "common_video/h265/h265_common.h" +#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" +#include "modules/rtp_rtcp/source/byte_io.h" +#include "modules/rtp_rtcp/source/rtp_packet_h265_common.h" +#include "rtc_base/copy_on_write_buffer.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +using ::testing::Each; +using ::testing::ElementsAre; +using ::testing::ElementsAreArray; +using ::testing::Eq; +using ::testing::IsEmpty; +using ::testing::SizeIs; + +TEST(VideoRtpDepacketizerH265Test, SingleNalu) { + uint8_t packet[3] = {0x26, 0x02, + 0xFF}; // F=0, Type=19 (Idr), LayerId=0, TID=2. + uint8_t expected_packet[] = {0x00, 0x00, 0x00, 0x01, 0x26, 0x02, 0xff}; + rtc::CopyOnWriteBuffer rtp_payload(packet); + + VideoRtpDepacketizerH265 depacketizer; + absl::optional parsed = + depacketizer.Parse(rtp_payload); + ASSERT_TRUE(parsed); + + EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(), + parsed->video_payload.size()), + ElementsAreArray(expected_packet)); + EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey); + EXPECT_EQ(parsed->video_header.codec, kVideoCodecH265); + EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame); +} + +TEST(VideoRtpDepacketizerH265Test, SingleNaluSpsWithResolution) { + // SPS for a 1280x720 camera capture from ffmpeg on linux. Contains + // emulation bytes but no cropping. This buffer is generated + // with following command: + // 1) ffmpeg -i /dev/video0 -r 30 -c:v libx265 -s 1280x720 camera.h265 + // + // 2) Open camera.h265 and find the SPS, generally everything between the + // second and third start codes (0 0 0 1 or 0 0 1). The first two bytes + // 0x42 and 0x02 shows the nal header of SPS. + uint8_t packet[] = {0x42, 0x02, 0x01, 0x04, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x5d, 0xb0, 0x02, 0x80, 0x80, 0x2d, 0x16, 0x59, + 0x59, 0xa4, 0x93, 0x2b, 0x80, 0x40, 0x00, 0x00, + 0x03, 0x00, 0x40, 0x00, 0x00, 0x07, 0x82}; + uint8_t expected_packet[] = { + 0x00, 0x00, 0x00, 0x01, 0x42, 0x02, 0x01, 0x04, 0x08, 0x00, 0x00, + 0x03, 0x00, 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x5d, 0xb0, + 0x02, 0x80, 0x80, 0x2d, 0x16, 0x59, 0x59, 0xa4, 0x93, 0x2b, 0x80, + 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x07, 0x82}; + rtc::CopyOnWriteBuffer rtp_payload(packet); + + VideoRtpDepacketizerH265 depacketizer; + absl::optional parsed = + depacketizer.Parse(rtp_payload); + ASSERT_TRUE(parsed); + + EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(), + parsed->video_payload.size()), + ElementsAreArray(expected_packet)); + EXPECT_EQ(parsed->video_header.codec, kVideoCodecH265); + EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame); + EXPECT_EQ(parsed->video_header.width, 1280u); + EXPECT_EQ(parsed->video_header.height, 720u); +} + +TEST(VideoRtpDepacketizerH265Test, PaciPackets) { + uint8_t packet[2] = {0x64, 0x02}; // F=0, Type=50 (PACI), LayerId=0, TID=2. + rtc::CopyOnWriteBuffer rtp_payload(packet); + + VideoRtpDepacketizerH265 depacketizer; + absl::optional parsed = + depacketizer.Parse(rtp_payload); + ASSERT_FALSE(parsed); +} + +TEST(VideoRtpDepacketizerH265Test, ApKey) { + uint8_t payload_header[] = {0x60, 0x02}; + uint8_t vps_nalu_size[] = {0, 0x17}; + uint8_t sps_nalu_size[] = {0, 0x27}; + uint8_t pps_nalu_size[] = {0, 0x32}; + uint8_t slice_nalu_size[] = {0, 0xa}; + uint8_t start_code[] = {0x00, 0x00, 0x00, 0x01}; + // VPS/SPS/PPS/IDR for a 1280x720 camera capture from ffmpeg on linux. + // Contains emulation bytes but no cropping. This buffer is generated with + // following command: 1) ffmpeg -i /dev/video0 -r 30 -c:v libx265 -s 1280x720 + // camera.h265 + // + // 2) Open camera.h265 and find: + // VPS - generally everything between the first and second start codes (0 0 0 + // 1 or 0 0 1). The first two bytes 0x40 and 0x02 shows the nal header of VPS. + // SPS - generally everything between the + // second and third start codes (0 0 0 1 or 0 0 1). The first two bytes + // 0x42 and 0x02 shows the nal header of SPS. + // PPS - generally everything between the third and fourth start codes (0 0 0 + // 1 or 0 0 1). The first two bytes 0x44 and 0x02 shows the nal header of PPS. + // IDR - Part of the keyframe bitstream (no need to show all the bytes for + // depacketizer testing). The first two bytes 0x26 and 0x02 shows the nal + // header of IDR frame. + uint8_t vps[] = { + 0x40, 0x02, 0x1c, 0x01, 0xff, 0xff, 0x04, 0x08, 0x00, 0x00, 0x03, 0x00, + 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78, 0x95, 0x98, 0x09, + }; + uint8_t sps[] = {0x42, 0x02, 0x01, 0x04, 0x08, 0x00, 0x00, 0x03, 0x00, 0x9d, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x5d, 0xb0, 0x02, 0x80, + 0x80, 0x2d, 0x16, 0x59, 0x59, 0xa4, 0x93, 0x2b, 0x80, 0x40, + 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x07, 0x82}; + uint8_t pps[] = {0x44, 0x02, 0xa4, 0x04, 0x55, 0xa2, 0x6d, 0xce, 0xc0, 0xc3, + 0xed, 0x0b, 0xac, 0xbc, 0x00, 0xc4, 0x44, 0x2e, 0xf7, 0x55, + 0xfd, 0x05, 0x86, 0x92, 0x19, 0xdf, 0x58, 0xec, 0x38, 0x36, + 0xb7, 0x7c, 0x00, 0x15, 0x33, 0x78, 0x03, 0x67, 0x26, 0x0f, + 0x7b, 0x30, 0x1c, 0xd7, 0xd4, 0x3a, 0xec, 0xad, 0xef, 0x73}; + uint8_t idr[] = {0x26, 0x02, 0xaf, 0x08, 0x4a, 0x31, 0x11, 0x15, 0xe5, 0xc0}; + + rtc::Buffer packet; + packet.AppendData(payload_header); + packet.AppendData(vps_nalu_size); + packet.AppendData(vps); + packet.AppendData(sps_nalu_size); + packet.AppendData(sps); + packet.AppendData(pps_nalu_size); + packet.AppendData(pps); + packet.AppendData(slice_nalu_size); + packet.AppendData(idr); + + rtc::Buffer expected_packet; + expected_packet.AppendData(start_code); + expected_packet.AppendData(vps); + expected_packet.AppendData(start_code); + expected_packet.AppendData(sps); + expected_packet.AppendData(start_code); + expected_packet.AppendData(pps); + expected_packet.AppendData(start_code); + expected_packet.AppendData(idr); + + // clang-format on + rtc::CopyOnWriteBuffer rtp_payload(packet); + + VideoRtpDepacketizerH265 depacketizer; + absl::optional parsed = + depacketizer.Parse(rtp_payload); + ASSERT_TRUE(parsed); + + EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(), + parsed->video_payload.size()), + ElementsAreArray(expected_packet)); + EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey); + EXPECT_EQ(parsed->video_header.codec, kVideoCodecH265); + EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame); +} + +TEST(VideoRtpDepacketizerH265Test, ApNaluSpsWithResolution) { + uint8_t payload_header[] = {0x60, 0x02}; + uint8_t vps_nalu_size[] = {0, 0x17}; + uint8_t sps_nalu_size[] = {0, 0x27}; + uint8_t pps_nalu_size[] = {0, 0x32}; + uint8_t slice_nalu_size[] = {0, 0xa}; + uint8_t start_code[] = {0x00, 0x00, 0x00, 0x01}; + // The VPS/SPS/PPS/IDR bytes are generated using the same way as above case. + uint8_t vps[] = { + 0x40, 0x02, 0x1c, 0x01, 0xff, 0xff, 0x04, 0x08, 0x00, 0x00, 0x03, 0x00, + 0x9d, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x78, 0x95, 0x98, 0x09, + }; + uint8_t sps[] = {0x42, 0x02, 0x01, 0x04, 0x08, 0x00, 0x00, 0x03, 0x00, 0x9d, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x5d, 0xb0, 0x02, 0x80, + 0x80, 0x2d, 0x16, 0x59, 0x59, 0xa4, 0x93, 0x2b, 0x80, 0x40, + 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x07, 0x82}; + uint8_t pps[] = {0x44, 0x02, 0xa4, 0x04, 0x55, 0xa2, 0x6d, 0xce, 0xc0, 0xc3, + 0xed, 0x0b, 0xac, 0xbc, 0x00, 0xc4, 0x44, 0x2e, 0xf7, 0x55, + 0xfd, 0x05, 0x86, 0x92, 0x19, 0xdf, 0x58, 0xec, 0x38, 0x36, + 0xb7, 0x7c, 0x00, 0x15, 0x33, 0x78, 0x03, 0x67, 0x26, 0x0f, + 0x7b, 0x30, 0x1c, 0xd7, 0xd4, 0x3a, 0xec, 0xad, 0xef, 0x73}; + uint8_t idr[] = {0x26, 0x02, 0xaf, 0x08, 0x4a, 0x31, 0x11, 0x15, 0xe5, 0xc0}; + + rtc::Buffer packet; + packet.AppendData(payload_header); + packet.AppendData(vps_nalu_size); + packet.AppendData(vps); + packet.AppendData(sps_nalu_size); + packet.AppendData(sps); + packet.AppendData(pps_nalu_size); + packet.AppendData(pps); + packet.AppendData(slice_nalu_size); + packet.AppendData(idr); + + rtc::Buffer expected_packet; + expected_packet.AppendData(start_code); + expected_packet.AppendData(vps); + expected_packet.AppendData(start_code); + expected_packet.AppendData(sps); + expected_packet.AppendData(start_code); + expected_packet.AppendData(pps); + expected_packet.AppendData(start_code); + expected_packet.AppendData(idr); + + rtc::CopyOnWriteBuffer rtp_payload(packet); + + VideoRtpDepacketizerH265 depacketizer; + absl::optional parsed = + depacketizer.Parse(rtp_payload); + ASSERT_TRUE(parsed); + + EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(), + parsed->video_payload.size()), + ElementsAreArray(expected_packet)); + EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameKey); + EXPECT_EQ(parsed->video_header.codec, kVideoCodecH265); + EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame); + EXPECT_EQ(parsed->video_header.width, 1280u); + EXPECT_EQ(parsed->video_header.height, 720u); +} + +TEST(VideoRtpDepacketizerH265Test, EmptyApRejected) { + uint8_t lone_empty_packet[] = {0x60, 0x02, // F=0, Type=48 (kH265Ap). + 0x00, 0x00}; + uint8_t leading_empty_packet[] = {0x60, 0x02, // F=0, Type=48 (kH265Ap). + 0x00, 0x00, 0x00, 0x05, 0x26, + 0x02, 0xFF, 0x00, 0x11}; // kIdrWRadl + uint8_t middle_empty_packet[] = {0x60, 0x02, // F=0, Type=48 (kH265Ap). + 0x00, 0x04, 0x26, 0x02, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x05, + 0x26, 0x02, 0xFF, 0x00, 0x11}; // kIdrWRadl + uint8_t trailing_empty_packet[] = {0x60, 0x02, // F=0, Type=48 (kH265Ap). + 0x00, 0x04, 0x26, + 0x02, 0xFF, 0x00, // kIdrWRadl + 0x00, 0x00}; + + VideoRtpDepacketizerH265 depacketizer; + EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(lone_empty_packet))); + EXPECT_FALSE( + depacketizer.Parse(rtc::CopyOnWriteBuffer(leading_empty_packet))); + EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(middle_empty_packet))); + EXPECT_FALSE( + depacketizer.Parse(rtc::CopyOnWriteBuffer(trailing_empty_packet))); +} + +TEST(VideoRtpDepacketizerH265Test, ApDelta) { + uint8_t packet[20] = {0x60, 0x02, // F=0, Type=48 (kH265Ap). + // Length, nal header, payload. + 0, 0x03, 0x02, 0x02, 0xFF, // TrailR + 0, 0x04, 0x02, 0x02, 0xFF, 0x00, // TrailR + 0, 0x05, 0x02, 0x02, 0xFF, 0x00, 0x11}; // TrailR + uint8_t expected_packet[] = { + 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xFF, // TrailR + 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xFF, 0x00, // TrailR + 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0xFF, 0x00, 0x11}; // TrailR + rtc::CopyOnWriteBuffer rtp_payload(packet); + + VideoRtpDepacketizerH265 depacketizer; + absl::optional parsed = + depacketizer.Parse(rtp_payload); + ASSERT_TRUE(parsed); + + EXPECT_THAT(rtc::MakeArrayView(parsed->video_payload.cdata(), + parsed->video_payload.size()), + ElementsAreArray(expected_packet)); + + EXPECT_EQ(parsed->video_header.frame_type, VideoFrameType::kVideoFrameDelta); + EXPECT_EQ(parsed->video_header.codec, kVideoCodecH265); + EXPECT_TRUE(parsed->video_header.is_first_packet_in_frame); +} + +TEST(VideoRtpDepacketizerH265Test, Fu) { + // clang-format off + uint8_t packet1[] = { + 0x62, 0x02, // F=0, Type=49 (kH265Fu). + 0x93, // FU header kH265SBitMask | H265::kIdrWRadl. + 0xaf, 0x08, 0x4a, 0x31, 0x11, 0x15, 0xe5, 0xc0 // Payload. + }; + // clang-format on + // F=0, Type=19, (kIdrWRadl), tid=1, nalu header: 00100110 00000010, which is + // 0x26, 0x02 + const uint8_t kExpected1[] = {0x00, 0x00, 0x00, 0x01, 0x26, 0x02, 0xaf, + 0x08, 0x4a, 0x31, 0x11, 0x15, 0xe5, 0xc0}; + + uint8_t packet2[] = { + 0x62, 0x02, // F=0, Type=49 (kH265Fu). + H265::kIdrWRadl, // FU header. + 0x02 // Payload. + }; + const uint8_t kExpected2[] = {0x02}; + + uint8_t packet3[] = { + 0x62, 0x02, // F=0, Type=49 (kH265Fu). + 0x33, // FU header kH265EBitMask | H265::kIdrWRadl. + 0x03 // Payload. + }; + const uint8_t kExpected3[] = {0x03}; + + VideoRtpDepacketizerH265 depacketizer; + absl::optional parsed1 = + depacketizer.Parse(rtc::CopyOnWriteBuffer(packet1)); + ASSERT_TRUE(parsed1); + // We expect that the first packet is one byte shorter since the FU header + // has been replaced by the original nal header. + EXPECT_THAT(rtc::MakeArrayView(parsed1->video_payload.cdata(), + parsed1->video_payload.size()), + ElementsAreArray(kExpected1)); + EXPECT_EQ(parsed1->video_header.frame_type, VideoFrameType::kVideoFrameKey); + EXPECT_EQ(parsed1->video_header.codec, kVideoCodecH265); + EXPECT_TRUE(parsed1->video_header.is_first_packet_in_frame); + + // Following packets will be 2 bytes shorter since they will only be appended + // onto the first packet. + auto parsed2 = depacketizer.Parse(rtc::CopyOnWriteBuffer(packet2)); + EXPECT_THAT(rtc::MakeArrayView(parsed2->video_payload.cdata(), + parsed2->video_payload.size()), + ElementsAreArray(kExpected2)); + EXPECT_FALSE(parsed2->video_header.is_first_packet_in_frame); + EXPECT_EQ(parsed2->video_header.codec, kVideoCodecH265); + + auto parsed3 = depacketizer.Parse(rtc::CopyOnWriteBuffer(packet3)); + EXPECT_THAT(rtc::MakeArrayView(parsed3->video_payload.cdata(), + parsed3->video_payload.size()), + ElementsAreArray(kExpected3)); + EXPECT_FALSE(parsed3->video_header.is_first_packet_in_frame); + EXPECT_EQ(parsed3->video_header.codec, kVideoCodecH265); +} + +TEST(VideoRtpDepacketizerH265Test, EmptyPayload) { + rtc::CopyOnWriteBuffer empty; + VideoRtpDepacketizerH265 depacketizer; + EXPECT_FALSE(depacketizer.Parse(empty)); +} + +TEST(VideoRtpDepacketizerH265Test, TruncatedFuNalu) { + const uint8_t kPayload[] = {0x62}; + VideoRtpDepacketizerH265 depacketizer; + EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload))); +} + +TEST(VideoRtpDepacketizerH265Test, TruncatedSingleApNalu) { + const uint8_t kPayload[] = {0xe0, 0x02, 0x40}; + VideoRtpDepacketizerH265 depacketizer; + EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload))); +} + +TEST(VideoRtpDepacketizerH265Test, ApPacketWithTruncatedNalUnits) { + const uint8_t kPayload[] = {0x60, 0x02, 0xED, 0xDF}; + VideoRtpDepacketizerH265 depacketizer; + EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload))); +} + +TEST(VideoRtpDepacketizerH265Test, TruncationJustAfterSingleApNalu) { + const uint8_t kPayload[] = {0x60, 0x02, 0x40, 0x40}; + VideoRtpDepacketizerH265 depacketizer; + EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload))); +} + +TEST(VideoRtpDepacketizerH265Test, ShortSpsPacket) { + const uint8_t kPayload[] = {0x40, 0x80, 0x00}; + VideoRtpDepacketizerH265 depacketizer; + EXPECT_TRUE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload))); +} + +TEST(VideoRtpDepacketizerH265Test, InvalidNaluSizeApNalu) { + const uint8_t kPayload[] = {0x60, 0x02, // F=0, Type=48 (kH265Ap). + // Length, nal header, payload. + 0, 0xff, 0x02, 0x02, 0xFF, // TrailR + 0, 0x05, 0x02, 0x02, 0xFF, 0x00, + 0x11}; // TrailR; + VideoRtpDepacketizerH265 depacketizer; + EXPECT_FALSE(depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload))); +} + +TEST(VideoRtpDepacketizerH265Test, SeiPacket) { + const uint8_t kPayload[] = { + 0x4e, 0x02, // F=0, Type=39 (kPrefixSei). + 0x03, 0x03, 0x03, 0x03 // Payload. + }; + VideoRtpDepacketizerH265 depacketizer; + auto parsed = depacketizer.Parse(rtc::CopyOnWriteBuffer(kPayload)); + ASSERT_TRUE(parsed); +} + +} // namespace +} // namespace webrtc diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn index 083c20c6f4..4f6a542e54 100644 --- a/test/fuzzers/BUILD.gn +++ b/test/fuzzers/BUILD.gn @@ -132,6 +132,11 @@ if (rtc_use_h265) { "../../modules/video_coding/", ] } + + webrtc_fuzzer_test("h265_depacketizer_fuzzer") { + sources = [ "h265_depacketizer_fuzzer.cc" ] + deps = [ "../../modules/rtp_rtcp" ] + } } webrtc_fuzzer_test("forward_error_correction_fuzzer") { diff --git a/test/fuzzers/h265_depacketizer_fuzzer.cc b/test/fuzzers/h265_depacketizer_fuzzer.cc new file mode 100644 index 0000000000..00025ef887 --- /dev/null +++ b/test/fuzzers/h265_depacketizer_fuzzer.cc @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 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 "modules/rtp_rtcp/source/video_rtp_depacketizer_h265.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + if (size > 200000) + return; + VideoRtpDepacketizerH265 depacketizer; + depacketizer.Parse(rtc::CopyOnWriteBuffer(data, size)); +} +} // namespace webrtc diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc index badb942cd4..7f6565346c 100644 --- a/video/rtp_video_stream_receiver2.cc +++ b/video/rtp_video_stream_receiver2.cc @@ -803,6 +803,7 @@ void RtpVideoStreamReceiver2::OnInsertedPacket( if (packet->is_last_packet_in_frame()) { auto depacketizer_it = payload_type_map_.find(first_packet->payload_type); RTC_CHECK(depacketizer_it != payload_type_map_.end()); + RTC_CHECK(depacketizer_it->second); rtc::scoped_refptr bitstream = depacketizer_it->second->AssembleFrame(payloads); From 7aa797244d01239c7be51b3ef0310d405093449f Mon Sep 17 00:00:00 2001 From: Tony Herre Date: Mon, 29 Jan 2024 08:31:14 +0100 Subject: [PATCH 033/170] Propagate sequence number to cloned encoded audio frames Bug: chromium:1520859 Change-Id: I6ce0304c850158ebfea1cb88bbcc74b09904fac2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336061 Auto-Submit: Tony Herre Reviewed-by: Stefan Holmer Commit-Queue: Stefan Holmer Cr-Commit-Position: refs/heads/main@{#41629} --- api/frame_transformer_interface.h | 6 +----- audio/channel_send_frame_transformer_delegate.cc | 14 +++++++++----- ...nel_send_frame_transformer_delegate_unittest.cc | 2 ++ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/api/frame_transformer_interface.h b/api/frame_transformer_interface.h index 5bbcffe28e..102ac33334 100644 --- a/api/frame_transformer_interface.h +++ b/api/frame_transformer_interface.h @@ -73,11 +73,7 @@ class TransformableAudioFrameInterface : public TransformableFrameInterface { virtual rtc::ArrayView GetContributingSources() const = 0; - // TODO(crbug.com/1453226): Change this to pure virtual after it - // is implemented everywhere. - virtual const absl::optional SequenceNumber() const { - return absl::nullopt; - } + virtual const absl::optional SequenceNumber() const = 0; virtual absl::optional AbsoluteCaptureTimestamp() const = 0; diff --git a/audio/channel_send_frame_transformer_delegate.cc b/audio/channel_send_frame_transformer_delegate.cc index ac32410aed..6d3c011862 100644 --- a/audio/channel_send_frame_transformer_delegate.cc +++ b/audio/channel_send_frame_transformer_delegate.cc @@ -58,7 +58,8 @@ class TransformableOutgoingAudioFrame absl::optional absolute_capture_timestamp_ms, uint32_t ssrc, std::vector csrcs, - const std::string& codec_mime_type) + const std::string& codec_mime_type, + absl::optional sequence_number) : frame_type_(frame_type), payload_type_(payload_type), rtp_timestamp_with_offset_(rtp_timestamp_with_offset), @@ -66,7 +67,8 @@ class TransformableOutgoingAudioFrame absolute_capture_timestamp_ms_(absolute_capture_timestamp_ms), ssrc_(ssrc), csrcs_(std::move(csrcs)), - codec_mime_type_(codec_mime_type) {} + codec_mime_type_(codec_mime_type), + sequence_number_(sequence_number) {} ~TransformableOutgoingAudioFrame() override = default; rtc::ArrayView GetData() const override { return payload_; } void SetData(rtc::ArrayView data) override { @@ -88,7 +90,7 @@ class TransformableOutgoingAudioFrame } const absl::optional SequenceNumber() const override { - return absl::nullopt; + return sequence_number_; } void SetRTPTimestamp(uint32_t rtp_timestamp_with_offset) override { @@ -108,6 +110,7 @@ class TransformableOutgoingAudioFrame uint32_t ssrc_; std::vector csrcs_; std::string codec_mime_type_; + absl::optional sequence_number_; }; } // namespace @@ -155,7 +158,8 @@ void ChannelSendFrameTransformerDelegate::Transform( std::make_unique( frame_type, payload_type, rtp_timestamp, payload_data, payload_size, absolute_capture_timestamp_ms, ssrc, - /*csrcs=*/std::vector(), codec_mimetype)); + /*csrcs=*/std::vector(), codec_mimetype, + /*sequence_number=*/absl::nullopt)); } void ChannelSendFrameTransformerDelegate::OnTransformedFrame( @@ -203,7 +207,7 @@ std::unique_ptr CloneSenderAudioFrame( original->GetPayloadType(), original->GetTimestamp(), original->GetData().data(), original->GetData().size(), original->AbsoluteCaptureTimestamp(), original->GetSsrc(), - std::move(csrcs), original->GetMimeType()); + std::move(csrcs), original->GetMimeType(), original->SequenceNumber()); } } // namespace webrtc diff --git a/audio/channel_send_frame_transformer_delegate_unittest.cc b/audio/channel_send_frame_transformer_delegate_unittest.cc index 5295e2657f..428235efc9 100644 --- a/audio/channel_send_frame_transformer_delegate_unittest.cc +++ b/audio/channel_send_frame_transformer_delegate_unittest.cc @@ -68,6 +68,7 @@ std::unique_ptr CreateMockReceiverFrame( ON_CALL(*mock_frame, GetDirection) .WillByDefault(Return(TransformableFrameInterface::Direction::kReceiver)); ON_CALL(*mock_frame, GetContributingSources).WillByDefault(Return(csrcs)); + ON_CALL(*mock_frame, SequenceNumber).WillByDefault(Return(987654321)); return mock_frame; } @@ -252,6 +253,7 @@ TEST(ChannelSendFrameTransformerDelegateTest, CloningReceiverFrameWithCsrcs) { ASSERT_NE(frame->GetContributingSources().size(), 0u); EXPECT_THAT(cloned_frame->GetContributingSources(), ElementsAreArray(frame->GetContributingSources())); + EXPECT_EQ(cloned_frame->SequenceNumber(), frame->SequenceNumber()); } } // namespace From 62cee88e4b02527385ef89397601fb9649f3bcd5 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 29 Jan 2024 18:38:21 +0100 Subject: [PATCH 034/170] Propagate Environment through QualityAnalyzingVideoDecoderFactory Bug: webrtc:15791 Change-Id: I9eddf7bf9fb66ee70495e9bc3c810126e2015287 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336800 Commit-Queue: Danil Chapovalov Reviewed-by: Jeremy Leconte Auto-Submit: Danil Chapovalov Commit-Queue: Jeremy Leconte Cr-Commit-Position: refs/heads/main@{#41630} --- test/pc/e2e/analyzer/video/BUILD.gn | 1 + .../e2e/analyzer/video/quality_analyzing_video_decoder.cc | 6 +++--- .../pc/e2e/analyzer/video/quality_analyzing_video_decoder.h | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/test/pc/e2e/analyzer/video/BUILD.gn b/test/pc/e2e/analyzer/video/BUILD.gn index 17876e54be..6adfc50049 100644 --- a/test/pc/e2e/analyzer/video/BUILD.gn +++ b/test/pc/e2e/analyzer/video/BUILD.gn @@ -130,6 +130,7 @@ rtc_library("quality_analyzing_video_decoder") { ":encoded_image_data_injector_api", ":simulcast_dummy_buffer_helper", "../../../../../api:video_quality_analyzer_api", + "../../../../../api/environment", "../../../../../api/video:encoded_image", "../../../../../api/video:video_frame", "../../../../../api/video_codecs:video_codecs_api", diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc index e17b5d5d83..3cd179370f 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc @@ -259,10 +259,10 @@ QualityAnalyzingVideoDecoderFactory::GetSupportedFormats() const { return delegate_->GetSupportedFormats(); } -std::unique_ptr -QualityAnalyzingVideoDecoderFactory::CreateVideoDecoder( +std::unique_ptr QualityAnalyzingVideoDecoderFactory::Create( + const Environment& env, const SdpVideoFormat& format) { - std::unique_ptr decoder = delegate_->CreateVideoDecoder(format); + std::unique_ptr decoder = delegate_->Create(env, format); return std::make_unique( peer_name_, std::move(decoder), extractor_, analyzer_); } diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h index 2f0c2b9d5d..daa919d7e4 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h @@ -18,6 +18,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "api/environment/environment.h" #include "api/test/video_quality_analyzer_interface.h" #include "api/video/encoded_image.h" #include "api/video/video_frame.h" @@ -136,8 +137,8 @@ class QualityAnalyzingVideoDecoderFactory : public VideoDecoderFactory { // Methods of VideoDecoderFactory interface. std::vector GetSupportedFormats() const override; - std::unique_ptr CreateVideoDecoder( - const SdpVideoFormat& format) override; + std::unique_ptr Create(const Environment& env, + const SdpVideoFormat& format) override; private: const std::string peer_name_; From 68e85b8d0d70f9696c43b4d3cb402213b91ca513 Mon Sep 17 00:00:00 2001 From: Dan Tan Date: Mon, 29 Jan 2024 15:02:59 -0800 Subject: [PATCH 035/170] Adds WebRTC-Audio-PriorityBitrate for controlling audio/video rate allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:15769 Change-Id: Id260fb9540ecb79b0c349937e55db343e04178c9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/334702 Reviewed-by: Jakob Ivarsson‎ Commit-Queue: Dan Tan Cr-Commit-Position: refs/heads/main@{#41631} --- audio/audio_send_stream.cc | 6 +++++ audio/audio_send_stream.h | 1 + audio/audio_send_stream_unittest.cc | 39 +++++++++++++++++++++++++++-- experiments/field_trials.py | 3 +++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index ba6cde8e79..2fdb5e63e7 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -157,6 +157,8 @@ AudioSendStream::AudioSendStream( event_log_(event_log), use_legacy_overhead_calculation_( field_trials_.IsEnabled("WebRTC-Audio-LegacyOverhead")), + enable_priority_bitrate_( + !field_trials_.IsDisabled("WebRTC-Audio-PriorityBitrate")), bitrate_allocator_(bitrate_allocator), rtp_transport_(rtp_transport), rtp_rtcp_module_(channel_send_->GetRtpRtcp()), @@ -807,6 +809,10 @@ void AudioSendStream::ConfigureBitrateObserver() { priority_bitrate = *allocation_settings_.priority_bitrate_raw; } + if (!enable_priority_bitrate_) { + priority_bitrate = DataRate::BitsPerSec(0); + } + bitrate_allocator_->AddObserver( this, MediaStreamAllocationConfig{ diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h index 374d7b1207..cf55ff6524 100644 --- a/audio/audio_send_stream.h +++ b/audio/audio_send_stream.h @@ -173,6 +173,7 @@ class AudioSendStream final : public webrtc::AudioSendStream, const std::unique_ptr channel_send_; RtcEventLog* const event_log_; const bool use_legacy_overhead_calculation_; + const bool enable_priority_bitrate_; int encoder_sample_rate_hz_ RTC_GUARDED_BY(worker_thread_checker_) = 0; size_t encoder_num_channels_ RTC_GUARDED_BY(worker_thread_checker_) = 0; diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc index 8c17326865..43f2fb14e7 100644 --- a/audio/audio_send_stream_unittest.cc +++ b/audio/audio_send_stream_unittest.cc @@ -21,6 +21,7 @@ #include "audio/audio_state.h" #include "audio/conversion.h" #include "audio/mock_voe_channel_proxy.h" +#include "call/test/mock_bitrate_allocator.h" #include "call/test/mock_rtp_transport_controller_send.h" #include "logging/rtc_event_log/mock/mock_rtc_event_log.h" #include "modules/audio_device/include/mock_audio_device.h" @@ -155,7 +156,6 @@ struct ConfigHelper { use_null_audio_processing ? nullptr : rtc::make_ref_counted>()), - bitrate_allocator_(&limit_observer_), audio_encoder_(nullptr) { using ::testing::Invoke; @@ -203,6 +203,7 @@ struct ConfigHelper { MockRtpRtcpInterface* rtp_rtcp() { return &rtp_rtcp_; } MockChannelSend* channel_send() { return channel_send_; } RtpTransportControllerSendInterface* transport() { return &rtp_transport_; } + MockBitrateAllocator* bitrate_allocator() { return &bitrate_allocator_; } static void AddBweToConfig(AudioSendStream::Config* config) { config->rtp.extensions.push_back(RtpExtension( @@ -328,7 +329,7 @@ struct ConfigHelper { ::testing::NiceMock rtp_transport_; ::testing::NiceMock rtp_rtcp_; ::testing::NiceMock limit_observer_; - BitrateAllocator bitrate_allocator_; + ::testing::NiceMock bitrate_allocator_; std::unique_ptr audio_encoder_; }; @@ -924,5 +925,39 @@ TEST(AudioSendStreamTest, ReconfigureWithFrameEncryptor) { send_stream->Reconfigure(new_config, nullptr); } } + +TEST(AudioSendStreamTest, DefaultsHonorsPriorityBitrate) { + ConfigHelper helper(true, true, true); + ScopedKeyValueConfig field_trials(helper.field_trials, + "WebRTC-Audio-Allocation/prio_rate:20/"); + auto send_stream = helper.CreateAudioSendStream(); + EXPECT_CALL(*helper.bitrate_allocator(), AddObserver(send_stream.get(), _)) + .WillOnce(Invoke( + [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + EXPECT_EQ(config.priority_bitrate_bps, 20000); + })); + EXPECT_CALL(*helper.channel_send(), StartSend()); + send_stream->Start(); + EXPECT_CALL(*helper.channel_send(), StopSend()); + send_stream->Stop(); +} + +TEST(AudioSendStreamTest, OverridesPriorityBitrate) { + ConfigHelper helper(true, true, true); + ScopedKeyValueConfig field_trials(helper.field_trials, + "WebRTC-Audio-Allocation/prio_rate:20/" + "WebRTC-Audio-PriorityBitrate/Disabled/"); + auto send_stream = helper.CreateAudioSendStream(); + EXPECT_CALL(*helper.bitrate_allocator(), AddObserver(send_stream.get(), _)) + .WillOnce(Invoke( + [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + EXPECT_EQ(config.priority_bitrate_bps, 0); + })); + EXPECT_CALL(*helper.channel_send(), StartSend()); + send_stream->Start(); + EXPECT_CALL(*helper.channel_send(), StopSend()); + send_stream->Stop(); +} + } // namespace test } // namespace webrtc diff --git a/experiments/field_trials.py b/experiments/field_trials.py index 70e131e3da..dff1ad1982 100755 --- a/experiments/field_trials.py +++ b/experiments/field_trials.py @@ -53,6 +53,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-Audio-OpusGeneratePlc', 'webrtc:13322', date(2024, 4, 1)), + FieldTrial('WebRTC-Audio-PriorityBitrate', + 'webrtc:15769', + date(2024, 4, 1)), FieldTrial('WebRTC-AV1-OverridePriorityBitrate', 'webrtc:15763', date(2024, 4, 1)), From 05a6f3b42561843fa0484ff4b26516b4ee8b7c83 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Mon, 29 Jan 2024 20:07:39 -0800 Subject: [PATCH 036/170] Update WebRTC code version (2024-01-30T04:07:38). Bug: None Change-Id: Id32a9f8bea4868a9d2de8cd2109153d18da685ae Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336822 Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41632} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 2e4e80dae9..12ea2ff210 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-29T04:16:27"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-30T04:07:38"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 765024e67b6cc1aed6adbc69488e691a44c9684e Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Thu, 18 Jan 2024 17:28:59 +0100 Subject: [PATCH 037/170] test: fix fuzzers line-endings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: None Change-Id: I95edb5482bfc9cfc7241963bbe43a3873aa814ad Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335143 Reviewed-by: Henrik Boström Commit-Queue: Philipp Hancke Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41633} --- test/fuzzers/rtp_format_h264_fuzzer.cc | 150 ++++++++++++------------- test/fuzzers/rtp_format_vp8_fuzzer.cc | 146 ++++++++++++------------ test/fuzzers/rtp_format_vp9_fuzzer.cc | 146 ++++++++++++------------ 3 files changed, 221 insertions(+), 221 deletions(-) diff --git a/test/fuzzers/rtp_format_h264_fuzzer.cc b/test/fuzzers/rtp_format_h264_fuzzer.cc index ddf2ca9d3d..97b0ce2c03 100644 --- a/test/fuzzers/rtp_format_h264_fuzzer.cc +++ b/test/fuzzers/rtp_format_h264_fuzzer.cc @@ -1,75 +1,75 @@ -/* - * Copyright (c) 2024 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 -#include - -#include "api/video/video_frame_type.h" -#include "modules/rtp_rtcp/source/rtp_format.h" -#include "modules/rtp_rtcp/source/rtp_format_h264.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "rtc_base/checks.h" -#include "test/fuzzers/fuzz_data_helper.h" - -namespace webrtc { -void FuzzOneInput(const uint8_t* data, size_t size) { - test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); - - RtpPacketizer::PayloadSizeLimits limits; - limits.max_payload_len = 1200; - // Read uint8_t to be sure reduction_lens are much smaller than - // max_payload_len and thus limits structure is valid. - limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); - limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); - limits.single_packet_reduction_len = - fuzz_input.ReadOrDefaultValue(0); - const H264PacketizationMode kPacketizationModes[] = { - H264PacketizationMode::NonInterleaved, - H264PacketizationMode::SingleNalUnit}; - - H264PacketizationMode packetization_mode = - fuzz_input.SelectOneOf(kPacketizationModes); - - // Main function under test: RtpPacketizerH264's constructor. - RtpPacketizerH264 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), - limits, packetization_mode); - - size_t num_packets = packetizer.NumPackets(); - if (num_packets == 0) { - return; - } - // When packetization was successful, validate NextPacket function too. - // While at it, check that packets respect the payload size limits. - RtpPacketToSend rtp_packet(nullptr); - // Single packet. - if (num_packets == 1) { - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.single_packet_reduction_len); - return; - } - // First packet. - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.first_packet_reduction_len); - // Middle packets. - for (size_t i = 1; i < num_packets - 1; ++i) { - rtp_packet.Clear(); - RTC_CHECK(packetizer.NextPacket(&rtp_packet)) - << "Failed to get packet#" << i; - RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) - << "Packet #" << i << " exceeds it's limit"; - } - // Last packet. - rtp_packet.Clear(); - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.last_packet_reduction_len); -} -} // namespace webrtc +/* + * Copyright (c) 2024 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 +#include + +#include "api/video/video_frame_type.h" +#include "modules/rtp_rtcp/source/rtp_format.h" +#include "modules/rtp_rtcp/source/rtp_format_h264.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); + + RtpPacketizer::PayloadSizeLimits limits; + limits.max_payload_len = 1200; + // Read uint8_t to be sure reduction_lens are much smaller than + // max_payload_len and thus limits structure is valid. + limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); + limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); + limits.single_packet_reduction_len = + fuzz_input.ReadOrDefaultValue(0); + const H264PacketizationMode kPacketizationModes[] = { + H264PacketizationMode::NonInterleaved, + H264PacketizationMode::SingleNalUnit}; + + H264PacketizationMode packetization_mode = + fuzz_input.SelectOneOf(kPacketizationModes); + + // Main function under test: RtpPacketizerH264's constructor. + RtpPacketizerH264 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), + limits, packetization_mode); + + size_t num_packets = packetizer.NumPackets(); + if (num_packets == 0) { + return; + } + // When packetization was successful, validate NextPacket function too. + // While at it, check that packets respect the payload size limits. + RtpPacketToSend rtp_packet(nullptr); + // Single packet. + if (num_packets == 1) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.single_packet_reduction_len); + return; + } + // First packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.first_packet_reduction_len); + // Middle packets. + for (size_t i = 1; i < num_packets - 1; ++i) { + rtp_packet.Clear(); + RTC_CHECK(packetizer.NextPacket(&rtp_packet)) + << "Failed to get packet#" << i; + RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) + << "Packet #" << i << " exceeds it's limit"; + } + // Last packet. + rtp_packet.Clear(); + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.last_packet_reduction_len); +} +} // namespace webrtc diff --git a/test/fuzzers/rtp_format_vp8_fuzzer.cc b/test/fuzzers/rtp_format_vp8_fuzzer.cc index c3c055de0f..93706e9253 100644 --- a/test/fuzzers/rtp_format_vp8_fuzzer.cc +++ b/test/fuzzers/rtp_format_vp8_fuzzer.cc @@ -1,73 +1,73 @@ -/* - * Copyright (c) 2024 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 -#include - -#include "api/video/video_frame_type.h" -#include "modules/rtp_rtcp/source/rtp_format.h" -#include "modules/rtp_rtcp/source/rtp_format_vp8.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "rtc_base/checks.h" -#include "test/fuzzers/fuzz_data_helper.h" - -namespace webrtc { -void FuzzOneInput(const uint8_t* data, size_t size) { - test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); - - RtpPacketizer::PayloadSizeLimits limits; - limits.max_payload_len = 1200; - // Read uint8_t to be sure reduction_lens are much smaller than - // max_payload_len and thus limits structure is valid. - limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); - limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); - limits.single_packet_reduction_len = - fuzz_input.ReadOrDefaultValue(0); - - RTPVideoHeaderVP8 hdr_info; - hdr_info.InitRTPVideoHeaderVP8(); - uint16_t picture_id = fuzz_input.ReadOrDefaultValue(0); - hdr_info.pictureId = - picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff; - - // Main function under test: RtpPacketizerVp8's constructor. - RtpPacketizerVp8 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), - limits, hdr_info); - - size_t num_packets = packetizer.NumPackets(); - if (num_packets == 0) { - return; - } - // When packetization was successful, validate NextPacket function too. - // While at it, check that packets respect the payload size limits. - RtpPacketToSend rtp_packet(nullptr); - // Single packet. - if (num_packets == 1) { - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.single_packet_reduction_len); - return; - } - // First packet. - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.first_packet_reduction_len); - // Middle packets. - for (size_t i = 1; i < num_packets - 1; ++i) { - RTC_CHECK(packetizer.NextPacket(&rtp_packet)) - << "Failed to get packet#" << i; - RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) - << "Packet #" << i << " exceeds it's limit"; - } - // Last packet. - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.last_packet_reduction_len); -} -} // namespace webrtc +/* + * Copyright (c) 2024 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 +#include + +#include "api/video/video_frame_type.h" +#include "modules/rtp_rtcp/source/rtp_format.h" +#include "modules/rtp_rtcp/source/rtp_format_vp8.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); + + RtpPacketizer::PayloadSizeLimits limits; + limits.max_payload_len = 1200; + // Read uint8_t to be sure reduction_lens are much smaller than + // max_payload_len and thus limits structure is valid. + limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); + limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); + limits.single_packet_reduction_len = + fuzz_input.ReadOrDefaultValue(0); + + RTPVideoHeaderVP8 hdr_info; + hdr_info.InitRTPVideoHeaderVP8(); + uint16_t picture_id = fuzz_input.ReadOrDefaultValue(0); + hdr_info.pictureId = + picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff; + + // Main function under test: RtpPacketizerVp8's constructor. + RtpPacketizerVp8 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), + limits, hdr_info); + + size_t num_packets = packetizer.NumPackets(); + if (num_packets == 0) { + return; + } + // When packetization was successful, validate NextPacket function too. + // While at it, check that packets respect the payload size limits. + RtpPacketToSend rtp_packet(nullptr); + // Single packet. + if (num_packets == 1) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.single_packet_reduction_len); + return; + } + // First packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.first_packet_reduction_len); + // Middle packets. + for (size_t i = 1; i < num_packets - 1; ++i) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)) + << "Failed to get packet#" << i; + RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) + << "Packet #" << i << " exceeds it's limit"; + } + // Last packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.last_packet_reduction_len); +} +} // namespace webrtc diff --git a/test/fuzzers/rtp_format_vp9_fuzzer.cc b/test/fuzzers/rtp_format_vp9_fuzzer.cc index 3b5e67f697..d95114eaef 100644 --- a/test/fuzzers/rtp_format_vp9_fuzzer.cc +++ b/test/fuzzers/rtp_format_vp9_fuzzer.cc @@ -1,73 +1,73 @@ -/* - * Copyright (c) 2024 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 -#include - -#include "api/video/video_frame_type.h" -#include "modules/rtp_rtcp/source/rtp_format.h" -#include "modules/rtp_rtcp/source/rtp_format_vp9.h" -#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" -#include "rtc_base/checks.h" -#include "test/fuzzers/fuzz_data_helper.h" - -namespace webrtc { -void FuzzOneInput(const uint8_t* data, size_t size) { - test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); - - RtpPacketizer::PayloadSizeLimits limits; - limits.max_payload_len = 1200; - // Read uint8_t to be sure reduction_lens are much smaller than - // max_payload_len and thus limits structure is valid. - limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); - limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); - limits.single_packet_reduction_len = - fuzz_input.ReadOrDefaultValue(0); - - RTPVideoHeaderVP9 hdr_info; - hdr_info.InitRTPVideoHeaderVP9(); - uint16_t picture_id = fuzz_input.ReadOrDefaultValue(0); - hdr_info.picture_id = - picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff; - - // Main function under test: RtpPacketizerVp9's constructor. - RtpPacketizerVp9 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), - limits, hdr_info); - - size_t num_packets = packetizer.NumPackets(); - if (num_packets == 0) { - return; - } - // When packetization was successful, validate NextPacket function too. - // While at it, check that packets respect the payload size limits. - RtpPacketToSend rtp_packet(nullptr); - // Single packet. - if (num_packets == 1) { - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.single_packet_reduction_len); - return; - } - // First packet. - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.first_packet_reduction_len); - // Middle packets. - for (size_t i = 1; i < num_packets - 1; ++i) { - RTC_CHECK(packetizer.NextPacket(&rtp_packet)) - << "Failed to get packet#" << i; - RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) - << "Packet #" << i << " exceeds it's limit"; - } - // Last packet. - RTC_CHECK(packetizer.NextPacket(&rtp_packet)); - RTC_CHECK_LE(rtp_packet.payload_size(), - limits.max_payload_len - limits.last_packet_reduction_len); -} -} // namespace webrtc +/* + * Copyright (c) 2024 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 +#include + +#include "api/video/video_frame_type.h" +#include "modules/rtp_rtcp/source/rtp_format.h" +#include "modules/rtp_rtcp/source/rtp_format_vp9.h" +#include "modules/rtp_rtcp/source/rtp_packet_to_send.h" +#include "rtc_base/checks.h" +#include "test/fuzzers/fuzz_data_helper.h" + +namespace webrtc { +void FuzzOneInput(const uint8_t* data, size_t size) { + test::FuzzDataHelper fuzz_input(rtc::MakeArrayView(data, size)); + + RtpPacketizer::PayloadSizeLimits limits; + limits.max_payload_len = 1200; + // Read uint8_t to be sure reduction_lens are much smaller than + // max_payload_len and thus limits structure is valid. + limits.first_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); + limits.last_packet_reduction_len = fuzz_input.ReadOrDefaultValue(0); + limits.single_packet_reduction_len = + fuzz_input.ReadOrDefaultValue(0); + + RTPVideoHeaderVP9 hdr_info; + hdr_info.InitRTPVideoHeaderVP9(); + uint16_t picture_id = fuzz_input.ReadOrDefaultValue(0); + hdr_info.picture_id = + picture_id >= 0x8000 ? kNoPictureId : picture_id & 0x7fff; + + // Main function under test: RtpPacketizerVp9's constructor. + RtpPacketizerVp9 packetizer(fuzz_input.ReadByteArray(fuzz_input.BytesLeft()), + limits, hdr_info); + + size_t num_packets = packetizer.NumPackets(); + if (num_packets == 0) { + return; + } + // When packetization was successful, validate NextPacket function too. + // While at it, check that packets respect the payload size limits. + RtpPacketToSend rtp_packet(nullptr); + // Single packet. + if (num_packets == 1) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.single_packet_reduction_len); + return; + } + // First packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.first_packet_reduction_len); + // Middle packets. + for (size_t i = 1; i < num_packets - 1; ++i) { + RTC_CHECK(packetizer.NextPacket(&rtp_packet)) + << "Failed to get packet#" << i; + RTC_CHECK_LE(rtp_packet.payload_size(), limits.max_payload_len) + << "Packet #" << i << " exceeds it's limit"; + } + // Last packet. + RTC_CHECK(packetizer.NextPacket(&rtp_packet)); + RTC_CHECK_LE(rtp_packet.payload_size(), + limits.max_payload_len - limits.last_packet_reduction_len); +} +} // namespace webrtc From 59f3b35013a29f8c73a46fa6fd06aadc96aad892 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Tue, 30 Jan 2024 07:39:42 +0000 Subject: [PATCH 038/170] Take out Fuchsia-only SDES-enabling parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This does not remove all traces of SDES - we still need to delete the cricket::CryptoParams struct and all code that uses it. Bug: webrtc:11066, chromium:804275 Change-Id: I811c8d40da7f4af714d53376f24cd53332a15945 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336780 Reviewed-by: Henrik Boström Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41634} --- api/peer_connection_interface.h | 9 - pc/peer_connection.cc | 16 +- pc/peer_connection_crypto_unittest.cc | 249 -------------------------- pc/peer_connection_integrationtest.cc | 20 --- pc/sdp_offer_answer.cc | 3 - 5 files changed, 1 insertion(+), 296 deletions(-) diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h index 3c225eb28a..7699f33438 100644 --- a/api/peer_connection_interface.h +++ b/api/peer_connection_interface.h @@ -451,15 +451,6 @@ class RTC_EXPORT PeerConnectionInterface : public webrtc::RefCountInterface { // when switching from a static scene to one with motion. absl::optional screencast_min_bitrate; -#if defined(WEBRTC_FUCHSIA) - // TODO(bugs.webrtc.org/11066): Remove entirely once Fuchsia does not use. - // TODO(bugs.webrtc.org/9891) - Move to crypto_options - // Can be used to disable DTLS-SRTP. This should never be done, but can be - // useful for testing purposes, for example in setting up a loopback call - // with a single PeerConnection. - absl::optional enable_dtls_srtp; -#endif - ///////////////////////////////////////////////// // The below fields are not part of the standard. ///////////////////////////////////////////////// diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index dc784771f8..3ab2c52130 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -348,15 +348,7 @@ bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration, return false; // Enable DTLS by default if we have an identity store or a certificate. - bool default_enabled = - (dependencies.cert_generator || !configuration.certificates.empty()); - -#if defined(WEBRTC_FUCHSIA) - // The `configuration` can override the default value. - return configuration.enable_dtls_srtp.value_or(default_enabled); -#else - return default_enabled; -#endif + return (dependencies.cert_generator || !configuration.certificates.empty()); } // Calls `ParseIceServersOrError` to extract ice server information from the @@ -416,9 +408,6 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( int max_ipv6_networks; bool disable_link_local_networks; absl::optional screencast_min_bitrate; -#if defined(WEBRTC_FUCHSIA) - absl::optional enable_dtls_srtp; -#endif TcpCandidatePolicy tcp_candidate_policy; CandidateNetworkPolicy candidate_network_policy; int audio_jitter_buffer_max_packets; @@ -483,9 +472,6 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( max_ipv6_networks == o.max_ipv6_networks && disable_link_local_networks == o.disable_link_local_networks && screencast_min_bitrate == o.screencast_min_bitrate && -#if defined(WEBRTC_FUCHSIA) - enable_dtls_srtp == o.enable_dtls_srtp && -#endif ice_candidate_pool_size == o.ice_candidate_pool_size && prune_turn_ports == o.prune_turn_ports && turn_port_prune_policy == o.turn_port_prune_policy && diff --git a/pc/peer_connection_crypto_unittest.cc b/pc/peer_connection_crypto_unittest.cc index 3b3f502e1f..4274e88b07 100644 --- a/pc/peer_connection_crypto_unittest.cc +++ b/pc/peer_connection_crypto_unittest.cc @@ -258,233 +258,6 @@ TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsEnabled) { answer->description())); } -#if defined(WEBRTC_FUCHSIA) -// When DTLS is disabled, the SDP offer/answer should include SDES cryptos and -// should not have a DTLS fingerprint. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsDisabled) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), - offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsDisabled) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOffer()); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), - answer->description())); -} - -// When encryption is disabled, the SDP offer/answer should have neither a DTLS -// fingerprint nor any SDES crypto options. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenEncryptionDisabled) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), - offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenEncryptionDisabled) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOffer()); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), - answer->description())); -} - -// CryptoOptions has been promoted to RTCConfiguration. As such if it is ever -// set in the configuration it should overrite the settings set in the factory. -TEST_P(PeerConnectionCryptoTest, RTCConfigurationCryptoOptionOverridesFactory) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - CryptoOptions crypto_options; - crypto_options.srtp.enable_gcm_crypto_suites = false; - config.crypto_options = crypto_options; - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - // This should exist if GCM is enabled see CorrectCryptoInOfferWithSdesAndGcm - EXPECT_FALSE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); -} - -// When DTLS is disabled and GCM cipher suites are enabled, the SDP offer/answer -// should have the correct ciphers in the SDES crypto options. -// With GCM cipher suites enabled, there will be 3 cryptos in the offer and 1 -// in the answer. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWithSdesAndGcm) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWithSdesAndGcm) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - for (cricket::ContentInfo& content : offer->description()->contents()) { - auto cryptos = content.media_description()->cryptos(); - cryptos.erase(cryptos.begin()); // Assumes that non-GCM is the default. - content.media_description()->set_cryptos(cryptos); - } - - callee->SetRemoteDescription(std::move(offer)); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(1), answer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CanSetSdesGcmRemoteOfferAndLocalAnswer) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - ASSERT_TRUE(callee->SetLocalDescription(std::move(answer))); -} - -// The following group tests that two PeerConnections can successfully exchange -// an offer/answer when DTLS is off and that they will refuse any offer/answer -// applied locally/remotely if it does not include SDES cryptos. -TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOfferAndSetAsLocal(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswerAndSetAsLocal(); - ASSERT_TRUE(answer); - ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetLocalOfferWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - SdpContentsForEach(RemoveSdesCryptos(), offer->description()); - - EXPECT_FALSE(caller->SetLocalDescription(std::move(offer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetRemoteOfferWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - SdpContentsForEach(RemoveSdesCryptos(), offer->description()); - - EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetLocalAnswerWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); - auto answer = callee->CreateAnswer(); - SdpContentsForEach(RemoveSdesCryptos(), answer->description()); - - EXPECT_FALSE(callee->SetLocalDescription(std::move(answer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetRemoteAnswerWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); - auto answer = callee->CreateAnswerAndSetAsLocal(); - SdpContentsForEach(RemoveSdesCryptos(), answer->description()); - - EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); -} -#endif - // The following group tests that two PeerConnections can successfully exchange // an offer/answer when DTLS is on and that they will refuse any offer/answer // applied locally/remotely if it does not include a DTLS fingerprint. @@ -545,28 +318,6 @@ TEST_P(PeerConnectionCryptoTest, EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); } -#if defined(WEBRTC_FUCHSIA) -// Test that an offer/answer can be exchanged when encryption is disabled. -TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenNoEncryption) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOfferAndSetAsLocal(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswerAndSetAsLocal(); - ASSERT_TRUE(answer); - ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); -} -#endif - // Tests that a DTLS call can be established when the certificate is specified // in the PeerConnection config and no certificate generator is specified. TEST_P(PeerConnectionCryptoTest, diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc index 23c8b1690f..24ca52f619 100644 --- a/pc/peer_connection_integrationtest.cc +++ b/pc/peer_connection_integrationtest.cc @@ -275,26 +275,6 @@ TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) { ASSERT_TRUE(ExpectNewFrames(media_expectations)); } -#if defined(WEBRTC_FUCHSIA) -// Uses SDES instead of DTLS for key agreement. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) { - PeerConnectionInterface::RTCConfiguration sdes_config; - sdes_config.enable_dtls_srtp.emplace(false); - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config)); - ConnectFakeSignaling(); - - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} -#endif - // Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions` // option to offer encrypted versions of all header extensions alongside the // unencrypted versions. diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 67c8d10241..19cd9ba45c 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -285,9 +285,6 @@ RTCError VerifyCrypto(const SessionDescription* desc, if (content_info.rejected) { continue; } -#if !defined(WEBRTC_FUCHSIA) - RTC_CHECK(dtls_enabled) << "SDES protocol is only allowed in Fuchsia"; -#endif const std::string& mid = content_info.name; auto it = bundle_groups_by_mid.find(mid); const cricket::ContentGroup* bundle = From 056782c4b5c682ed8bf8881a31430717ab719122 Mon Sep 17 00:00:00 2001 From: Per K Date: Tue, 30 Jan 2024 12:32:05 +0100 Subject: [PATCH 039/170] Implement Socket::RecvFrom(ReceiveBuffer& buffer) in PhysicalSocketServer And RTC_CHECK(NOTREACHED) Socket::RecvFrom(void* pv..) This cl also change usage of PhysicalSocket to use PhysicalSocket::RecvFrom(ReceivedBuffer&) in Nat and tests. Note that Socket::RecvFrom(ReceiveBuffer& buffer) is already used in AsyncUdpSocket.( https://webrtc-review.googlesource.com/c/src/+/332200) AsyncTCPSocket uses Socket::Recv(). Therefore, there should be no production usage left of Socket::RecvFrom(void* pv..) in open source webrtc. Follow up cls should remove usage of Socket::RecvFrom(void* pv..) in implementations of rtc:AsyncSocketAdapter such as FirewallSocketAdapter. Change-Id: I597dc32b14be98e954a3dc419723f043e8a7e19e Bug: webrtc:15368 Change-Id: I597dc32b14be98e954a3dc419723f043e8a7e19e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/332341 Reviewed-by: Harald Alvestrand Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/main@{#41635} --- rtc_base/BUILD.gn | 4 +++ rtc_base/nat_server.cc | 16 +++++---- rtc_base/nat_socket_factory.cc | 58 +++++++++++------------------- rtc_base/nat_socket_factory.h | 6 ++-- rtc_base/nat_unittest.cc | 10 +++--- rtc_base/physical_socket_server.cc | 25 +++++++++++++ rtc_base/physical_socket_server.h | 2 ++ rtc_base/socket.h | 11 ++++-- rtc_base/socket_unittest.cc | 14 ++++---- 9 files changed, 86 insertions(+), 60 deletions(-) diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index ac30d8708b..8d108bbdec 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -1106,6 +1106,7 @@ rtc_library("socket") { ] deps = [ ":buffer", + ":checks", ":macromagic", ":socket_address", "../api/units:timestamp", @@ -1718,6 +1719,7 @@ rtc_library("rtc_base_tests_utils") { ":async_socket", ":async_tcp_socket", ":async_udp_socket", + ":buffer", ":byte_buffer", ":checks", ":ip_address", @@ -1737,6 +1739,7 @@ rtc_library("rtc_base_tests_utils") { ":stringutils", ":threading", ":timeutils", + "../api:array_view", "../api:make_ref_counted", "../api:refcountedbase", "../api:scoped_refptr", @@ -1852,6 +1855,7 @@ if (rtc_include_tests) { ":threading", ":timeutils", "../api/units:time_delta", + "../api/units:timestamp", "../system_wrappers", "../test:field_trial", "../test:fileutils", diff --git a/rtc_base/nat_server.cc b/rtc_base/nat_server.cc index c274cedf18..f21d404bd3 100644 --- a/rtc_base/nat_server.cc +++ b/rtc_base/nat_server.cc @@ -11,8 +11,10 @@ #include "rtc_base/nat_server.h" #include +#include #include +#include "api/array_view.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/nat_socket_factory.h" @@ -97,8 +99,9 @@ class NATProxyServerSocket : public AsyncProxyServerSocket { } SocketAddress dest_addr; - size_t address_length = UnpackAddressFromNAT(data, *len, &dest_addr); - + size_t address_length = UnpackAddressFromNAT( + MakeArrayView(reinterpret_cast(data), *len), + &dest_addr); *len -= address_length; if (*len > 0) { memmove(data, data + address_length, *len); @@ -171,15 +174,12 @@ NATServer::~NATServer() { void NATServer::OnInternalUDPPacket(AsyncPacketSocket* socket, const rtc::ReceivedPacket& packet) { RTC_DCHECK(internal_socket_thread_.IsCurrent()); - const char* buf = reinterpret_cast(packet.payload().data()); - size_t size = packet.payload().size(); - const SocketAddress& addr = packet.source_address(); // Read the intended destination from the wire. SocketAddress dest_addr; - size_t length = UnpackAddressFromNAT(buf, size, &dest_addr); + size_t length = UnpackAddressFromNAT(packet.payload(), &dest_addr); // Find the translation for these addresses (allocating one if necessary). - SocketAddressPair route(addr, dest_addr); + SocketAddressPair route(packet.source_address(), dest_addr); InternalMap::iterator iter = int_map_->find(route); if (iter == int_map_->end()) { Translate(route); @@ -192,6 +192,8 @@ void NATServer::OnInternalUDPPacket(AsyncPacketSocket* socket, // Send the packet to its intended destination. rtc::PacketOptions options; + const char* buf = reinterpret_cast(packet.payload().data()); + size_t size = packet.payload().size(); iter->second->socket->SendTo(buf + length, size - length, dest_addr, options); } diff --git a/rtc_base/nat_socket_factory.cc b/rtc_base/nat_socket_factory.cc index 83ec2bc327..66e4f84cd7 100644 --- a/rtc_base/nat_socket_factory.cc +++ b/rtc_base/nat_socket_factory.cc @@ -10,7 +10,9 @@ #include "rtc_base/nat_socket_factory.h" +#include "api/units/timestamp.h" #include "rtc_base/arraysize.h" +#include "rtc_base/buffer.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/nat_server.h" @@ -47,21 +49,20 @@ size_t PackAddressForNAT(char* buf, // Decodes the remote address from a packet that has been encoded with the nat's // quasi-STUN format. Returns the length of the address (i.e., the offset into // data where the original packet starts). -size_t UnpackAddressFromNAT(const char* buf, - size_t buf_size, +size_t UnpackAddressFromNAT(rtc::ArrayView buf, SocketAddress* remote_addr) { - RTC_DCHECK(buf_size >= 8); - RTC_DCHECK(buf[0] == 0); + RTC_CHECK(buf.size() >= 8); + RTC_DCHECK(buf.data()[0] == 0); int family = buf[1]; uint16_t port = - NetworkToHost16(*(reinterpret_cast(&buf[2]))); + NetworkToHost16(*(reinterpret_cast(&buf.data()[2]))); if (family == AF_INET) { - const in_addr* v4addr = reinterpret_cast(&buf[4]); + const in_addr* v4addr = reinterpret_cast(&buf.data()[4]); *remote_addr = SocketAddress(IPAddress(*v4addr), port); return kNATEncodedIPv4AddressSize; } else if (family == AF_INET6) { - RTC_DCHECK(buf_size >= 20); - const in6_addr* v6addr = reinterpret_cast(&buf[4]); + RTC_DCHECK(buf.size() >= 20); + const in6_addr* v6addr = reinterpret_cast(&buf.data()[4]); *remote_addr = SocketAddress(IPAddress(*v6addr), port); return kNATEncodedIPv6AddressSize; } @@ -76,14 +77,9 @@ class NATSocket : public Socket, public sigslot::has_slots<> { family_(family), type_(type), connected_(false), - socket_(nullptr), - buf_(nullptr), - size_(0) {} + socket_(nullptr) {} - ~NATSocket() override { - delete socket_; - delete[] buf_; - } + ~NATSocket() override { delete socket_; } SocketAddress GetLocalAddress() const override { return (socket_) ? socket_->GetLocalAddress() : SocketAddress(); @@ -165,23 +161,21 @@ class NATSocket : public Socket, public sigslot::has_slots<> { } // Make sure we have enough room to read the requested amount plus the // largest possible header address. - SocketAddress remote_addr; - Grow(size + kNATEncodedIPv6AddressSize); + buf_.EnsureCapacity(size + kNATEncodedIPv6AddressSize); // Read the packet from the socket. - int result = socket_->RecvFrom(buf_, size_, &remote_addr, timestamp); + Socket::ReceiveBuffer receive_buffer(buf_); + int result = socket_->RecvFrom(receive_buffer); if (result >= 0) { - RTC_DCHECK(remote_addr == server_addr_); - - // TODO: we need better framing so we know how many bytes we can - // return before we need to read the next address. For UDP, this will be - // fine as long as the reader always reads everything in the packet. - RTC_DCHECK((size_t)result < size_); + RTC_DCHECK(receive_buffer.source_address == server_addr_); + *timestamp = + receive_buffer.arrival_time.value_or(webrtc::Timestamp::Micros(0)) + .us(); // Decode the wire packet into the actual results. SocketAddress real_remote_addr; - size_t addrlength = UnpackAddressFromNAT(buf_, result, &real_remote_addr); - memcpy(data, buf_ + addrlength, result - addrlength); + size_t addrlength = UnpackAddressFromNAT(buf_, &real_remote_addr); + memcpy(data, buf_.data() + addrlength, result - addrlength); // Make sure this packet should be delivered before returning it. if (!connected_ || (real_remote_addr == remote_addr_)) { @@ -285,15 +279,6 @@ class NATSocket : public Socket, public sigslot::has_slots<> { return result; } - // Makes sure the buffer is at least the given size. - void Grow(size_t new_size) { - if (size_ < new_size) { - delete[] buf_; - size_ = new_size; - buf_ = new char[size_]; - } - } - // Sends the destination address to the server to tell it to connect. void SendConnectRequest() { char buf[kNATEncodedIPv6AddressSize]; @@ -323,8 +308,7 @@ class NATSocket : public Socket, public sigslot::has_slots<> { Socket* socket_; // Need to hold error in case it occurs before the socket is created. int error_ = 0; - char* buf_; - size_t size_; + Buffer buf_; }; // NATSocketFactory diff --git a/rtc_base/nat_socket_factory.h b/rtc_base/nat_socket_factory.h index f803496b05..5adcaa5dfd 100644 --- a/rtc_base/nat_socket_factory.h +++ b/rtc_base/nat_socket_factory.h @@ -13,10 +13,13 @@ #include +#include #include #include #include +#include "api/array_view.h" +#include "rtc_base/buffer.h" #include "rtc_base/nat_server.h" #include "rtc_base/nat_types.h" #include "rtc_base/socket.h" @@ -172,8 +175,7 @@ class NATSocketServer : public SocketServer, public NATInternalSocketFactory { size_t PackAddressForNAT(char* buf, size_t buf_size, const SocketAddress& remote_addr); -size_t UnpackAddressFromNAT(const char* buf, - size_t buf_size, +size_t UnpackAddressFromNAT(rtc::ArrayView buf, SocketAddress* remote_addr); } // namespace rtc diff --git a/rtc_base/nat_unittest.cc b/rtc_base/nat_unittest.cc index 742e0d6ee7..978a30aefe 100644 --- a/rtc_base/nat_unittest.cc +++ b/rtc_base/nat_unittest.cc @@ -233,12 +233,12 @@ bool TestConnectivity(const SocketAddress& src, const IPAddress& dst) { const char* buf = "hello other socket"; size_t len = strlen(buf); int sent = client->SendTo(buf, len, server->GetLocalAddress()); - SocketAddress addr; - const size_t kRecvBufSize = 64; - char recvbuf[kRecvBufSize]; + Thread::Current()->SleepMs(100); - int received = server->RecvFrom(recvbuf, kRecvBufSize, &addr, nullptr); - return received == sent && ::memcmp(buf, recvbuf, len) == 0; + rtc::Buffer payload; + Socket::ReceiveBuffer receive_buffer(payload); + int received = server->RecvFrom(receive_buffer); + return received == sent && ::memcmp(buf, payload.data(), len) == 0; } void TestPhysicalInternal(const SocketAddress& int_addr) { diff --git a/rtc_base/physical_socket_server.cc b/rtc_base/physical_socket_server.cc index b0af1c20ce..c3bc1814a1 100644 --- a/rtc_base/physical_socket_server.cc +++ b/rtc_base/physical_socket_server.cc @@ -432,6 +432,31 @@ int PhysicalSocket::RecvFrom(void* buffer, SocketAddress* out_addr, int64_t* timestamp) { int received = DoReadFromSocket(buffer, length, out_addr, timestamp); + + UpdateLastError(); + int error = GetError(); + bool success = (received >= 0) || IsBlockingError(error); + if (udp_ || success) { + EnableEvents(DE_READ); + } + if (!success) { + RTC_LOG_F(LS_VERBOSE) << "Error = " << error; + } + return received; +} + +int PhysicalSocket::RecvFrom(ReceiveBuffer& buffer) { + int64_t timestamp = -1; + static constexpr int BUF_SIZE = 64 * 1024; + buffer.payload.EnsureCapacity(BUF_SIZE); + + int received = + DoReadFromSocket(buffer.payload.data(), buffer.payload.capacity(), + &buffer.source_address, ×tamp); + buffer.payload.SetSize(received > 0 ? received : 0); + if (received > 0 && timestamp != -1) { + buffer.arrival_time = webrtc::Timestamp::Micros(timestamp); + } UpdateLastError(); int error = GetError(); bool success = (received >= 0) || IsBlockingError(error); diff --git a/rtc_base/physical_socket_server.h b/rtc_base/physical_socket_server.h index 584f42a188..2af563a3ca 100644 --- a/rtc_base/physical_socket_server.h +++ b/rtc_base/physical_socket_server.h @@ -188,10 +188,12 @@ class PhysicalSocket : public Socket, public sigslot::has_slots<> { const SocketAddress& addr) override; int Recv(void* buffer, size_t length, int64_t* timestamp) override; + // TODO(webrtc:15368): Deprecate and remove. int RecvFrom(void* buffer, size_t length, SocketAddress* out_addr, int64_t* timestamp) override; + int RecvFrom(ReceiveBuffer& buffer) override; int Listen(int backlog) override; Socket* Accept(SocketAddress* out_addr) override; diff --git a/rtc_base/socket.h b/rtc_base/socket.h index fac75aca94..98e468e754 100644 --- a/rtc_base/socket.h +++ b/rtc_base/socket.h @@ -14,6 +14,7 @@ #include #include "absl/types/optional.h" +#include "rtc_base/checks.h" #if defined(WEBRTC_POSIX) #include @@ -86,11 +87,11 @@ inline bool IsBlockingError(int e) { class RTC_EXPORT Socket { public: struct ReceiveBuffer { - ReceiveBuffer(rtc::Buffer& payload) : payload(payload) {} + ReceiveBuffer(Buffer& payload) : payload(payload) {} absl::optional arrival_time; SocketAddress source_address; - rtc::Buffer& payload; + Buffer& payload; }; virtual ~Socket() {} @@ -111,10 +112,14 @@ class RTC_EXPORT Socket { virtual int SendTo(const void* pv, size_t cb, const SocketAddress& addr) = 0; // `timestamp` is in units of microseconds. virtual int Recv(void* pv, size_t cb, int64_t* timestamp) = 0; + // TODO(webrtc:15368): Deprecate and remove. virtual int RecvFrom(void* pv, size_t cb, SocketAddress* paddr, - int64_t* timestamp) = 0; + int64_t* timestamp) { + // Not implemented. Use RecvFrom(ReceiveBuffer& buffer). + RTC_CHECK_NOTREACHED(); + } // Intended to replace RecvFrom(void* ...). // Default implementation calls RecvFrom(void* ...) with 64Kbyte buffer. // Returns number of bytes received or a negative value on error. diff --git a/rtc_base/socket_unittest.cc b/rtc_base/socket_unittest.cc index f5ef2a33fc..5314128d0a 100644 --- a/rtc_base/socket_unittest.cc +++ b/rtc_base/socket_unittest.cc @@ -20,6 +20,7 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" +#include "api/units/timestamp.h" #include "rtc_base/arraysize.h" #include "rtc_base/async_packet_socket.h" #include "rtc_base/async_udp_socket.h" @@ -1092,11 +1093,11 @@ void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) { int64_t send_time_1 = TimeMicros(); socket->SendTo("foo", 3, address); - int64_t recv_timestamp_1; // Wait until data is available. EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout); - char buffer[3]; - ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_1), 0); + rtc::Buffer buffer; + Socket::ReceiveBuffer receive_buffer_1(buffer); + ASSERT_GT(socket->RecvFrom(receive_buffer_1), 0); const int64_t kTimeBetweenPacketsMs = 100; Thread::SleepMs(kTimeBetweenPacketsMs); @@ -1105,11 +1106,12 @@ void SocketTest::SocketRecvTimestamp(const IPAddress& loopback) { socket->SendTo("bar", 3, address); // Wait until data is available. EXPECT_TRUE_WAIT(sink.Check(socket.get(), SSE_READ), kTimeout); - int64_t recv_timestamp_2; - ASSERT_GT(socket->RecvFrom(buffer, 3, nullptr, &recv_timestamp_2), 0); + Socket::ReceiveBuffer receive_buffer_2(buffer); + ASSERT_GT(socket->RecvFrom(receive_buffer_2), 0); int64_t system_time_diff = send_time_2 - send_time_1; - int64_t recv_timestamp_diff = recv_timestamp_2 - recv_timestamp_1; + int64_t recv_timestamp_diff = + receive_buffer_2.arrival_time->us() - receive_buffer_1.arrival_time->us(); // Compare against the system time at the point of sending, because // SleepMs may not sleep for exactly the requested time. EXPECT_NEAR(system_time_diff, recv_timestamp_diff, 10000); From cc83e32cdb938c519f9c14aca6061f583caa8e10 Mon Sep 17 00:00:00 2001 From: Qiu Jianlin Date: Wed, 31 Jan 2024 11:13:07 +0800 Subject: [PATCH 040/170] Fix H.265 bitstream parser incorrect PPS reference. H.265 bitstream parser currently always assume pps id to be 0 when calculating the last slice QP. This assumption is incorrect. Bug: webrtc:13485 Change-Id: I06918df035e8e4a8e68eb3002a49b824ffd5f516 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337080 Commit-Queue: Jianlin Qiu Reviewed-by: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41636} --- common_video/h265/h265_bitstream_parser.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common_video/h265/h265_bitstream_parser.cc b/common_video/h265/h265_bitstream_parser.cc index f270f228c1..9247d5d272 100644 --- a/common_video/h265/h265_bitstream_parser.cc +++ b/common_video/h265/h265_bitstream_parser.cc @@ -531,8 +531,7 @@ absl::optional H265BitstreamParser::GetLastSliceQp() const { if (!last_slice_qp_delta_ || !last_slice_pps_id_) { return absl::nullopt; } - uint32_t pps_id = 0; - const H265PpsParser::PpsState* pps = GetPPS(pps_id); + const H265PpsParser::PpsState* pps = GetPPS(last_slice_pps_id_.value()); if (!pps) return absl::nullopt; const int parsed_qp = 26 + pps->init_qp_minus26 + *last_slice_qp_delta_; From c6675ed967b6ee72fa8dc98dce34bf949aec372f Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Wed, 31 Jan 2024 08:52:13 +0100 Subject: [PATCH 041/170] Test new tree. This CL should not land since the tree is closed. [1] - https://ci.chromium.org/ui/labs/tree-status/webrtc No-Try: True Bug: None Change-Id: I398864f5ba7e684e2351681390a211a73e6ed466 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337140 Auto-Submit: Mirko Bonadei Reviewed-by: Christoffer Dewerin Reviewed-by: Christoffer Dewerin Commit-Queue: Mirko Bonadei Owners-Override: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41637} --- whitespace.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/whitespace.txt b/whitespace.txt index e4ba9abb0d..506c93ba09 100644 --- a/whitespace.txt +++ b/whitespace.txt @@ -1,7 +1,6 @@ You can modify this file to create no-op changelists. Try to write something funny. And please don't add trailing whitespace. - Once upon a time there was a white elephant in Stockholm. Why did the elephant get kicked out of the Swedish Parliament? Because it kept making trunk calls! From 365cf14407775ba2dc56322204a53f7ee4e9ec8e Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Wed, 31 Jan 2024 08:35:44 +0000 Subject: [PATCH 042/170] Revert "Test new tree." This reverts commit c6675ed967b6ee72fa8dc98dce34bf949aec372f. Reason for revert: Testing tree close Original change's description: > Test new tree. > > This CL should not land since the tree is closed. > > [1] - https://ci.chromium.org/ui/labs/tree-status/webrtc > > No-Try: True > Bug: None > Change-Id: I398864f5ba7e684e2351681390a211a73e6ed466 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337140 > Auto-Submit: Mirko Bonadei > Reviewed-by: Christoffer Dewerin > Reviewed-by: Christoffer Dewerin > Commit-Queue: Mirko Bonadei > Owners-Override: Mirko Bonadei > Cr-Commit-Position: refs/heads/main@{#41637} Bug: None Change-Id: Iac4a12901263807ca3f57bcffa58d26f956efc9b No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337121 Owners-Override: Mirko Bonadei Bot-Commit: rubber-stamper@appspot.gserviceaccount.com Reviewed-by: Christoffer Dewerin Commit-Queue: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41638} --- whitespace.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/whitespace.txt b/whitespace.txt index 506c93ba09..e4ba9abb0d 100644 --- a/whitespace.txt +++ b/whitespace.txt @@ -1,6 +1,7 @@ You can modify this file to create no-op changelists. Try to write something funny. And please don't add trailing whitespace. + Once upon a time there was a white elephant in Stockholm. Why did the elephant get kicked out of the Swedish Parliament? Because it kept making trunk calls! From 958c9ac546f33716d097b5092515dcac705151d3 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Mon, 29 Jan 2024 15:12:47 +0100 Subject: [PATCH 043/170] Allow VideoCaptureModulePipeWire to be shared with more consumers This allows to share an instance of VideoCaptureModulePipeWire which is what browsers usually do when the same camera is being shared with more than one consumer. This matches V4L2 implementation. Bug: webrtc:15211 Change-Id: I2ae466739c2649029e76a29e6f16aad1014e9d42 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/306964 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Jan Grulich Cr-Commit-Position: refs/heads/main@{#41639} --- .../video_capture/linux/video_capture_pipewire.cc | 15 ++++++++++++++- .../video_capture/linux/video_capture_pipewire.h | 1 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc index 9d47e3ddbf..fb813e331f 100644 --- a/modules/video_capture/linux/video_capture_pipewire.cc +++ b/modules/video_capture/linux/video_capture_pipewire.cc @@ -48,7 +48,10 @@ VideoType VideoCaptureModulePipeWire::PipeWireRawFormatToVideoType( VideoCaptureModulePipeWire::VideoCaptureModulePipeWire( VideoCaptureOptions* options) - : VideoCaptureImpl(), session_(options->pipewire_session()) {} + : VideoCaptureImpl(), + session_(options->pipewire_session()), + initialized_(false), + started_(false) {} VideoCaptureModulePipeWire::~VideoCaptureModulePipeWire() { RTC_DCHECK_RUN_ON(&api_checker_); @@ -121,6 +124,14 @@ int32_t VideoCaptureModulePipeWire::StartCapture( RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); RTC_DCHECK_RUN_ON(&api_checker_); + if (initialized_) { + if (capability == _requestedCapability) { + return 0; + } else { + StopCapture(); + } + } + uint8_t buffer[1024] = {}; RTC_LOG(LS_VERBOSE) << "Creating new PipeWire stream for node " << node_id_; @@ -171,6 +182,8 @@ int32_t VideoCaptureModulePipeWire::StartCapture( } _requestedCapability = capability; + initialized_ = true; + return 0; } diff --git a/modules/video_capture/linux/video_capture_pipewire.h b/modules/video_capture/linux/video_capture_pipewire.h index 620ee520ca..5d6794ed65 100644 --- a/modules/video_capture/linux/video_capture_pipewire.h +++ b/modules/video_capture/linux/video_capture_pipewire.h @@ -50,6 +50,7 @@ class VideoCaptureModulePipeWire : public VideoCaptureImpl { int node_id_ RTC_GUARDED_BY(capture_checker_); VideoCaptureCapability configured_capability_ RTC_GUARDED_BY(pipewire_checker_); + bool initialized_ RTC_GUARDED_BY(capture_checker_); bool started_ RTC_GUARDED_BY(api_lock_); struct pw_stream* stream_ RTC_GUARDED_BY(pipewire_checker_) = nullptr; From c4dd03dfcbe5577f47e1fa9d735be1ecb170f98e Mon Sep 17 00:00:00 2001 From: Tommi Date: Wed, 31 Jan 2024 10:44:27 +0100 Subject: [PATCH 044/170] Remove kUnknown as a possible value for IceCandidateType. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subsequently also tighten IceCandidateType error checking. The Candidate type in `cricket` should be using something similar (currently using a string for the type), so I'm making sure that types that we have already, align with where we'd like to be overall. Possibly we can move IceCandidateType to where Candidate is defined. Bug: none Change-Id: Iffeba7268f2a393e18a5f33249efae46e6e08252 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335980 Reviewed-by: Björn Terelius Commit-Queue: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41640} --- .../encoder/rtc_event_log_encoder_legacy.cc | 8 +- .../rtc_event_log_encoder_new_format.cc | 2 - .../rtc_event_ice_candidate_pair_config.cc | 8 +- .../rtc_event_ice_candidate_pair_config.h | 4 +- logging/rtc_event_log/ice_logger.cc | 3 +- logging/rtc_event_log/rtc_event_log_parser.cc | 74 +++++++++++++------ .../rtc_event_log_unittest_helper.cc | 4 +- p2p/base/connection.cc | 10 +-- rtc_tools/rtc_event_log_to_text/converter.cc | 3 +- .../rtc_event_log_visualizer/analyzer.cc | 30 ++++---- 10 files changed, 84 insertions(+), 62 deletions(-) diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc index 2c1444af07..ba1e597ad8 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc @@ -131,8 +131,6 @@ ConvertIceCandidatePairConfigType(IceCandidatePairConfigType type) { rtclog::IceCandidatePairConfig::IceCandidateType ConvertIceCandidateType( IceCandidateType type) { switch (type) { - case IceCandidateType::kUnknown: - return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; case IceCandidateType::kLocal: return rtclog::IceCandidatePairConfig::LOCAL; case IceCandidateType::kStun: @@ -141,11 +139,11 @@ rtclog::IceCandidatePairConfig::IceCandidateType ConvertIceCandidateType( return rtclog::IceCandidatePairConfig::PRFLX; case IceCandidateType::kRelay: return rtclog::IceCandidatePairConfig::RELAY; - case IceCandidateType::kNumValues: + default: + // TODO(tommi): Remove the default handler when kNumValues is gone. RTC_DCHECK_NOTREACHED(); + return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; } - RTC_DCHECK_NOTREACHED(); - return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; } rtclog::IceCandidatePairConfig::Protocol ConvertIceCandidatePairProtocol( diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc index 01bd89718d..a07afbe48a 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc @@ -198,8 +198,6 @@ ConvertToProtoFormat(IceCandidatePairConfigType type) { rtclog2::IceCandidatePairConfig::IceCandidateType ConvertToProtoFormat( IceCandidateType type) { switch (type) { - case IceCandidateType::kUnknown: - return rtclog2::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; case IceCandidateType::kLocal: return rtclog2::IceCandidatePairConfig::LOCAL; case IceCandidateType::kStun: diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc index eb458c4640..59d76e7a03 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.cc @@ -14,12 +14,14 @@ namespace webrtc { -IceCandidatePairDescription::IceCandidatePairDescription() { - local_candidate_type = IceCandidateType::kUnknown; +IceCandidatePairDescription::IceCandidatePairDescription( + IceCandidateType local_candidate_type, + IceCandidateType remote_candidate_type) + : local_candidate_type(local_candidate_type), + remote_candidate_type(remote_candidate_type) { local_relay_protocol = IceCandidatePairProtocol::kUnknown; local_network_type = IceCandidateNetworkType::kUnknown; local_address_family = IceCandidatePairAddressFamily::kUnknown; - remote_candidate_type = IceCandidateType::kUnknown; remote_address_family = IceCandidatePairAddressFamily::kUnknown; candidate_pair_protocol = IceCandidatePairProtocol::kUnknown; } diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h index e72d999cff..a44f530e77 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h @@ -35,7 +35,6 @@ enum class IceCandidatePairConfigType { // TODO(qingsi): Change the names of candidate types to "host", "srflx", "prflx" // and "relay" after the naming is spec-compliant in the signaling part enum class IceCandidateType { - kUnknown, kLocal, kStun, kPrflx, @@ -88,7 +87,8 @@ struct LoggedIceCandidatePairConfig { class IceCandidatePairDescription { public: - IceCandidatePairDescription(); + IceCandidatePairDescription(IceCandidateType local_candidate_type, + IceCandidateType remote_candidate_type); explicit IceCandidatePairDescription( const IceCandidatePairDescription& other); diff --git a/logging/rtc_event_log/ice_logger.cc b/logging/rtc_event_log/ice_logger.cc index 390deda953..daa7057439 100644 --- a/logging/rtc_event_log/ice_logger.cc +++ b/logging/rtc_event_log/ice_logger.cc @@ -26,7 +26,8 @@ void IceEventLog::LogCandidatePairConfig( if (event_log_ == nullptr) { return; } - candidate_pair_desc_by_id_[candidate_pair_id] = candidate_pair_desc; + + candidate_pair_desc_by_id_.emplace(candidate_pair_id, candidate_pair_desc); event_log_->Log(std::make_unique( type, candidate_pair_id, candidate_pair_desc)); } diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc index 37bb70a69b..c53b1dd59a 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/logging/rtc_event_log/rtc_event_log_parser.cc @@ -163,22 +163,29 @@ IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType( return IceCandidatePairConfigType::kAdded; } -IceCandidateType GetRuntimeIceCandidateType( - rtclog::IceCandidatePairConfig::IceCandidateType type) { - switch (type) { +// Converts a log type (proto based) to a matching `IceCandidateType` value +// and checks for validity of the log type (since the enums aren't a perfect +// match). +bool GetRuntimeIceCandidateType( + rtclog::IceCandidatePairConfig::IceCandidateType log_type, + IceCandidateType& parsed_type) { + switch (log_type) { case rtclog::IceCandidatePairConfig::LOCAL: - return IceCandidateType::kLocal; + parsed_type = IceCandidateType::kLocal; + break; case rtclog::IceCandidatePairConfig::STUN: - return IceCandidateType::kStun; + parsed_type = IceCandidateType::kStun; + break; case rtclog::IceCandidatePairConfig::PRFLX: - return IceCandidateType::kPrflx; + parsed_type = IceCandidateType::kPrflx; + break; case rtclog::IceCandidatePairConfig::RELAY: - return IceCandidateType::kRelay; - case rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE: - return IceCandidateType::kUnknown; + parsed_type = IceCandidateType::kRelay; + break; + default: + return false; } - RTC_DCHECK_NOTREACHED(); - return IceCandidateType::kUnknown; + return true; } IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol( @@ -813,11 +820,32 @@ IceCandidateType GetRuntimeIceCandidateType( return IceCandidateType::kPrflx; case rtclog2::IceCandidatePairConfig::RELAY: return IceCandidateType::kRelay; - case rtclog2::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE: - return IceCandidateType::kUnknown; + default: + RTC_DCHECK_NOTREACHED(); + return IceCandidateType::kLocal; } - RTC_DCHECK_NOTREACHED(); - return IceCandidateType::kUnknown; +} + +bool GetRuntimeIceCandidateType( + rtclog2::IceCandidatePairConfig::IceCandidateType log_type, + IceCandidateType& parsed_type) { + switch (log_type) { + case rtclog2::IceCandidatePairConfig::LOCAL: + parsed_type = IceCandidateType::kLocal; + break; + case rtclog2::IceCandidatePairConfig::STUN: + parsed_type = IceCandidateType::kStun; + break; + case rtclog2::IceCandidatePairConfig::PRFLX: + parsed_type = IceCandidateType::kPrflx; + break; + case rtclog2::IceCandidatePairConfig::RELAY: + parsed_type = IceCandidateType::kRelay; + break; + default: + return false; + } + return true; } IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol( @@ -2142,8 +2170,8 @@ ParsedRtcEventLog::GetIceCandidatePairConfig( RTC_PARSE_CHECK_OR_RETURN(config.has_candidate_pair_id()); res.candidate_pair_id = config.candidate_pair_id(); RTC_PARSE_CHECK_OR_RETURN(config.has_local_candidate_type()); - res.local_candidate_type = - GetRuntimeIceCandidateType(config.local_candidate_type()); + RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType( + config.local_candidate_type(), res.local_candidate_type)); RTC_PARSE_CHECK_OR_RETURN(config.has_local_relay_protocol()); res.local_relay_protocol = GetRuntimeIceCandidatePairProtocol(config.local_relay_protocol()); @@ -2154,8 +2182,8 @@ ParsedRtcEventLog::GetIceCandidatePairConfig( res.local_address_family = GetRuntimeIceCandidatePairAddressFamily(config.local_address_family()); RTC_PARSE_CHECK_OR_RETURN(config.has_remote_candidate_type()); - res.remote_candidate_type = - GetRuntimeIceCandidateType(config.remote_candidate_type()); + RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType( + config.remote_candidate_type(), res.remote_candidate_type)); RTC_PARSE_CHECK_OR_RETURN(config.has_remote_address_family()); res.remote_address_family = GetRuntimeIceCandidatePairAddressFamily(config.remote_address_family()); @@ -3498,8 +3526,8 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidatePairConfig( RTC_PARSE_CHECK_OR_RETURN(proto.has_candidate_pair_id()); ice_config.candidate_pair_id = proto.candidate_pair_id(); RTC_PARSE_CHECK_OR_RETURN(proto.has_local_candidate_type()); - ice_config.local_candidate_type = - GetRuntimeIceCandidateType(proto.local_candidate_type()); + RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType( + proto.local_candidate_type(), ice_config.local_candidate_type)); RTC_PARSE_CHECK_OR_RETURN(proto.has_local_relay_protocol()); ice_config.local_relay_protocol = GetRuntimeIceCandidatePairProtocol(proto.local_relay_protocol()); @@ -3510,8 +3538,8 @@ ParsedRtcEventLog::ParseStatus ParsedRtcEventLog::StoreIceCandidatePairConfig( ice_config.local_address_family = GetRuntimeIceCandidatePairAddressFamily(proto.local_address_family()); RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_candidate_type()); - ice_config.remote_candidate_type = - GetRuntimeIceCandidateType(proto.remote_candidate_type()); + RTC_PARSE_CHECK_OR_RETURN(GetRuntimeIceCandidateType( + proto.remote_candidate_type(), ice_config.remote_candidate_type)); RTC_PARSE_CHECK_OR_RETURN(proto.has_remote_address_family()); ice_config.remote_address_family = GetRuntimeIceCandidatePairAddressFamily(proto.remote_address_family()); diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc index aece4b5753..1aff19fc34 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -238,12 +238,10 @@ EventGenerator::NewIceCandidatePairConfig() { static_cast(prng_.Rand( static_cast(IceCandidatePairProtocol::kNumValues) - 1)); - IceCandidatePairDescription desc; - desc.local_candidate_type = local_candidate_type; + IceCandidatePairDescription desc(local_candidate_type, remote_candidate_type); desc.local_relay_protocol = protocol_type; desc.local_network_type = local_network_type; desc.local_address_family = local_address_family; - desc.remote_candidate_type = remote_candidate_type; desc.remote_address_family = remote_address_family; desc.candidate_pair_protocol = protocol_type; diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc index a2e3dfce41..cd5166af06 100644 --- a/p2p/base/connection.cc +++ b/p2p/base/connection.cc @@ -82,10 +82,9 @@ webrtc::IceCandidateType GetRtcEventLogCandidateType(const Candidate& c) { return webrtc::IceCandidateType::kStun; } else if (c.is_prflx()) { return webrtc::IceCandidateType::kPrflx; - } else if (c.is_relay()) { - return webrtc::IceCandidateType::kRelay; } - return webrtc::IceCandidateType::kUnknown; + RTC_DCHECK(c.is_relay()); + return webrtc::IceCandidateType::kRelay; } webrtc::IceCandidatePairProtocol GetProtocolByString( @@ -1366,14 +1365,13 @@ const webrtc::IceCandidatePairDescription& Connection::ToLogDescription() { const Candidate& local = local_candidate(); const Candidate& remote = remote_candidate(); const rtc::Network* network = port()->Network(); - log_description_ = webrtc::IceCandidatePairDescription(); - log_description_->local_candidate_type = GetRtcEventLogCandidateType(local); + log_description_ = webrtc::IceCandidatePairDescription( + GetRtcEventLogCandidateType(local), GetRtcEventLogCandidateType(remote)); log_description_->local_relay_protocol = GetProtocolByString(local.relay_protocol()); log_description_->local_network_type = ConvertNetworkType(network->type()); log_description_->local_address_family = GetAddressFamilyByInt(local.address().family()); - log_description_->remote_candidate_type = GetRtcEventLogCandidateType(remote); log_description_->remote_address_family = GetAddressFamilyByInt(remote.address().family()); log_description_->candidate_pair_protocol = diff --git a/rtc_tools/rtc_event_log_to_text/converter.cc b/rtc_tools/rtc_event_log_to_text/converter.cc index 90d568f30f..35a780f043 100644 --- a/rtc_tools/rtc_event_log_to_text/converter.cc +++ b/rtc_tools/rtc_event_log_to_text/converter.cc @@ -231,8 +231,7 @@ bool Convert(std::string inputfile, {IceCandidatePairConfigType::kNumValues, "NUM_VALUES"}}; static const std::map - candidate_type_name{{IceCandidateType::kUnknown, "UNKNOWN"}, - {IceCandidateType::kLocal, "LOCAL"}, + candidate_type_name{{IceCandidateType::kLocal, "LOCAL"}, {IceCandidateType::kStun, "STUN"}, {IceCandidateType::kPrflx, "PRFLX"}, {IceCandidateType::kRelay, "RELAY"}, diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer.cc b/rtc_tools/rtc_event_log_visualizer/analyzer.cc index 1d8d5f12c0..33a7ce3933 100644 --- a/rtc_tools/rtc_event_log_visualizer/analyzer.cc +++ b/rtc_tools/rtc_event_log_visualizer/analyzer.cc @@ -238,7 +238,9 @@ TimeSeries CreateRtcpTypeTimeSeries(const std::vector& rtcp_list, const char kUnknownEnumValue[] = "unknown"; +// TODO(tommi): This should be "host". const char kIceCandidateTypeLocal[] = "local"; +// TODO(tommi): This should be "srflx". const char kIceCandidateTypeStun[] = "stun"; const char kIceCandidateTypePrflx[] = "prflx"; const char kIceCandidateTypeRelay[] = "relay"; @@ -257,17 +259,18 @@ const char kNetworkTypeWifi[] = "wifi"; const char kNetworkTypeVpn[] = "vpn"; const char kNetworkTypeCellular[] = "cellular"; -std::string GetIceCandidateTypeAsString(webrtc::IceCandidateType type) { +absl::string_view GetIceCandidateTypeAsString(IceCandidateType type) { switch (type) { - case webrtc::IceCandidateType::kLocal: + case IceCandidateType::kLocal: return kIceCandidateTypeLocal; - case webrtc::IceCandidateType::kStun: + case IceCandidateType::kStun: return kIceCandidateTypeStun; - case webrtc::IceCandidateType::kPrflx: + case IceCandidateType::kPrflx: return kIceCandidateTypePrflx; - case webrtc::IceCandidateType::kRelay: + case IceCandidateType::kRelay: return kIceCandidateTypeRelay; default: + RTC_DCHECK_NOTREACHED(); return kUnknownEnumValue; } } @@ -323,18 +326,15 @@ std::string GetCandidatePairLogDescriptionAsString( // and a remote relay candidate using TCP as the relay protocol on a cell // network, when the candidate pair communicates over UDP using IPv4. rtc::StringBuilder ss; - std::string local_candidate_type = - GetIceCandidateTypeAsString(config.local_candidate_type); - std::string remote_candidate_type = - GetIceCandidateTypeAsString(config.remote_candidate_type); - if (config.local_candidate_type == webrtc::IceCandidateType::kRelay) { - local_candidate_type += - "(" + GetProtocolAsString(config.local_relay_protocol) + ")"; + ss << GetIceCandidateTypeAsString(config.local_candidate_type); + + if (config.local_candidate_type == IceCandidateType::kRelay) { + ss << "(" << GetProtocolAsString(config.local_relay_protocol) << ")"; } - ss << local_candidate_type << ":" - << GetNetworkTypeAsString(config.local_network_type) << ":" + + ss << ":" << GetNetworkTypeAsString(config.local_network_type) << ":" << GetAddressFamilyAsString(config.local_address_family) << "->" - << remote_candidate_type << ":" + << GetIceCandidateTypeAsString(config.remote_candidate_type) << ":" << GetAddressFamilyAsString(config.remote_address_family) << "@" << GetProtocolAsString(config.candidate_pair_protocol); return ss.Release(); From 3cbe63eac1646ba3e8be6db8521ebd138fb364b3 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Fri, 19 Jan 2024 09:53:12 +0100 Subject: [PATCH 045/170] Do not register receiver for REMB until it starts receiving which avoids associating a REMB sender with a inactive m-line. BUG=webrtc:15759,webrtc:11013 Change-Id: I391614856323637522720b5022ca176077f14ec7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335281 Reviewed-by: Ilya Nikolaevskiy Reviewed-by: Harald Alvestrand Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41641} --- video/rtp_video_stream_receiver2.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc index 7f6565346c..624f699b73 100644 --- a/video/rtp_video_stream_receiver2.cc +++ b/video/rtp_video_stream_receiver2.cc @@ -296,9 +296,12 @@ RtpVideoStreamReceiver2::RtpVideoStreamReceiver2( frames_decryptable_(false), absolute_capture_time_interpolator_(clock) { packet_sequence_checker_.Detach(); - constexpr bool remb_candidate = true; - if (packet_router_) - packet_router_->AddReceiveRtpModule(rtp_rtcp_.get(), remb_candidate); + if (packet_router_) { + // Do not register as REMB candidate, this is only done when starting to + // receive. + packet_router_->AddReceiveRtpModule(rtp_rtcp_.get(), + /*remb_candidate=*/false); + } RTC_DCHECK(config_.rtp.rtcp_mode != RtcpMode::kOff) << "A stream should not be configured with RTCP disabled. This value is " @@ -1251,11 +1254,23 @@ void RtpVideoStreamReceiver2::SignalNetworkState(NetworkState state) { void RtpVideoStreamReceiver2::StartReceive() { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); + if (!receiving_ && packet_router_) { + // Change REMB candidate egibility. + packet_router_->RemoveReceiveRtpModule(rtp_rtcp_.get()); + packet_router_->AddReceiveRtpModule(rtp_rtcp_.get(), + /*remb_candidate=*/true); + } receiving_ = true; } void RtpVideoStreamReceiver2::StopReceive() { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); + if (receiving_ && packet_router_) { + // Change REMB candidate egibility. + packet_router_->RemoveReceiveRtpModule(rtp_rtcp_.get()); + packet_router_->AddReceiveRtpModule(rtp_rtcp_.get(), + /*remb_candidate=*/false); + } receiving_ = false; } From 7cb4ce0079b3db66c892971189f17eb2abe78427 Mon Sep 17 00:00:00 2001 From: Tommi Date: Mon, 29 Jan 2024 15:14:33 +0100 Subject: [PATCH 046/170] Remove IceCandidateType::kNumValues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: none Change-Id: I108a006d6ff00f436c87dc9ee5b7e3c27b7b6c83 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336242 Commit-Queue: Tomas Gunnarsson Reviewed-by: Björn Terelius Cr-Commit-Position: refs/heads/main@{#41642} --- .../encoder/rtc_event_log_encoder_legacy.cc | 5 +--- .../rtc_event_log_encoder_new_format.cc | 2 -- .../rtc_event_ice_candidate_pair_config.h | 5 ++-- .../rtc_event_log_unittest_helper.cc | 25 ++++++++++++++++--- rtc_tools/rtc_event_log_to_text/converter.cc | 3 +-- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc index ba1e597ad8..f1b12f0beb 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc @@ -139,10 +139,6 @@ rtclog::IceCandidatePairConfig::IceCandidateType ConvertIceCandidateType( return rtclog::IceCandidatePairConfig::PRFLX; case IceCandidateType::kRelay: return rtclog::IceCandidatePairConfig::RELAY; - default: - // TODO(tommi): Remove the default handler when kNumValues is gone. - RTC_DCHECK_NOTREACHED(); - return rtclog::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; } } @@ -200,6 +196,7 @@ rtclog::IceCandidatePairConfig::NetworkType ConvertIceCandidateNetworkType( return rtclog::IceCandidatePairConfig::CELLULAR; case IceCandidateNetworkType::kNumValues: RTC_DCHECK_NOTREACHED(); + break; } RTC_DCHECK_NOTREACHED(); return rtclog::IceCandidatePairConfig::UNKNOWN_NETWORK_TYPE; diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc index a07afbe48a..4c662fd266 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc @@ -206,8 +206,6 @@ rtclog2::IceCandidatePairConfig::IceCandidateType ConvertToProtoFormat( return rtclog2::IceCandidatePairConfig::PRFLX; case IceCandidateType::kRelay: return rtclog2::IceCandidatePairConfig::RELAY; - case IceCandidateType::kNumValues: - RTC_DCHECK_NOTREACHED(); } RTC_DCHECK_NOTREACHED(); return rtclog2::IceCandidatePairConfig::UNKNOWN_CANDIDATE_TYPE; diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h index a44f530e77..e77253d9fb 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h @@ -32,14 +32,13 @@ enum class IceCandidatePairConfigType { kNumValues, }; -// TODO(qingsi): Change the names of candidate types to "host", "srflx", "prflx" -// and "relay" after the naming is spec-compliant in the signaling part +// TODO(tommi): Change the names of candidate types to "host", "srflx" for +// spec-compliance. enum class IceCandidateType { kLocal, kStun, kPrflx, kRelay, - kNumValues, }; enum class IceCandidatePairProtocol { diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc index 1aff19fc34..df3586a3b6 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -217,10 +217,27 @@ EventGenerator::NewProbeResultSuccess() { return std::make_unique(id, bitrate_bps); } +constexpr uint32_t CandidateTypeCount() { + // This switch statement only exists to catch changes to the IceCandidateType + // enumeration. If you get an error here, please update the switch statement + // and the return value. + IceCandidateType type = IceCandidateType::kLocal; + switch (type) { + case IceCandidateType::kLocal: + case IceCandidateType::kStun: + case IceCandidateType::kPrflx: + case IceCandidateType::kRelay: + break; + } + return 4u; +} + std::unique_ptr EventGenerator::NewIceCandidatePairConfig() { - IceCandidateType local_candidate_type = static_cast( - prng_.Rand(static_cast(IceCandidateType::kNumValues) - 1)); + static_assert(static_cast(IceCandidateType::kLocal) == 0, + "Expect kLocal to be the first enum value, equal to 0"); + IceCandidateType local_candidate_type = + static_cast(prng_.Rand(CandidateTypeCount() - 1)); IceCandidateNetworkType local_network_type = static_cast(prng_.Rand( static_cast(IceCandidateNetworkType::kNumValues) - 1)); @@ -228,8 +245,8 @@ EventGenerator::NewIceCandidatePairConfig() { static_cast(prng_.Rand( static_cast(IceCandidatePairAddressFamily::kNumValues) - 1)); - IceCandidateType remote_candidate_type = static_cast( - prng_.Rand(static_cast(IceCandidateType::kNumValues) - 1)); + IceCandidateType remote_candidate_type = + static_cast(prng_.Rand(CandidateTypeCount() - 1)); IceCandidatePairAddressFamily remote_address_family = static_cast(prng_.Rand( static_cast(IceCandidatePairAddressFamily::kNumValues) - diff --git a/rtc_tools/rtc_event_log_to_text/converter.cc b/rtc_tools/rtc_event_log_to_text/converter.cc index 35a780f043..79cf03ead4 100644 --- a/rtc_tools/rtc_event_log_to_text/converter.cc +++ b/rtc_tools/rtc_event_log_to_text/converter.cc @@ -234,8 +234,7 @@ bool Convert(std::string inputfile, candidate_type_name{{IceCandidateType::kLocal, "LOCAL"}, {IceCandidateType::kStun, "STUN"}, {IceCandidateType::kPrflx, "PRFLX"}, - {IceCandidateType::kRelay, "RELAY"}, - {IceCandidateType::kNumValues, "NUM_VALUES"}}; + {IceCandidateType::kRelay, "RELAY"}}; static const std::map protocol_name{{IceCandidatePairProtocol::kUnknown, "UNKNOWN"}, From c0741e9f12df679a2ec634d064edd212d7e72ed3 Mon Sep 17 00:00:00 2001 From: Olga Sharonova Date: Wed, 31 Jan 2024 12:49:22 +0000 Subject: [PATCH 047/170] Revert "Take out Fuchsia-only SDES-enabling parameters" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 59f3b35013a29f8c73a46fa6fd06aadc96aad892. Broke WebRTC into Chrome rolls: https://chromium-review.googlesource.com/c/chromium/src/+/5248171?tab=checks /../third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc:216:18: error: no member named 'enable_dtls_srtp' in 'webrtc::PeerConnectionInterface::RTCConfiguration' 216 | configuration->enable_dtls_srtp = dtls_srtp_key_agreement; | ~~~~~~~~~~~~~ ^ Original change's description: > Take out Fuchsia-only SDES-enabling parameters > > This does not remove all traces of SDES - we still need to delete > the cricket::CryptoParams struct and all code that uses it. > > Bug: webrtc:11066, chromium:804275 > Change-Id: I811c8d40da7f4af714d53376f24cd53332a15945 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336780 > Reviewed-by: Henrik Boström > Commit-Queue: Harald Alvestrand > Cr-Commit-Position: refs/heads/main@{#41634} Bug: webrtc:11066, chromium:804275 Change-Id: I2c2114873091e0c662977a6ef5723e6447166a65 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337181 Commit-Queue: Olga Sharonova Reviewed-by: Henrik Boström Bot-Commit: rubber-stamper@appspot.gserviceaccount.com Owners-Override: Olga Sharonova Cr-Commit-Position: refs/heads/main@{#41643} --- api/peer_connection_interface.h | 9 + pc/peer_connection.cc | 16 +- pc/peer_connection_crypto_unittest.cc | 249 ++++++++++++++++++++++++++ pc/peer_connection_integrationtest.cc | 20 +++ pc/sdp_offer_answer.cc | 3 + 5 files changed, 296 insertions(+), 1 deletion(-) diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h index 7699f33438..3c225eb28a 100644 --- a/api/peer_connection_interface.h +++ b/api/peer_connection_interface.h @@ -451,6 +451,15 @@ class RTC_EXPORT PeerConnectionInterface : public webrtc::RefCountInterface { // when switching from a static scene to one with motion. absl::optional screencast_min_bitrate; +#if defined(WEBRTC_FUCHSIA) + // TODO(bugs.webrtc.org/11066): Remove entirely once Fuchsia does not use. + // TODO(bugs.webrtc.org/9891) - Move to crypto_options + // Can be used to disable DTLS-SRTP. This should never be done, but can be + // useful for testing purposes, for example in setting up a loopback call + // with a single PeerConnection. + absl::optional enable_dtls_srtp; +#endif + ///////////////////////////////////////////////// // The below fields are not part of the standard. ///////////////////////////////////////////////// diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 3ab2c52130..dc784771f8 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -348,7 +348,15 @@ bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration, return false; // Enable DTLS by default if we have an identity store or a certificate. - return (dependencies.cert_generator || !configuration.certificates.empty()); + bool default_enabled = + (dependencies.cert_generator || !configuration.certificates.empty()); + +#if defined(WEBRTC_FUCHSIA) + // The `configuration` can override the default value. + return configuration.enable_dtls_srtp.value_or(default_enabled); +#else + return default_enabled; +#endif } // Calls `ParseIceServersOrError` to extract ice server information from the @@ -408,6 +416,9 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( int max_ipv6_networks; bool disable_link_local_networks; absl::optional screencast_min_bitrate; +#if defined(WEBRTC_FUCHSIA) + absl::optional enable_dtls_srtp; +#endif TcpCandidatePolicy tcp_candidate_policy; CandidateNetworkPolicy candidate_network_policy; int audio_jitter_buffer_max_packets; @@ -472,6 +483,9 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( max_ipv6_networks == o.max_ipv6_networks && disable_link_local_networks == o.disable_link_local_networks && screencast_min_bitrate == o.screencast_min_bitrate && +#if defined(WEBRTC_FUCHSIA) + enable_dtls_srtp == o.enable_dtls_srtp && +#endif ice_candidate_pool_size == o.ice_candidate_pool_size && prune_turn_ports == o.prune_turn_ports && turn_port_prune_policy == o.turn_port_prune_policy && diff --git a/pc/peer_connection_crypto_unittest.cc b/pc/peer_connection_crypto_unittest.cc index 4274e88b07..3b3f502e1f 100644 --- a/pc/peer_connection_crypto_unittest.cc +++ b/pc/peer_connection_crypto_unittest.cc @@ -258,6 +258,233 @@ TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsEnabled) { answer->description())); } +#if defined(WEBRTC_FUCHSIA) +// When DTLS is disabled, the SDP offer/answer should include SDES cryptos and +// should not have a DTLS fingerprint. +TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsDisabled) { + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + ASSERT_TRUE(offer); + + ASSERT_FALSE(offer->description()->contents().empty()); + EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), offer->description())); + EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); + EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), + offer->description())); +} + +TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsDisabled) { + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + callee->SetRemoteDescription(caller->CreateOffer()); + auto answer = callee->CreateAnswer(); + ASSERT_TRUE(answer); + + ASSERT_FALSE(answer->description()->contents().empty()); + EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), answer->description())); + EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); + EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), + answer->description())); +} + +// When encryption is disabled, the SDP offer/answer should have neither a DTLS +// fingerprint nor any SDES crypto options. +TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenEncryptionDisabled) { + PeerConnectionFactoryInterface::Options options; + options.disable_encryption = true; + pc_factory_->SetOptions(options); + + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + ASSERT_TRUE(offer); + + ASSERT_FALSE(offer->description()->contents().empty()); + EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description())); + EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); + EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), + offer->description())); +} + +TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenEncryptionDisabled) { + PeerConnectionFactoryInterface::Options options; + options.disable_encryption = true; + pc_factory_->SetOptions(options); + + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + callee->SetRemoteDescription(caller->CreateOffer()); + auto answer = callee->CreateAnswer(); + ASSERT_TRUE(answer); + + ASSERT_FALSE(answer->description()->contents().empty()); + EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description())); + EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); + EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), + answer->description())); +} + +// CryptoOptions has been promoted to RTCConfiguration. As such if it is ever +// set in the configuration it should overrite the settings set in the factory. +TEST_P(PeerConnectionCryptoTest, RTCConfigurationCryptoOptionOverridesFactory) { + PeerConnectionFactoryInterface::Options options; + options.crypto_options.srtp.enable_gcm_crypto_suites = true; + pc_factory_->SetOptions(options); + + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + CryptoOptions crypto_options; + crypto_options.srtp.enable_gcm_crypto_suites = false; + config.crypto_options = crypto_options; + auto caller = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + ASSERT_TRUE(offer); + + ASSERT_FALSE(offer->description()->contents().empty()); + // This should exist if GCM is enabled see CorrectCryptoInOfferWithSdesAndGcm + EXPECT_FALSE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); +} + +// When DTLS is disabled and GCM cipher suites are enabled, the SDP offer/answer +// should have the correct ciphers in the SDES crypto options. +// With GCM cipher suites enabled, there will be 3 cryptos in the offer and 1 +// in the answer. +TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWithSdesAndGcm) { + PeerConnectionFactoryInterface::Options options; + options.crypto_options.srtp.enable_gcm_crypto_suites = true; + pc_factory_->SetOptions(options); + + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + ASSERT_TRUE(offer); + + ASSERT_FALSE(offer->description()->contents().empty()); + EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); +} + +TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWithSdesAndGcm) { + PeerConnectionFactoryInterface::Options options; + options.crypto_options.srtp.enable_gcm_crypto_suites = true; + pc_factory_->SetOptions(options); + + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + for (cricket::ContentInfo& content : offer->description()->contents()) { + auto cryptos = content.media_description()->cryptos(); + cryptos.erase(cryptos.begin()); // Assumes that non-GCM is the default. + content.media_description()->set_cryptos(cryptos); + } + + callee->SetRemoteDescription(std::move(offer)); + auto answer = callee->CreateAnswer(); + ASSERT_TRUE(answer); + + ASSERT_FALSE(answer->description()->contents().empty()); + EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(1), answer->description())); +} + +TEST_P(PeerConnectionCryptoTest, CanSetSdesGcmRemoteOfferAndLocalAnswer) { + PeerConnectionFactoryInterface::Options options; + options.crypto_options.srtp.enable_gcm_crypto_suites = true; + pc_factory_->SetOptions(options); + + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + ASSERT_TRUE(offer); + ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); + + auto answer = callee->CreateAnswer(); + ASSERT_TRUE(answer); + ASSERT_TRUE(callee->SetLocalDescription(std::move(answer))); +} + +// The following group tests that two PeerConnections can successfully exchange +// an offer/answer when DTLS is off and that they will refuse any offer/answer +// applied locally/remotely if it does not include SDES cryptos. +TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenSdesOn) { + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOfferAndSetAsLocal(); + ASSERT_TRUE(offer); + ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); + + auto answer = callee->CreateAnswerAndSetAsLocal(); + ASSERT_TRUE(answer); + ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); +} +TEST_P(PeerConnectionCryptoTest, FailToSetLocalOfferWithNoCryptosWhenSdesOn) { + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + SdpContentsForEach(RemoveSdesCryptos(), offer->description()); + + EXPECT_FALSE(caller->SetLocalDescription(std::move(offer))); +} +TEST_P(PeerConnectionCryptoTest, FailToSetRemoteOfferWithNoCryptosWhenSdesOn) { + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOffer(); + SdpContentsForEach(RemoveSdesCryptos(), offer->description()); + + EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer))); +} +TEST_P(PeerConnectionCryptoTest, FailToSetLocalAnswerWithNoCryptosWhenSdesOn) { + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); + auto answer = callee->CreateAnswer(); + SdpContentsForEach(RemoveSdesCryptos(), answer->description()); + + EXPECT_FALSE(callee->SetLocalDescription(std::move(answer))); +} +TEST_P(PeerConnectionCryptoTest, FailToSetRemoteAnswerWithNoCryptosWhenSdesOn) { + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); + auto answer = callee->CreateAnswerAndSetAsLocal(); + SdpContentsForEach(RemoveSdesCryptos(), answer->description()); + + EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); +} +#endif + // The following group tests that two PeerConnections can successfully exchange // an offer/answer when DTLS is on and that they will refuse any offer/answer // applied locally/remotely if it does not include a DTLS fingerprint. @@ -318,6 +545,28 @@ TEST_P(PeerConnectionCryptoTest, EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); } +#if defined(WEBRTC_FUCHSIA) +// Test that an offer/answer can be exchanged when encryption is disabled. +TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenNoEncryption) { + PeerConnectionFactoryInterface::Options options; + options.disable_encryption = true; + pc_factory_->SetOptions(options); + + RTCConfiguration config; + config.enable_dtls_srtp.emplace(false); + auto caller = CreatePeerConnectionWithAudioVideo(config); + auto callee = CreatePeerConnectionWithAudioVideo(config); + + auto offer = caller->CreateOfferAndSetAsLocal(); + ASSERT_TRUE(offer); + ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); + + auto answer = callee->CreateAnswerAndSetAsLocal(); + ASSERT_TRUE(answer); + ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); +} +#endif + // Tests that a DTLS call can be established when the certificate is specified // in the PeerConnection config and no certificate generator is specified. TEST_P(PeerConnectionCryptoTest, diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc index 24ca52f619..23c8b1690f 100644 --- a/pc/peer_connection_integrationtest.cc +++ b/pc/peer_connection_integrationtest.cc @@ -275,6 +275,26 @@ TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) { ASSERT_TRUE(ExpectNewFrames(media_expectations)); } +#if defined(WEBRTC_FUCHSIA) +// Uses SDES instead of DTLS for key agreement. +TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) { + PeerConnectionInterface::RTCConfiguration sdes_config; + sdes_config.enable_dtls_srtp.emplace(false); + ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config)); + ConnectFakeSignaling(); + + // Do normal offer/answer and wait for some frames to be received in each + // direction. + caller()->AddAudioVideoTracks(); + callee()->AddAudioVideoTracks(); + caller()->CreateAndSetAndSignalOffer(); + ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); + MediaExpectations media_expectations; + media_expectations.ExpectBidirectionalAudioAndVideo(); + ASSERT_TRUE(ExpectNewFrames(media_expectations)); +} +#endif + // Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions` // option to offer encrypted versions of all header extensions alongside the // unencrypted versions. diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 19cd9ba45c..67c8d10241 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -285,6 +285,9 @@ RTCError VerifyCrypto(const SessionDescription* desc, if (content_info.rejected) { continue; } +#if !defined(WEBRTC_FUCHSIA) + RTC_CHECK(dtls_enabled) << "SDES protocol is only allowed in Fuchsia"; +#endif const std::string& mid = content_info.name; auto it = bundle_groups_by_mid.find(mid); const cricket::ContentGroup* bundle = From 14b016fbf9b99c15edc8e9bb4732f7306cc3bad9 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Fri, 5 Jan 2024 13:51:00 +0100 Subject: [PATCH 048/170] In RtcEventLogEncoderNewFormat use propagated instead of global field trials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:10335 Change-Id: Id407a7bc25375cadccba4cf4ae0c771f22a19a0e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333581 Reviewed-by: Björn Terelius Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41644} --- logging/BUILD.gn | 3 +- .../rtc_event_log_encoder_new_format.cc | 29 ++-- .../rtc_event_log_encoder_new_format.h | 10 +- .../encoder/rtc_event_log_encoder_unittest.cc | 155 ++++++++++++------ logging/rtc_event_log/rtc_event_log_impl.cc | 2 +- 5 files changed, 131 insertions(+), 68 deletions(-) diff --git a/logging/BUILD.gn b/logging/BUILD.gn index 91890553a3..5b91a39357 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -353,6 +353,7 @@ rtc_library("rtc_event_log_impl_encoder") { deps = [ ":rtc_event_number_encodings", + "../api:field_trials_view", "../api:rtp_headers", "../api:rtp_parameters", "../api/transport:network_control", @@ -362,7 +363,6 @@ rtc_library("rtc_event_log_impl_encoder") { "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:safe_conversions", - "../system_wrappers:field_trial", ] absl_deps = [ "//third_party/abseil-cpp/absl/memory", @@ -617,6 +617,7 @@ if (rtc_enable_protobuf) { "../api/environment:environment_factory", "../api/rtc_event_log", "../api/rtc_event_log:rtc_event_log_factory", + "../api/transport:field_trial_based_config", "../api/units:time_delta", "../api/units:timestamp", "../call", diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc index 4c662fd266..ebda3bfeed 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc @@ -10,8 +10,11 @@ #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h" +#include + #include "absl/types/optional.h" #include "api/array_view.h" +#include "api/field_trials_view.h" #include "api/network_state_predictor.h" #include "logging/rtc_event_log/dependency_descriptor_encoder_decoder.h" #include "logging/rtc_event_log/encoder/blob_encoding.h" @@ -62,7 +65,6 @@ #include "modules/rtp_rtcp/source/rtp_packet.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" -#include "system_wrappers/include/field_trial.h" // *.pb.h files are generated at build-time by the protobuf compiler. #ifdef WEBRTC_ANDROID_PLATFORM_BUILD @@ -381,10 +383,12 @@ void EncodeRtcpPacket(rtc::ArrayView batch, } proto_batch->set_raw_packet_blobs(EncodeBlobs(scrubed_packets)); } +} // namespace -template -void EncodeRtpPacket(const std::vector& batch, - ProtoType* proto_batch) { +template +void RtcEventLogEncoderNewFormat::EncodeRtpPacket(const Batch& batch, + ProtoType* proto_batch) { + using EventType = std::remove_pointer_t; if (batch.empty()) { return; } @@ -459,8 +463,7 @@ void EncodeRtpPacket(const std::vector& batch, { // TODO(webrtc:14975) Remove this kill switch after DD in RTC event log has // been rolled out. - if (!webrtc::field_trial::IsDisabled( - "WebRTC-RtcEventLogEncodeDependencyDescriptor")) { + if (encode_dependency_descriptor_) { std::vector> raw_dds(batch.size()); bool has_dd = false; for (size_t i = 0; i < batch.size(); ++i) { @@ -674,15 +677,13 @@ void EncodeRtpPacket(const std::vector& batch, proto_batch->set_voice_activity_deltas(encoded_deltas); } } -} // namespace -RtcEventLogEncoderNewFormat::RtcEventLogEncoderNewFormat() { - encode_neteq_set_minimum_delay_kill_switch_ = false; - if (webrtc::field_trial::IsEnabled( - "WebRTC-RtcEventLogEncodeNetEqSetMinimumDelayKillSwitch")) { - encode_neteq_set_minimum_delay_kill_switch_ = true; - } -} +RtcEventLogEncoderNewFormat::RtcEventLogEncoderNewFormat( + const FieldTrialsView& field_trials) + : encode_neteq_set_minimum_delay_kill_switch_(field_trials.IsEnabled( + "WebRTC-RtcEventLogEncodeNetEqSetMinimumDelayKillSwitch")), + encode_dependency_descriptor_(!field_trials.IsDisabled( + "WebRTC-RtcEventLogEncodeDependencyDescriptor")) {} std::string RtcEventLogEncoderNewFormat::EncodeLogStart(int64_t timestamp_us, int64_t utc_time_us) { diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h index 6747f41f07..6a657090dd 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h @@ -18,6 +18,7 @@ #include #include "api/array_view.h" +#include "api/field_trials_view.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder.h" namespace webrtc { @@ -59,7 +60,7 @@ class RtcEventGenericPacketSent; class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder { public: - RtcEventLogEncoderNewFormat(); + explicit RtcEventLogEncoderNewFormat(const FieldTrialsView& field_trials); ~RtcEventLogEncoderNewFormat() override = default; std::string EncodeBatch( @@ -71,8 +72,6 @@ class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder { std::string EncodeLogEnd(int64_t timestamp_us) override; private: - bool encode_neteq_set_minimum_delay_kill_switch_ = false; - // Encoding entry-point for the various RtcEvent subclasses. void EncodeAlrState(rtc::ArrayView batch, rtclog2::EventStream* event_stream); @@ -157,6 +156,11 @@ class RtcEventLogEncoderNewFormat final : public RtcEventLogEncoder { void EncodeVideoSendStreamConfig( rtc::ArrayView batch, rtclog2::EventStream* event_stream); + template + void EncodeRtpPacket(const Batch& batch, ProtoType* proto_batch); + + const bool encode_neteq_set_minimum_delay_kill_switch_; + const bool encode_dependency_descriptor_; }; } // namespace webrtc diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc index 612f85bf61..73ff67e8b9 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc @@ -14,6 +14,7 @@ #include #include +#include "api/transport/field_trial_based_config.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_v3.h" @@ -40,10 +41,14 @@ #include "modules/rtp_rtcp/source/rtp_header_extensions.h" #include "rtc_base/fake_clock.h" #include "rtc_base/random.h" +#include "test/explicit_key_value_config.h" #include "test/field_trial.h" #include "test/gtest.h" namespace webrtc { + +using test::ExplicitKeyValueConfig; + class RtcEventLogEncoderTest : public ::testing::TestWithParam< std::tuple> { @@ -55,22 +60,26 @@ class RtcEventLogEncoderTest event_count_(std::get<2>(GetParam())), force_repeated_fields_(std::get<3>(GetParam())), gen_(seed_ * 880001UL), - verifier_(encoding_type_) { + verifier_(encoding_type_) {} + ~RtcEventLogEncoderTest() override = default; + + std::unique_ptr CreateEncoder() { + std::unique_ptr encoder; switch (encoding_type_) { case RtcEventLog::EncodingType::Legacy: - encoder_ = std::make_unique(); + encoder = std::make_unique(); break; case RtcEventLog::EncodingType::NewFormat: - encoder_ = std::make_unique(); + encoder = std::make_unique( + FieldTrialBasedConfig()); break; case RtcEventLog::EncodingType::ProtoFree: - encoder_ = std::make_unique(); + encoder = std::make_unique(); break; } - encoded_ = - encoder_->EncodeLogStart(rtc::TimeMillis(), rtc::TimeUTCMillis()); + encoded_ = encoder->EncodeLogStart(rtc::TimeMillis(), rtc::TimeUTCMillis()); + return encoder; } - ~RtcEventLogEncoderTest() override = default; // ANA events have some optional fields, so we want to make sure that we get // correct behavior both when all of the values are there, as well as when @@ -92,7 +101,6 @@ class RtcEventLogEncoderTest void TestRtpPackets(); std::deque> history_; - std::unique_ptr encoder_; ParsedRtcEventLog parsed_log_; const uint64_t seed_; Random prng_; @@ -108,12 +116,13 @@ void RtcEventLogEncoderTest::TestRtcEventAudioNetworkAdaptation( const std::vector>& events) { ASSERT_TRUE(history_.empty()) << "Function should be called once per test."; + std::unique_ptr encoder = CreateEncoder(); for (auto& event : events) { history_.push_back(event->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& ana_configs = parsed_log_.audio_network_adaptation_events(); @@ -172,6 +181,7 @@ void RtcEventLogEncoderTest::TestRtpPackets() { const std::vector kSsrcPool = {0x00000000, 0x12345678, 0xabcdef01, 0xffffffff, 0x20171024, 0x19840730, 0x19831230}; + std::unique_ptr encoder = CreateEncoder(); // TODO(terelius): Test extensions for legacy encoding, too. RtpHeaderExtensionMap extension_map; @@ -193,7 +203,7 @@ void RtcEventLogEncoderTest::TestRtpPackets() { } // Encode and parse. - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); // For each SSRC, make sure the RTP packets associated with it to have been @@ -213,6 +223,7 @@ void RtcEventLogEncoderTest::TestRtpPackets() { } TEST_P(RtcEventLogEncoderTest, RtcEventAlrState) { + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) ? gen_.NewAlrState() @@ -220,7 +231,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAlrState) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& alr_state_events = parsed_log_.alr_state_events(); @@ -234,6 +245,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRouteChange) { if (encoding_type_ == RtcEventLog::EncodingType::Legacy) { return; } + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) ? gen_.NewRouteChange() @@ -241,7 +253,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRouteChange) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& route_change_events = parsed_log_.route_change_events(); @@ -252,6 +264,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRouteChange) { } TEST_P(RtcEventLogEncoderTest, RtcEventRemoteEstimate) { + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) @@ -260,7 +273,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRemoteEstimate) { history_.push_back(std::make_unique(*events[i])); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& parsed_events = parsed_log_.remote_estimate_events(); @@ -395,6 +408,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationAll) { } TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) { + std::unique_ptr encoder = CreateEncoder(); // SSRCs will be randomly assigned out of this small pool, significant only // in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff. // The pool is intentionally small, so as to produce collisions. @@ -414,7 +428,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) { original_events_by_ssrc[ssrc].push_back(std::move(event)); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& parsed_playout_events_by_ssrc = @@ -443,6 +457,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) { } TEST_P(RtcEventLogEncoderTest, RtcEventNetEqSetMinimumDelayDecoded) { + std::unique_ptr encoder = CreateEncoder(); // SSRCs will be randomly assigned out of this small pool, significant only // in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff. // The pool is intentionally small, so as to produce collisions. @@ -461,7 +476,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventNetEqSetMinimumDelayDecoded) { original_events_by_ssrc[ssrc].push_back(std::move(event)); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& parsed_neteq_set_minimum_delay_events_by_ssrc = @@ -502,13 +517,14 @@ TEST_P(RtcEventLogEncoderTest, RtcEventNetEqSetMinimumDelayDecoded) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) { + std::unique_ptr encoder = CreateEncoder(); uint32_t ssrc = prng_.Rand(); RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); std::unique_ptr event = gen_.NewAudioReceiveStreamConfig(ssrc, extensions); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& audio_recv_configs = parsed_log_.audio_recv_configs(); @@ -518,13 +534,14 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventAudioSendStreamConfig) { + std::unique_ptr encoder = CreateEncoder(); uint32_t ssrc = prng_.Rand(); RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); std::unique_ptr event = gen_.NewAudioSendStreamConfig(ssrc, extensions); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& audio_send_configs = parsed_log_.audio_send_configs(); @@ -533,6 +550,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventAudioSendStreamConfig) { } TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) { + std::unique_ptr encoder = CreateEncoder(); std::vector> events( event_count_); for (size_t i = 0; i < event_count_; ++i) { @@ -542,7 +560,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& bwe_delay_updates = parsed_log_.bwe_delay_updates(); @@ -554,6 +572,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) { } TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) { + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) @@ -562,7 +581,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& bwe_loss_updates = parsed_log_.bwe_loss_updates(); @@ -577,6 +596,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketReceived) { if (encoding_type_ == RtcEventLog::EncodingType::Legacy) { return; } + std::unique_ptr encoder = CreateEncoder(); std::vector> events( event_count_); for (size_t i = 0; i < event_count_; ++i) { @@ -586,7 +606,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketReceived) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& packets_received = parsed_log_.generic_packets_received(); @@ -602,6 +622,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketSent) { if (encoding_type_ == RtcEventLog::EncodingType::Legacy) { return; } + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) @@ -610,7 +631,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventGenericPacketSent) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& packets_sent = parsed_log_.generic_packets_sent(); @@ -625,6 +646,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventGenericAcksReceived) { if (encoding_type_ == RtcEventLog::EncodingType::Legacy) { return; } + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) @@ -633,7 +655,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventGenericAcksReceived) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& decoded_events = parsed_log_.generic_acks_received(); @@ -645,6 +667,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventGenericAcksReceived) { } TEST_P(RtcEventLogEncoderTest, RtcEventDtlsTransportState) { + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) @@ -653,7 +676,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventDtlsTransportState) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& dtls_transport_states = parsed_log_.dtls_transport_states(); @@ -670,6 +693,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventDtlsTransportState) { } TEST_P(RtcEventLogEncoderTest, RtcEventDtlsWritableState) { + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) @@ -678,7 +702,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventDtlsWritableState) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& dtls_writable_states = parsed_log_.dtls_writable_states(); @@ -696,6 +720,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventDtlsWritableState) { } TEST_P(RtcEventLogEncoderTest, RtcEventFrameDecoded) { + std::unique_ptr encoder = CreateEncoder(); // SSRCs will be randomly assigned out of this small pool, significant only // in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff. // The pool is intentionally small, so as to produce collisions. @@ -715,7 +740,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventFrameDecoded) { original_events_by_ssrc[ssrc].push_back(std::move(event)); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); auto status = parsed_log_.ParseString(encoded_); if (!status.ok()) RTC_LOG(LS_ERROR) << status.message(); @@ -751,11 +776,12 @@ TEST_P(RtcEventLogEncoderTest, RtcEventFrameDecoded) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePairConfig) { + std::unique_ptr encoder = CreateEncoder(); std::unique_ptr event = gen_.NewIceCandidatePairConfig(); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& ice_candidate_pair_configs = parsed_log_.ice_candidate_pair_configs(); @@ -767,10 +793,11 @@ TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePairConfig) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePair) { + std::unique_ptr encoder = CreateEncoder(); std::unique_ptr event = gen_.NewIceCandidatePair(); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& ice_candidate_pair_events = parsed_log_.ice_candidate_pair_events(); @@ -781,11 +808,12 @@ TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePair) { } TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) { + std::unique_ptr encoder = CreateEncoder(); const int64_t timestamp_ms = prng_.Rand(1'000'000'000); const int64_t utc_time_ms = prng_.Rand(1'000'000'000); // Overwrite the previously encoded LogStart event. - encoded_ = encoder_->EncodeLogStart(timestamp_ms * 1000, utc_time_ms * 1000); + encoded_ = encoder->EncodeLogStart(timestamp_ms * 1000, utc_time_ms * 1000); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& start_log_events = parsed_log_.start_log_events(); @@ -795,16 +823,17 @@ TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) { } TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) { + std::unique_ptr encoder = CreateEncoder(); const int64_t start_timestamp_ms = prng_.Rand(1'000'000'000); const int64_t start_utc_time_ms = prng_.Rand(1'000'000'000); // Overwrite the previously encoded LogStart event. - encoded_ = encoder_->EncodeLogStart(start_timestamp_ms * 1000, - start_utc_time_ms * 1000); + encoded_ = encoder->EncodeLogStart(start_timestamp_ms * 1000, + start_utc_time_ms * 1000); const int64_t stop_timestamp_ms = prng_.Rand(start_timestamp_ms, 2'000'000'000); - encoded_ += encoder_->EncodeLogEnd(stop_timestamp_ms * 1000); + encoded_ += encoder->EncodeLogEnd(stop_timestamp_ms * 1000); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& stop_log_events = parsed_log_.stop_log_events(); @@ -814,11 +843,12 @@ TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) { + std::unique_ptr encoder = CreateEncoder(); std::unique_ptr event = gen_.NewProbeClusterCreated(); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& bwe_probe_cluster_created_events = parsed_log_.bwe_probe_cluster_created_events(); @@ -830,11 +860,12 @@ TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultFailure) { + std::unique_ptr encoder = CreateEncoder(); std::unique_ptr event = gen_.NewProbeResultFailure(); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& bwe_probe_failure_events = parsed_log_.bwe_probe_failure_events(); @@ -845,11 +876,12 @@ TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultFailure) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultSuccess) { + std::unique_ptr encoder = CreateEncoder(); std::unique_ptr event = gen_.NewProbeResultSuccess(); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& bwe_probe_success_events = parsed_log_.bwe_probe_success_events(); @@ -864,6 +896,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) { // As a work around, we're removing duplicates in the parser. return; } + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { @@ -873,7 +906,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& incoming_rtcp_packets = parsed_log_.incoming_rtcp_packets(); @@ -886,6 +919,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) { } TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketOutgoing) { + std::unique_ptr encoder = CreateEncoder(); std::vector> events(event_count_); for (size_t i = 0; i < event_count_; ++i) { events[i] = (i == 0 || !force_repeated_fields_) @@ -894,7 +928,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketOutgoing) { history_.push_back(events[i]->Copy()); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& outgoing_rtcp_packets = parsed_log_.outgoing_rtcp_packets(); @@ -914,6 +948,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpReceiverReport) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -931,7 +967,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpReceiverReport) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& receiver_reports = parsed_log_.receiver_reports(direction); @@ -952,6 +988,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpSenderReport) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -969,7 +1007,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpSenderReport) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& sender_reports = parsed_log_.sender_reports(direction); @@ -990,6 +1028,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpExtendedReports) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -1007,7 +1047,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpExtendedReports) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& extended_reports = parsed_log_.extended_reports(direction); @@ -1028,6 +1068,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpFir) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -1045,7 +1087,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpFir) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& firs = parsed_log_.firs(direction); @@ -1065,6 +1107,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPli) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -1082,7 +1126,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPli) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& plis = parsed_log_.plis(direction); @@ -1102,6 +1146,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpBye) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -1119,7 +1165,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpBye) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& byes = parsed_log_.byes(direction); @@ -1139,6 +1185,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpNack) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -1156,7 +1204,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpNack) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& nacks = parsed_log_.nacks(direction); @@ -1176,6 +1224,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpRemb) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events(event_count_); std::vector timestamps_ms(event_count_); @@ -1193,7 +1243,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpRemb) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& rembs = parsed_log_.rembs(direction); @@ -1213,6 +1263,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpTransportFeedback) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events; events.reserve(event_count_); @@ -1231,7 +1283,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpTransportFeedback) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& transport_feedbacks = @@ -1253,6 +1305,8 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpLossNotification) { rtc::ScopedFakeClock fake_clock; fake_clock.SetTime(Timestamp::Millis(prng_.Rand())); + std::unique_ptr encoder = CreateEncoder(); + for (auto direction : {kIncomingPacket, kOutgoingPacket}) { std::vector events; events.reserve(event_count_); @@ -1271,7 +1325,7 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpLossNotification) { fake_clock.AdvanceTime(TimeDelta::Millis(prng_.Rand(0, 1000))); } - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& loss_notifications = parsed_log_.loss_notifications(direction); @@ -1308,13 +1362,14 @@ TEST_P(RtcEventLogEncoderTest, // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) { + std::unique_ptr encoder = CreateEncoder(); uint32_t ssrc = prng_.Rand(); RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); std::unique_ptr event = gen_.NewVideoReceiveStreamConfig(ssrc, extensions); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& video_recv_configs = parsed_log_.video_recv_configs(); @@ -1324,13 +1379,14 @@ TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) { // TODO(eladalon/terelius): Test with multiple events in the batch. TEST_P(RtcEventLogEncoderTest, RtcEventVideoSendStreamConfig) { + std::unique_ptr encoder = CreateEncoder(); uint32_t ssrc = prng_.Rand(); RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap(); std::unique_ptr event = gen_.NewVideoSendStreamConfig(ssrc, extensions); history_.push_back(event->Copy()); - encoded_ += encoder_->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); const auto& video_send_configs = parsed_log_.video_send_configs(); @@ -1357,7 +1413,8 @@ class RtcEventLogEncoderSimpleTest encoder_ = std::make_unique(); break; case RtcEventLog::EncodingType::NewFormat: - encoder_ = std::make_unique(); + encoder_ = std::make_unique( + ExplicitKeyValueConfig("")); break; case RtcEventLog::EncodingType::ProtoFree: encoder_ = std::make_unique(); diff --git a/logging/rtc_event_log/rtc_event_log_impl.cc b/logging/rtc_event_log/rtc_event_log_impl.cc index 419afd330a..5cafe8a711 100644 --- a/logging/rtc_event_log/rtc_event_log_impl.cc +++ b/logging/rtc_event_log/rtc_event_log_impl.cc @@ -39,7 +39,7 @@ std::unique_ptr CreateEncoder(const Environment& env) { return std::make_unique(); } else { RTC_DLOG(LS_INFO) << "Creating new format encoder for RTC event log."; - return std::make_unique(); + return std::make_unique(env.field_trials()); } } From 9b7f3649af2137347b84d49f202ab5662967baed Mon Sep 17 00:00:00 2001 From: Henrik Lundin Date: Wed, 31 Jan 2024 13:15:00 +0000 Subject: [PATCH 049/170] Fix a fuzzer-found issue in PCM16 decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: chromium:1521761 Change-Id: Id5292e80fd6ecae2c39a446dec010b0383bd805e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337200 Reviewed-by: Jakob Ivarsson‎ Commit-Queue: Henrik Lundin Cr-Commit-Position: refs/heads/main@{#41645} --- modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc | 5 +++++ modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc index 7761efe8b3..1e2b5db331 100644 --- a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc +++ b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.cc @@ -67,4 +67,9 @@ int AudioDecoderPcm16B::PacketDuration(const uint8_t* encoded, return static_cast(encoded_len / (2 * Channels())); } +int AudioDecoderPcm16B::PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const { + return PacketDuration(encoded, encoded_len); +} + } // namespace webrtc diff --git a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h index 6f50161d3f..c31cc5d0a2 100644 --- a/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h +++ b/modules/audio_coding/codecs/pcm16b/audio_decoder_pcm16b.h @@ -32,6 +32,8 @@ class AudioDecoderPcm16B final : public AudioDecoder { std::vector ParsePayload(rtc::Buffer&& payload, uint32_t timestamp) override; int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override; + int PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const override; int SampleRateHz() const override; size_t Channels() const override; From 26ad5b82ce6b6feae7fe92bc549e8f4730edf436 Mon Sep 17 00:00:00 2001 From: Henrik Lundin Date: Wed, 31 Jan 2024 15:02:55 +0000 Subject: [PATCH 050/170] Fix a fuzzer-found issue in PCM/G.711 decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: chromium:1521415 Change-Id: Ia955b59ee40c57bdbbb2a32fa1bf80475df8c743 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337201 Auto-Submit: Henrik Lundin Commit-Queue: Jakob Ivarsson‎ Reviewed-by: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41646} --- modules/audio_coding/codecs/g711/audio_decoder_pcm.cc | 10 ++++++++++ modules/audio_coding/codecs/g711/audio_decoder_pcm.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc b/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc index 46ac671b30..ff7e919d9b 100644 --- a/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc +++ b/modules/audio_coding/codecs/g711/audio_decoder_pcm.cc @@ -58,6 +58,11 @@ int AudioDecoderPcmU::PacketDuration(const uint8_t* encoded, return static_cast(encoded_len / Channels()); } +int AudioDecoderPcmU::PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const { + return PacketDuration(encoded, encoded_len); +} + void AudioDecoderPcmA::Reset() {} std::vector AudioDecoderPcmA::ParsePayload( @@ -99,4 +104,9 @@ int AudioDecoderPcmA::PacketDuration(const uint8_t* encoded, return static_cast(encoded_len / Channels()); } +int AudioDecoderPcmA::PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const { + return PacketDuration(encoded, encoded_len); +} + } // namespace webrtc diff --git a/modules/audio_coding/codecs/g711/audio_decoder_pcm.h b/modules/audio_coding/codecs/g711/audio_decoder_pcm.h index 3fa42cba30..5531d6e7f0 100644 --- a/modules/audio_coding/codecs/g711/audio_decoder_pcm.h +++ b/modules/audio_coding/codecs/g711/audio_decoder_pcm.h @@ -35,6 +35,8 @@ class AudioDecoderPcmU final : public AudioDecoder { std::vector ParsePayload(rtc::Buffer&& payload, uint32_t timestamp) override; int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override; + int PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const override; int SampleRateHz() const override; size_t Channels() const override; @@ -62,6 +64,8 @@ class AudioDecoderPcmA final : public AudioDecoder { std::vector ParsePayload(rtc::Buffer&& payload, uint32_t timestamp) override; int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override; + int PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const override; int SampleRateHz() const override; size_t Channels() const override; From 1d3e286c7f3b8ad7cc492c4914756af59262a39b Mon Sep 17 00:00:00 2001 From: Henrik Lundin Date: Wed, 31 Jan 2024 15:22:13 +0000 Subject: [PATCH 051/170] Fix a fuzzer-found issue in G.722 decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: chromium:1521407 Change-Id: I913108232f195856a9e2693dc1350ec0937fa923 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337182 Reviewed-by: Jakob Ivarsson‎ Auto-Submit: Henrik Lundin Commit-Queue: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41647} --- modules/audio_coding/codecs/g722/audio_decoder_g722.cc | 5 +++++ modules/audio_coding/codecs/g722/audio_decoder_g722.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/modules/audio_coding/codecs/g722/audio_decoder_g722.cc b/modules/audio_coding/codecs/g722/audio_decoder_g722.cc index e969ed1189..bca47cea13 100644 --- a/modules/audio_coding/codecs/g722/audio_decoder_g722.cc +++ b/modules/audio_coding/codecs/g722/audio_decoder_g722.cc @@ -63,6 +63,11 @@ int AudioDecoderG722Impl::PacketDuration(const uint8_t* encoded, return static_cast(2 * encoded_len / Channels()); } +int AudioDecoderG722Impl::PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const { + return PacketDuration(encoded, encoded_len); +} + int AudioDecoderG722Impl::SampleRateHz() const { return 16000; } diff --git a/modules/audio_coding/codecs/g722/audio_decoder_g722.h b/modules/audio_coding/codecs/g722/audio_decoder_g722.h index 5872fad5de..e7083c3fd6 100644 --- a/modules/audio_coding/codecs/g722/audio_decoder_g722.h +++ b/modules/audio_coding/codecs/g722/audio_decoder_g722.h @@ -30,6 +30,8 @@ class AudioDecoderG722Impl final : public AudioDecoder { std::vector ParsePayload(rtc::Buffer&& payload, uint32_t timestamp) override; int PacketDuration(const uint8_t* encoded, size_t encoded_len) const override; + int PacketDurationRedundant(const uint8_t* encoded, + size_t encoded_len) const override; int SampleRateHz() const override; size_t Channels() const override; From 4860148c51cb673711a41bc26135659ad4e6cb9d Mon Sep 17 00:00:00 2001 From: Dan Tan Date: Wed, 31 Jan 2024 09:11:18 -0800 Subject: [PATCH 052/170] Add WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop parameter to explicitly limit the maximum consecutive frame drop Bug: webrtc:15821 Change-Id: Ib8be6827ea57e4e54269b94a0fc9ea81945af09f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337020 Reviewed-by: Marco Paniconi Commit-Queue: Dan Tan Reviewed-by: Sergey Silkin Cr-Commit-Position: refs/heads/main@{#41648} --- experiments/field_trials.py | 3 +++ .../codecs/av1/libaom_av1_encoder.cc | 18 ++++++++++++- .../codecs/av1/libaom_av1_encoder_unittest.cc | 25 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/experiments/field_trials.py b/experiments/field_trials.py index dff1ad1982..32ab6bf351 100755 --- a/experiments/field_trials.py +++ b/experiments/field_trials.py @@ -89,6 +89,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-LibaomAv1Encoder-DisableFrameDropping', 'webrtc:15225', date(2024, 4, 1)), + FieldTrial('WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop', + 'webrtc:15821', + date(2024, 4, 1)), FieldTrial('WebRTC-Pacer-FastRetransmissions', 'chromium:1354491', date(2024, 4, 1)), diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index 4ff22bfe34..03bb367fe0 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -133,6 +133,7 @@ class LibaomAv1Encoder final : public VideoEncoder { // TODO(webrtc:15225): Kill switch for disabling frame dropping. Remove it // after frame dropping is fully rolled out. bool disable_frame_dropping_; + int max_consec_frame_drop_; }; int32_t VerifyCodecSettings(const VideoCodec& codec_settings) { @@ -163,6 +164,14 @@ int32_t VerifyCodecSettings(const VideoCodec& codec_settings) { return WEBRTC_VIDEO_CODEC_OK; } +int GetMaxConsecutiveFrameDrop(const FieldTrialsView& field_trials) { + webrtc::FieldTrialParameter maxdrop("maxdrop", 0); + webrtc::ParseFieldTrial( + {&maxdrop}, + field_trials.Lookup("WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop")); + return maxdrop; +} + LibaomAv1Encoder::LibaomAv1Encoder( const absl::optional& aux_config, const FieldTrialsView& trials) @@ -174,7 +183,8 @@ LibaomAv1Encoder::LibaomAv1Encoder( timestamp_(0), disable_frame_dropping_(absl::StartsWith( trials.Lookup("WebRTC-LibaomAv1Encoder-DisableFrameDropping"), - "Enabled")) {} + "Enabled")), + max_consec_frame_drop_(GetMaxConsecutiveFrameDrop(trials)) {} LibaomAv1Encoder::~LibaomAv1Encoder() { Release(); @@ -297,6 +307,12 @@ int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings, SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_ENABLE_PALETTE, 0); } + if (codec_settings->mode == VideoCodecMode::kRealtimeVideo && + encoder_settings_.GetFrameDropEnabled() && max_consec_frame_drop_ > 0) { + SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_MAX_CONSEC_FRAME_DROP_CBR, + max_consec_frame_drop_); + } + if (cfg_.g_threads == 8) { // Values passed to AV1E_SET_TILE_ROWS and AV1E_SET_TILE_COLUMNS are log2() // based. diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc index 04ee9162ba..127aadb275 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc @@ -188,6 +188,31 @@ TEST(LibaomAv1EncoderTest, CheckOddDimensionsWithSpatialLayers) { ASSERT_THAT(encoded_frames, SizeIs(6)); } +TEST(LibaomAv1EncoderTest, WithMaximumConsecutiveFrameDrop) { + test::ScopedFieldTrials field_trials( + "WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop/maxdrop:2/"); + VideoBitrateAllocation allocation; + allocation.SetBitrate(0, 0, 1000); // some very low bitrate + std::unique_ptr encoder = CreateLibaomAv1Encoder(); + VideoCodec codec_settings = DefaultCodecSettings(); + codec_settings.SetFrameDropEnabled(true); + codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1); + codec_settings.startBitrate = allocation.get_sum_kbps(); + ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()), + WEBRTC_VIDEO_CODEC_OK); + encoder->SetRates(VideoEncoder::RateControlParameters( + allocation, codec_settings.maxFramerate)); + EncodedVideoFrameProducer evfp(*encoder); + evfp.SetResolution( + RenderResolution{codec_settings.width, codec_settings.height}); + // We should code the first frame, skip two, then code another frame. + std::vector encoded_frames = + evfp.SetNumInputFrames(4).Encode(); + ASSERT_THAT(encoded_frames, SizeIs(2)); + // The 4 frames have default Rtp-timestamps of 1000, 4000, 7000, 10000. + ASSERT_THAT(encoded_frames[1].encoded_image.RtpTimestamp(), 10000); +} + TEST(LibaomAv1EncoderTest, EncoderInfoWithoutResolutionBitrateLimits) { std::unique_ptr encoder = CreateLibaomAv1Encoder(); EXPECT_TRUE(encoder->GetEncoderInfo().resolution_bitrate_limits.empty()); From 27a452da21893a06fe6a08ac2ff0b24ef6016d41 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Wed, 31 Jan 2024 11:54:24 +0000 Subject: [PATCH 053/170] Rewrite webrtc_sdp unittest to use DTLS not SDES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for removing SDES support. Bug: webrtc:11066 Change-Id: Ia89f8003cf1869c94baf429e9b2905235bd09a22 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337180 Reviewed-by: Henrik Boström Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41649} --- pc/webrtc_sdp_unittest.cc | 251 ++++++++++++++++---------------------- 1 file changed, 106 insertions(+), 145 deletions(-) diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc index eb9bc729c6..0238c97aa0 100644 --- a/pc/webrtc_sdp_unittest.cc +++ b/pc/webrtc_sdp_unittest.cc @@ -102,13 +102,6 @@ static const char kCandidateFoundation1[] = "a0+B/1"; static const char kCandidateFoundation2[] = "a0+B/2"; static const char kCandidateFoundation3[] = "a0+B/3"; static const char kCandidateFoundation4[] = "a0+B/4"; -static const char kAttributeCryptoVoice[] = - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n"; -static const char kAttributeCryptoVideo[] = - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n"; static const char kFingerprint[] = "a=fingerprint:sha-1 " "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n"; @@ -141,10 +134,6 @@ struct CodecParams { int maxaveragebitrate; }; -// TODO(deadbeef): In these reference strings, use "a=fingerprint" by default -// instead of "a=crypto", and have an explicit test for adding "a=crypto". -// Currently it's the other way around. - // Reference sdp string static const char kSdpFullString[] = "v=0\r\n" @@ -171,14 +160,13 @@ static const char kSdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -199,11 +187,11 @@ static const char kSdpFullString[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" "a=mid:video_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -221,14 +209,14 @@ static const char kSdpString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -237,11 +225,12 @@ static const char kSdpString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -253,6 +242,9 @@ static const char kSdpSctpDataChannelString[] = "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n" "a=sctpmap:5000 webrtc-datachannel 1024\r\n"; @@ -265,6 +257,9 @@ static const char kSdpSctpDataChannelStringWithSctpPort[] = "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n"; // draft-ietf-mmusic-sctp-sdp-26 @@ -274,6 +269,9 @@ static const char kSdpSctpDataChannelStringWithSctpColonPort[] = "c=IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n"; static const char kSdpSctpDataChannelWithCandidatesString[] = @@ -288,6 +286,9 @@ static const char kSdpSctpDataChannelWithCandidatesString[] = "generation 2\r\n" "a=ice-ufrag:ufrag_data\r\n" "a=ice-pwd:pwd_data\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:data_content_name\r\n" "a=sctpmap:5000 webrtc-datachannel 1024\r\n"; @@ -316,6 +317,9 @@ static const char kSdpAudioString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=rtpmap:111 opus/48000/2\r\n" @@ -327,6 +331,9 @@ static const char kSdpVideoString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=sendrecv\r\n" "a=rtpmap:120 VP8/90000\r\n" @@ -360,14 +367,14 @@ static const char kBundleOnlySdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -379,9 +386,9 @@ static const char kBundleOnlySdpFullString[] = "a=mid:video_content_name\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" "a=ssrc:3 cname:stream_1_cname\r\n"; @@ -413,13 +420,13 @@ static const char kPlanBSdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -443,10 +450,11 @@ static const char kPlanBSdpFullString[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -486,14 +494,14 @@ static const char kUnifiedPlanSdpFullString[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -515,11 +523,12 @@ static const char kUnifiedPlanSdpFullString[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc-group:FEC 2 3\r\n" "a=ssrc:2 cname:stream_1_cname\r\n" @@ -529,14 +538,14 @@ static const char kUnifiedPlanSdpFullString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice_2\r\na=ice-pwd:pwd_voice_2\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name_2\r\n" "a=msid:local_stream_2 audio_track_id_2\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -546,11 +555,12 @@ static const char kUnifiedPlanSdpFullString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video_2\r\na=ice-pwd:pwd_video_2\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name_2\r\n" "a=msid:local_stream_2 video_track_id_2\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc:5 cname:stream_2_cname\r\n" // Video track 3, stream 2. @@ -558,11 +568,12 @@ static const char kUnifiedPlanSdpFullString[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_video_3\r\na=ice-pwd:pwd_video_3\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name_3\r\n" "a=msid:local_stream_2 video_track_id_3\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" "a=ssrc:6 cname:stream_2_cname\r\n"; @@ -599,14 +610,14 @@ static const char kUnifiedPlanSdpFullStringWithSpecialMsid[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -617,15 +628,15 @@ static const char kUnifiedPlanSdpFullStringWithSpecialMsid[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice_2\r\na=ice-pwd:pwd_voice_2\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name_2\r\n" "a=sendrecv\r\n" "a=msid:local_stream_1 audio_track_id_2\r\n" "a=msid:local_stream_2 audio_track_id_2\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -638,14 +649,14 @@ static const char kUnifiedPlanSdpFullStringWithSpecialMsid[] = "c=IN IP4 0.0.0.0\r\n" "a=rtcp:9 IN IP4 0.0.0.0\r\n" "a=ice-ufrag:ufrag_voice_3\r\na=ice-pwd:pwd_voice_3\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name_3\r\n" "a=sendrecv\r\n" "a=msid:- audio_track_id_3\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -678,14 +689,14 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "raddr 192.168.1.5 rport 2348 " "generation 2\r\n" "a=ice-ufrag:ufrag_voice\r\na=ice-pwd:pwd_voice\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:audio_content_name\r\n" "a=msid:local_stream_1 audio_track_id_1\r\n" "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -706,11 +717,12 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=candidate:a0+B/4 1 udp 2130706432 74.125.224.39 3457 typ relay " "generation 2\r\n" "a=ice-ufrag:ufrag_video\r\na=ice-pwd:pwd_video\r\n" + "a=fingerprint:sha-1 " + "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" + "a=mid:video_content_name\r\n" "a=msid:local_stream_1 video_track_id_1\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" // Audio track 2, stream 2. "m=audio 9 RTP/SAVPF 111 103 104\r\n" @@ -722,9 +734,6 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=sendrecv\r\n" "a=rtcp-mux\r\n" "a=rtcp-rsize\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_32 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n" "a=rtpmap:111 opus/48000/2\r\n" "a=rtpmap:103 ISAC/16000\r\n" "a=rtpmap:104 ISAC/32000\r\n" @@ -736,8 +745,6 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=mid:video_content_name_2\r\n" "a=msid:local_stream_2 video_track_id_2\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n" // Video track 3, stream 2. "m=video 9 RTP/SAVPF 120\r\n" @@ -747,8 +754,6 @@ static const char kUnifiedPlanSdpFullStringNoSsrc[] = "a=mid:video_content_name_3\r\n" "a=msid:local_stream_2 video_track_id_3\r\n" "a=sendrecv\r\n" - "a=crypto:1 AES_CM_128_HMAC_SHA1_80 " - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32\r\n" "a=rtpmap:120 VP8/90000\r\n"; // One candidate reference string as per W3c spec. @@ -945,6 +950,14 @@ static void ReplaceRejected(bool audio_rejected, } } +static TransportDescription MakeTransportDescription(std::string ufrag, + std::string pwd) { + rtc::SSLFingerprint fingerprint(rtc::DIGEST_SHA_1, kIdentityDigest); + return TransportDescription(std::vector(), ufrag, pwd, + cricket::ICEMODE_FULL, + cricket::CONNECTIONROLE_NONE, &fingerprint); +} + // WebRtcSdpTest class WebRtcSdpTest : public ::testing::Test { @@ -982,11 +995,12 @@ class WebRtcSdpTest : public ::testing::Test { desc_.AddContent(kVideoContentName, MediaProtocolType::kRtp, absl::WrapUnique(video_desc_)); - // TransportInfo + // TransportInfo, with fingerprint + rtc::SSLFingerprint fingerprint(rtc::DIGEST_SHA_1, kIdentityDigest); desc_.AddTransportInfo(TransportInfo( - kAudioContentName, TransportDescription(kUfragVoice, kPwdVoice))); + kAudioContentName, MakeTransportDescription(kUfragVoice, kPwdVoice))); desc_.AddTransportInfo(TransportInfo( - kVideoContentName, TransportDescription(kUfragVideo, kPwdVideo))); + kVideoContentName, MakeTransportDescription(kUfragVideo, kPwdVideo))); // v4 host int port = 1234; @@ -1186,8 +1200,9 @@ class WebRtcSdpTest : public ::testing::Test { audio_desc_2->AddStream(audio_track_2); desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp, absl::WrapUnique(audio_desc_2)); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName2, TransportDescription(kUfragVoice2, kPwdVoice2))); + desc_.AddTransportInfo( + TransportInfo(kAudioContentName2, + MakeTransportDescription(kUfragVoice2, kPwdVoice2))); // Video track 2, in stream 2. VideoContentDescription* video_desc_2 = CreateVideoContentDescription(); StreamParams video_track_2; @@ -1200,8 +1215,9 @@ class WebRtcSdpTest : public ::testing::Test { video_desc_2->AddStream(video_track_2); desc_.AddContent(kVideoContentName2, MediaProtocolType::kRtp, absl::WrapUnique(video_desc_2)); - desc_.AddTransportInfo(TransportInfo( - kVideoContentName2, TransportDescription(kUfragVideo2, kPwdVideo2))); + desc_.AddTransportInfo( + TransportInfo(kVideoContentName2, + MakeTransportDescription(kUfragVideo2, kPwdVideo2))); // Video track 3, in stream 2. VideoContentDescription* video_desc_3 = CreateVideoContentDescription(); @@ -1215,8 +1231,9 @@ class WebRtcSdpTest : public ::testing::Test { video_desc_3->AddStream(video_track_3); desc_.AddContent(kVideoContentName3, MediaProtocolType::kRtp, absl::WrapUnique(video_desc_3)); - desc_.AddTransportInfo(TransportInfo( - kVideoContentName3, TransportDescription(kUfragVideo3, kPwdVideo3))); + desc_.AddTransportInfo( + TransportInfo(kVideoContentName3, + MakeTransportDescription(kUfragVideo3, kPwdVideo3))); desc_.set_msid_signaling(cricket::kMsidSignalingMediaSection | cricket::kMsidSignalingSemantic); @@ -1230,10 +1247,6 @@ class WebRtcSdpTest : public ::testing::Test { AudioContentDescription* audio = new AudioContentDescription(); audio->set_rtcp_mux(true); audio->set_rtcp_reduced_size(true); - audio->AddCrypto(CryptoParams( - 1, "AES_CM_128_HMAC_SHA1_32", - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32", - "dummy_session_params")); audio->set_protocol(cricket::kMediaProtocolSavpf); audio->AddCodec(cricket::CreateAudioCodec(111, "opus", 48000, 2)); audio->AddCodec(cricket::CreateAudioCodec(103, "ISAC", 16000, 1)); @@ -1260,8 +1273,9 @@ class WebRtcSdpTest : public ::testing::Test { audio_desc_2->AddStream(audio_track_2); desc_.AddContent(kAudioContentName2, MediaProtocolType::kRtp, absl::WrapUnique(audio_desc_2)); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName2, TransportDescription(kUfragVoice2, kPwdVoice2))); + desc_.AddTransportInfo( + TransportInfo(kAudioContentName2, + MakeTransportDescription(kUfragVoice2, kPwdVoice2))); // Audio track 3 has no stream ids. AudioContentDescription* audio_desc_3 = CreateAudioContentDescription(); @@ -1273,8 +1287,9 @@ class WebRtcSdpTest : public ::testing::Test { audio_desc_3->AddStream(audio_track_3); desc_.AddContent(kAudioContentName3, MediaProtocolType::kRtp, absl::WrapUnique(audio_desc_3)); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName3, TransportDescription(kUfragVoice3, kPwdVoice3))); + desc_.AddTransportInfo( + TransportInfo(kAudioContentName3, + MakeTransportDescription(kUfragVoice3, kPwdVoice3))); desc_.set_msid_signaling(msid_signaling); ASSERT_TRUE(jdesc_.Initialize(desc_.Clone(), jdesc_.session_id(), jdesc_.session_version())); @@ -1308,9 +1323,6 @@ class WebRtcSdpTest : public ::testing::Test { // configuration. VideoContentDescription* CreateVideoContentDescription() { VideoContentDescription* video = new VideoContentDescription(); - video->AddCrypto(CryptoParams( - 1, "AES_CM_128_HMAC_SHA1_80", - "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32", "")); video->set_protocol(cricket::kMediaProtocolSavpf); video->AddCodec(cricket::CreateVideoCodec(120, "VP8")); return video; @@ -1497,8 +1509,14 @@ class WebRtcSdpTest : public ::testing::Test { EXPECT_EQ(transport1.description.ice_mode, transport2.description.ice_mode); if (transport1.description.identity_fingerprint) { - EXPECT_EQ(*transport1.description.identity_fingerprint, - *transport2.description.identity_fingerprint); + if (!transport2.description.identity_fingerprint) { + ADD_FAILURE() << "transport[" << i + << "]: left transport has fingerprint, right transport " + "does not have it"; + } else { + EXPECT_EQ(*transport1.description.identity_fingerprint, + *transport2.description.identity_fingerprint); + } } else { EXPECT_EQ(transport1.description.identity_fingerprint.get(), transport2.description.identity_fingerprint.get()); @@ -1559,7 +1577,7 @@ class WebRtcSdpTest : public ::testing::Test { RTC_DCHECK_NOTREACHED(); } TransportInfo transport_info(content_name, - TransportDescription(ufrag, pwd)); + MakeTransportDescription(ufrag, pwd)); SessionDescription* desc = const_cast(jdesc->description()); desc->RemoveTransportInfoByName(content_name); @@ -1598,22 +1616,6 @@ class WebRtcSdpTest : public ::testing::Test { desc_.AddTransportInfo(transport_info); } - void AddFingerprint() { - desc_.RemoveTransportInfoByName(kAudioContentName); - desc_.RemoveTransportInfoByName(kVideoContentName); - rtc::SSLFingerprint fingerprint(rtc::DIGEST_SHA_1, kIdentityDigest); - desc_.AddTransportInfo(TransportInfo( - kAudioContentName, - TransportDescription(std::vector(), kUfragVoice, kPwdVoice, - cricket::ICEMODE_FULL, - cricket::CONNECTIONROLE_NONE, &fingerprint))); - desc_.AddTransportInfo(TransportInfo( - kVideoContentName, - TransportDescription(std::vector(), kUfragVideo, kPwdVideo, - cricket::ICEMODE_FULL, - cricket::CONNECTIONROLE_NONE, &fingerprint))); - } - void AddExtmap(bool encrypted) { audio_desc_ = new AudioContentDescription(*audio_desc_); video_desc_ = new VideoContentDescription(*video_desc_); @@ -1730,7 +1732,7 @@ class WebRtcSdpTest : public ::testing::Test { desc_.AddContent(kDataContentName, MediaProtocolType::kSctp, std::move(data)); desc_.AddTransportInfo(TransportInfo( - kDataContentName, TransportDescription(kUfragData, kPwdData))); + kDataContentName, MakeTransportDescription(kUfragData, kPwdData))); } bool TestDeserializeDirection(RtpTransceiverDirection direction) { @@ -2035,39 +2037,6 @@ TEST_F(WebRtcSdpTest, SerializeSessionDescriptionEmpty) { EXPECT_EQ("", webrtc::SdpSerialize(jdesc_empty)); } -// This tests serialization of SDP with a=crypto and a=fingerprint, as would be -// the case in a DTLS offer. -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprint) { - AddFingerprint(); - JsepSessionDescription jdesc_with_fingerprint(kDummyType); - MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint); - std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint); - - std::string sdp_with_fingerprint = kSdpString; - InjectAfter(kAttributeIcePwdVoice, kFingerprint, &sdp_with_fingerprint); - InjectAfter(kAttributeIcePwdVideo, kFingerprint, &sdp_with_fingerprint); - - EXPECT_EQ(sdp_with_fingerprint, message); -} - -// This tests serialization of SDP with a=fingerprint with no a=crypto, as would -// be the case in a DTLS answer. -TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithFingerprintNoCryptos) { - AddFingerprint(); - RemoveCryptos(); - JsepSessionDescription jdesc_with_fingerprint(kDummyType); - MakeDescriptionWithoutCandidates(&jdesc_with_fingerprint); - std::string message = webrtc::SdpSerialize(jdesc_with_fingerprint); - - std::string sdp_with_fingerprint = kSdpString; - Replace(kAttributeCryptoVoice, "", &sdp_with_fingerprint); - Replace(kAttributeCryptoVideo, "", &sdp_with_fingerprint); - InjectAfter(kAttributeIcePwdVoice, kFingerprint, &sdp_with_fingerprint); - InjectAfter(kAttributeIcePwdVideo, kFingerprint, &sdp_with_fingerprint); - - EXPECT_EQ(sdp_with_fingerprint, message); -} - TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithoutCandidates) { // JsepSessionDescription with desc but without candidates. JsepSessionDescription jdesc_no_candidates(kDummyType); @@ -2461,8 +2430,6 @@ TEST_F(WebRtcSdpTest, DeserializeSessionDescriptionWithoutRtpmapButWithFmtp) { // Ensure that we can deserialize SDP with a=fingerprint properly. TEST_F(WebRtcSdpTest, DeserializeJsepSessionDescriptionWithFingerprint) { - // Add a DTLS a=fingerprint attribute to our session description. - AddFingerprint(); JsepSessionDescription new_jdesc(kDummyType); ASSERT_TRUE(new_jdesc.Initialize(desc_.Clone(), jdesc_.session_id(), jdesc_.session_version())); @@ -3177,8 +3144,6 @@ TEST_F(WebRtcSdpTest, DeserializeSdpWithInvalidAttributeValue) { // ssrc ExpectParseFailure("a=ssrc:1", "a=ssrc:badvalue"); ExpectParseFailure("a=ssrc-group:FEC 2 3", "a=ssrc-group:FEC badvalue 3"); - // crypto - ExpectParseFailure("a=crypto:1 ", "a=crypto:badvalue "); // rtpmap ExpectParseFailure("a=rtpmap:111 ", "a=rtpmap:badvalue "); ExpectParseFailure("opus/48000/2", "opus/badvalue/2"); @@ -3564,7 +3529,6 @@ TEST_F(WebRtcSdpTest, RoundTripSdpWithSctpDataChannelsWithCandidates) { } TEST_F(WebRtcSdpTest, SerializeDtlsSetupAttribute) { - AddFingerprint(); TransportInfo audio_transport_info = *(desc_.GetTransportInfoByName(kAudioContentName)); EXPECT_EQ(cricket::CONNECTIONROLE_NONE, @@ -3590,9 +3554,6 @@ TEST_F(WebRtcSdpTest, SerializeDtlsSetupAttribute) { std::string message = webrtc::SdpSerialize(jdesc_); std::string sdp_with_dtlssetup = kSdpFullString; - // Fingerprint attribute is necessary to add DTLS setup attribute. - InjectAfter(kAttributeIcePwdVoice, kFingerprint, &sdp_with_dtlssetup); - InjectAfter(kAttributeIcePwdVideo, kFingerprint, &sdp_with_dtlssetup); // Now adding `setup` attribute. InjectAfter(kFingerprint, "a=setup:active\r\n", &sdp_with_dtlssetup); EXPECT_EQ(sdp_with_dtlssetup, message); From 657b65fa188fbb2ddd18307e55af4847e44c0e0f Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Mon, 29 Jan 2024 09:50:01 +0100 Subject: [PATCH 054/170] Remove special-casing of TWCCv2 negotiation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit since it can be enabled locally using the RTP header extensions API Bug: webrtc:15057 Change-Id: Id15d26ab858d88769939974f2a7ae4327df925b7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336720 Reviewed-by: Harald Alvestrand Reviewed-by: Johannes Kron Commit-Queue: Philipp Hancke Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/main@{#41650} --- pc/media_session.cc | 30 ++----------------- pc/media_session_unittest.cc | 56 +++++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/pc/media_session.cc b/pc/media_session.cc index a118beebb0..f146562b37 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -1254,17 +1254,6 @@ void NegotiateRtpHeaderExtensions(const RtpHeaderExtensions& local_extensions, const RtpHeaderExtensions& offered_extensions, webrtc::RtpExtension::Filter filter, RtpHeaderExtensions* negotiated_extensions) { - // TransportSequenceNumberV2 is not offered by default. The special logic for - // the TransportSequenceNumber extensions works as follows: - // Offer Answer - // V1 V1 if in local_extensions. - // V1 and V2 V2 regardless of local_extensions. - // V2 V2 regardless of local_extensions. - const webrtc::RtpExtension* transport_sequence_number_v2_offer = - FindHeaderExtensionByUriDiscardUnsupported( - offered_extensions, - webrtc::RtpExtension::kTransportSequenceNumberV2Uri, filter); - bool frame_descriptor_in_local = false; bool dependency_descriptor_in_local = false; bool abs_capture_time_in_local = false; @@ -1276,29 +1265,16 @@ void NegotiateRtpHeaderExtensions(const RtpHeaderExtensions& local_extensions, dependency_descriptor_in_local = true; else if (ours.uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri) abs_capture_time_in_local = true; + const webrtc::RtpExtension* theirs = FindHeaderExtensionByUriDiscardUnsupported(offered_extensions, ours.uri, filter); if (theirs) { - if (transport_sequence_number_v2_offer && - ours.uri == webrtc::RtpExtension::kTransportSequenceNumberUri) { - // Don't respond to - // http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 - // if we get an offer including - // http://www.webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02 - continue; - } else { - // We respond with their RTP header extension id. - negotiated_extensions->push_back(*theirs); - } + // We respond with their RTP header extension id. + negotiated_extensions->push_back(*theirs); } } - if (transport_sequence_number_v2_offer) { - // Respond that we support kTransportSequenceNumberV2Uri. - negotiated_extensions->push_back(*transport_sequence_number_v2_offer); - } - // Frame descriptors support. If the extension is not present locally, but is // in the offer, we add it to the list. if (!dependency_descriptor_in_local) { diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc index f4fd09cba0..ecfb4397bb 100644 --- a/pc/media_session_unittest.cc +++ b/pc/media_session_unittest.cc @@ -1731,30 +1731,72 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestOfferAnswerWithRtpExtensions) { } // Create a audio/video offer and answer and ensure that the -// TransportSequenceNumber RTP header extensions are handled correctly. 02 is -// supported and should take precedence even though not listed among locally -// supported extensions. +// TransportSequenceNumber RTP v1 and v2 header extensions are handled +// correctly. TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferAnswerWithTransportSequenceNumberInOffer) { + TestOfferAnswerWithTransportSequenceNumberV1LocalAndV1InOffer) { TestTransportSequenceNumberNegotiation( MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Offer. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01)); // Expected answer. } TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferAnswerWithTransportSequenceNumber01And02InOffer) { + TestOfferAnswerWithTransportSequenceNumberV1LocalAndV1V2InOffer) { TestTransportSequenceNumberNegotiation( MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Offer. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01)); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1LocalAndV2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Offer. + {}); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV2LocalAndV1InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Offer. + {}); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV2LocalAndV1V2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Offer. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02)); // Expected answer. } TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferAnswerWithTransportSequenceNumber02InOffer) { + TestOfferAnswerWithTransportSequenceNumberV2LocalAndV2InOffer) { TestTransportSequenceNumberNegotiation( - MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Local. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Offer. MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02)); // Expected answer. } +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1V2LocalAndV1InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01), // Offer. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01)); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1V2LocalAndV2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02), // Offer. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber02)); // Expected answer. +} +TEST_F(MediaSessionDescriptionFactoryTest, + TestOfferAnswerWithTransportSequenceNumberV1V2LocalAndV1V2InOffer) { + TestTransportSequenceNumberNegotiation( + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Local. + MAKE_VECTOR(kRtpExtensionTransportSequenceNumber01And02), // Offer. + MAKE_VECTOR( + kRtpExtensionTransportSequenceNumber01And02)); // Expected answer. +} TEST_F(MediaSessionDescriptionFactoryTest, TestNegotiateFrameDescriptorWhenUnexposedLocally) { From d071dc17257d4ad9f387f73305b3bf219323533f Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Wed, 31 Jan 2024 17:05:15 +0100 Subject: [PATCH 055/170] Bypass global field trial string in RtcEventLog unittests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass explicit field trials for object under test, Bypass field trial altogether for setting expectations Bug: webrtc:10335 Change-Id: Id17d70aa2c650bd9a00f4bca0035f37b3b415b76 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337183 Commit-Queue: Danil Chapovalov Reviewed-by: Björn Terelius Cr-Commit-Position: refs/heads/main@{#41651} --- logging/BUILD.gn | 4 +-- .../encoder/rtc_event_log_encoder_unittest.cc | 34 +++++++++++-------- .../rtc_event_log_unittest_helper.cc | 27 ++++++--------- .../rtc_event_log_unittest_helper.h | 10 ++++++ 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/logging/BUILD.gn b/logging/BUILD.gn index 5b91a39357..415c52789c 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -609,6 +609,7 @@ if (rtc_enable_protobuf) { ":rtc_event_video", ":rtc_stream_config", "../api:array_view", + "../api:field_trials_view", "../api:network_state_predictor_api", "../api:rtc_event_log_output_file", "../api:rtp_headers", @@ -617,7 +618,6 @@ if (rtc_enable_protobuf) { "../api/environment:environment_factory", "../api/rtc_event_log", "../api/rtc_event_log:rtc_event_log_factory", - "../api/transport:field_trial_based_config", "../api/units:time_delta", "../api/units:timestamp", "../call", @@ -631,9 +631,7 @@ if (rtc_enable_protobuf) { "../rtc_base:rtc_base_tests_utils", "../rtc_base:timeutils", "../system_wrappers", - "../system_wrappers:field_trial", "../test:explicit_key_value_config", - "../test:field_trial", "../test:fileutils", "../test:test_support", "../test/logging:log_writer", diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc index 73ff67e8b9..72611db8ce 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_unittest.cc @@ -14,7 +14,7 @@ #include #include -#include "api/transport/field_trial_based_config.h" +#include "api/field_trials_view.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.h" #include "logging/rtc_event_log/encoder/rtc_event_log_encoder_v3.h" @@ -42,7 +42,6 @@ #include "rtc_base/fake_clock.h" #include "rtc_base/random.h" #include "test/explicit_key_value_config.h" -#include "test/field_trial.h" #include "test/gtest.h" namespace webrtc { @@ -63,15 +62,15 @@ class RtcEventLogEncoderTest verifier_(encoding_type_) {} ~RtcEventLogEncoderTest() override = default; - std::unique_ptr CreateEncoder() { + std::unique_ptr CreateEncoder( + const FieldTrialsView& field_trials = ExplicitKeyValueConfig("")) { std::unique_ptr encoder; switch (encoding_type_) { case RtcEventLog::EncodingType::Legacy: encoder = std::make_unique(); break; case RtcEventLog::EncodingType::NewFormat: - encoder = std::make_unique( - FieldTrialBasedConfig()); + encoder = std::make_unique(field_trials); break; case RtcEventLog::EncodingType::ProtoFree: encoder = std::make_unique(); @@ -98,7 +97,7 @@ class RtcEventLogEncoderTest uint32_t ssrc); template - void TestRtpPackets(); + void TestRtpPackets(RtcEventLogEncoder& encoder); std::deque> history_; ParsedRtcEventLog parsed_log_; @@ -174,14 +173,13 @@ RtcEventLogEncoderTest::GetRtpPacketsBySsrc(const ParsedRtcEventLog* parsed_log, } template -void RtcEventLogEncoderTest::TestRtpPackets() { +void RtcEventLogEncoderTest::TestRtpPackets(RtcEventLogEncoder& encoder) { // SSRCs will be randomly assigned out of this small pool, significant only // in that it also covers such edge cases as SSRC = 0 and SSRC = 0xffffffff. // The pool is intentionally small, so as to produce collisions. const std::vector kSsrcPool = {0x00000000, 0x12345678, 0xabcdef01, 0xffffffff, 0x20171024, 0x19840730, 0x19831230}; - std::unique_ptr encoder = CreateEncoder(); // TODO(terelius): Test extensions for legacy encoding, too. RtpHeaderExtensionMap extension_map; @@ -203,7 +201,7 @@ void RtcEventLogEncoderTest::TestRtpPackets() { } // Encode and parse. - encoded_ += encoder->EncodeBatch(history_.begin(), history_.end()); + encoded_ += encoder.EncodeBatch(history_.begin(), history_.end()); ASSERT_TRUE(parsed_log_.ParseString(encoded_).ok()); // For each SSRC, make sure the RTP packets associated with it to have been @@ -1339,25 +1337,31 @@ TEST_P(RtcEventLogEncoderTest, RtcEventRtcpLossNotification) { } TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) { - TestRtpPackets(); + std::unique_ptr encoder = CreateEncoder(); + TestRtpPackets(*encoder); } TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoing) { - TestRtpPackets(); + std::unique_ptr encoder = CreateEncoder(); + TestRtpPackets(*encoder); } TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncomingNoDependencyDescriptor) { - test::ScopedFieldTrials no_dd( + ExplicitKeyValueConfig no_dd( "WebRTC-RtcEventLogEncodeDependencyDescriptor/Disabled/"); - TestRtpPackets(); + std::unique_ptr encoder = CreateEncoder(no_dd); + verifier_.ExpectDependencyDescriptorExtensionIsSet(false); + TestRtpPackets(*encoder); } TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoingNoDependencyDescriptor) { - test::ScopedFieldTrials no_dd( + ExplicitKeyValueConfig no_dd( "WebRTC-RtcEventLogEncodeDependencyDescriptor/Disabled/"); - TestRtpPackets(); + std::unique_ptr encoder = CreateEncoder(no_dd); + verifier_.ExpectDependencyDescriptorExtensionIsSet(false); + TestRtpPackets(*encoder); } // TODO(eladalon/terelius): Test with multiple events in the batch. diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc index df3586a3b6..be771e3cbb 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -42,8 +42,8 @@ #include "rtc_base/buffer.h" #include "rtc_base/checks.h" #include "rtc_base/time_utils.h" -#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/ntp_time.h" +#include "test/gmock.h" #include "test/gtest.h" namespace webrtc { @@ -52,6 +52,9 @@ namespace test { namespace { +using ::testing::ElementsAreArray; +using ::testing::IsEmpty; + struct ExtensionPair { RTPExtensionType type; const char* name; @@ -1047,23 +1050,15 @@ void VerifyLoggedRtpHeader(const Event& original_header, } template -void VerifyLoggedDependencyDescriptor(const Event& packet, - const std::vector& logged_dd) { - if (webrtc::field_trial::IsDisabled( - "WebRTC-RtcEventLogEncodeDependencyDescriptor")) { - EXPECT_TRUE(logged_dd.empty()); - } else { +void EventVerifier::VerifyLoggedDependencyDescriptor( + const Event& packet, + const std::vector& logged_dd) const { + if (expect_dependency_descriptor_rtp_header_extension_is_set_) { rtc::ArrayView original = packet.template GetRawExtension(); - EXPECT_EQ(logged_dd.size(), original.size()); - bool dd_is_same = true; - for (size_t i = 0; i < logged_dd.size(); ++i) { - dd_is_same = logged_dd[i] == original[i]; - if (!dd_is_same) { - break; - } - } - EXPECT_TRUE(dd_is_same); + EXPECT_THAT(logged_dd, ElementsAreArray(original)); + } else { + EXPECT_THAT(logged_dd, IsEmpty()); } } diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.h b/logging/rtc_event_log/rtc_event_log_unittest_helper.h index 950a622f8b..e0fd3b741b 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.h +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.h @@ -160,6 +160,10 @@ class EventVerifier { explicit EventVerifier(RtcEventLog::EncodingType encoding_type) : encoding_type_(encoding_type) {} + void ExpectDependencyDescriptorExtensionIsSet(bool value) { + expect_dependency_descriptor_rtp_header_extension_is_set_ = value; + } + void VerifyLoggedAlrStateEvent(const RtcEventAlrState& original_event, const LoggedAlrStateEvent& logged_event) const; @@ -331,7 +335,13 @@ class EventVerifier { void VerifyReportBlock(const rtcp::ReportBlock& original_report_block, const rtcp::ReportBlock& logged_report_block); + template + void VerifyLoggedDependencyDescriptor( + const Event& packet, + const std::vector& logged_dd) const; + RtcEventLog::EncodingType encoding_type_; + bool expect_dependency_descriptor_rtp_header_extension_is_set_ = true; }; } // namespace test From 2c169aef974fffb9c77fd7dc248a7f78b229fcb4 Mon Sep 17 00:00:00 2001 From: Tommi Date: Wed, 31 Jan 2024 15:21:34 +0100 Subject: [PATCH 056/170] Rename kLocal to kHost and kStun to kSrflx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: none Change-Id: I92845014024e5780365057e81b613b0882724d1d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336740 Reviewed-by: Björn Terelius Commit-Queue: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41652} --- .../encoder/rtc_event_log_encoder_legacy.cc | 4 ++-- .../rtc_event_log_encoder_new_format.cc | 4 ++-- .../rtc_event_ice_candidate_pair_config.h | 10 ++++++---- logging/rtc_event_log/rtc_event_log_parser.cc | 18 +++++++++--------- .../rtc_event_log_unittest_helper.cc | 8 ++++---- p2p/base/connection.cc | 4 ++-- rtc_tools/rtc_event_log_to_text/converter.cc | 4 ++-- rtc_tools/rtc_event_log_visualizer/analyzer.cc | 4 ++-- 8 files changed, 29 insertions(+), 27 deletions(-) diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc index f1b12f0beb..83c5441138 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.cc @@ -131,9 +131,9 @@ ConvertIceCandidatePairConfigType(IceCandidatePairConfigType type) { rtclog::IceCandidatePairConfig::IceCandidateType ConvertIceCandidateType( IceCandidateType type) { switch (type) { - case IceCandidateType::kLocal: + case IceCandidateType::kHost: return rtclog::IceCandidatePairConfig::LOCAL; - case IceCandidateType::kStun: + case IceCandidateType::kSrflx: return rtclog::IceCandidatePairConfig::STUN; case IceCandidateType::kPrflx: return rtclog::IceCandidatePairConfig::PRFLX; diff --git a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc index ebda3bfeed..7018f71e1b 100644 --- a/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc +++ b/logging/rtc_event_log/encoder/rtc_event_log_encoder_new_format.cc @@ -200,9 +200,9 @@ ConvertToProtoFormat(IceCandidatePairConfigType type) { rtclog2::IceCandidatePairConfig::IceCandidateType ConvertToProtoFormat( IceCandidateType type) { switch (type) { - case IceCandidateType::kLocal: + case IceCandidateType::kHost: return rtclog2::IceCandidatePairConfig::LOCAL; - case IceCandidateType::kStun: + case IceCandidateType::kSrflx: return rtclog2::IceCandidatePairConfig::STUN; case IceCandidateType::kPrflx: return rtclog2::IceCandidatePairConfig::PRFLX; diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h index e77253d9fb..c8623a3010 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h @@ -32,13 +32,15 @@ enum class IceCandidatePairConfigType { kNumValues, }; -// TODO(tommi): Change the names of candidate types to "host", "srflx" for -// spec-compliance. +// TODO(tommi): Move this definition to candidate.h. enum class IceCandidateType { - kLocal, - kStun, + kHost, + kSrflx, kPrflx, kRelay, + // TODO(tommi): Legacy names. Remove. + kLocal [[deprecated("Use kHost instead")]] = kHost, + kStun [[deprecated("Use kSrflx instead ")]] = kSrflx }; enum class IceCandidatePairProtocol { diff --git a/logging/rtc_event_log/rtc_event_log_parser.cc b/logging/rtc_event_log/rtc_event_log_parser.cc index c53b1dd59a..d6469e1033 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.cc +++ b/logging/rtc_event_log/rtc_event_log_parser.cc @@ -171,10 +171,10 @@ bool GetRuntimeIceCandidateType( IceCandidateType& parsed_type) { switch (log_type) { case rtclog::IceCandidatePairConfig::LOCAL: - parsed_type = IceCandidateType::kLocal; + parsed_type = IceCandidateType::kHost; break; case rtclog::IceCandidatePairConfig::STUN: - parsed_type = IceCandidateType::kStun; + parsed_type = IceCandidateType::kSrflx; break; case rtclog::IceCandidatePairConfig::PRFLX: parsed_type = IceCandidateType::kPrflx; @@ -813,16 +813,16 @@ IceCandidateType GetRuntimeIceCandidateType( rtclog2::IceCandidatePairConfig::IceCandidateType type) { switch (type) { case rtclog2::IceCandidatePairConfig::LOCAL: - return IceCandidateType::kLocal; + return IceCandidateType::kHost; case rtclog2::IceCandidatePairConfig::STUN: - return IceCandidateType::kStun; + return IceCandidateType::kSrflx; case rtclog2::IceCandidatePairConfig::PRFLX: return IceCandidateType::kPrflx; case rtclog2::IceCandidatePairConfig::RELAY: return IceCandidateType::kRelay; default: RTC_DCHECK_NOTREACHED(); - return IceCandidateType::kLocal; + return IceCandidateType::kHost; } } @@ -831,10 +831,10 @@ bool GetRuntimeIceCandidateType( IceCandidateType& parsed_type) { switch (log_type) { case rtclog2::IceCandidatePairConfig::LOCAL: - parsed_type = IceCandidateType::kLocal; + parsed_type = IceCandidateType::kHost; break; case rtclog2::IceCandidatePairConfig::STUN: - parsed_type = IceCandidateType::kStun; + parsed_type = IceCandidateType::kSrflx; break; case rtclog2::IceCandidatePairConfig::PRFLX: parsed_type = IceCandidateType::kPrflx; @@ -2270,13 +2270,13 @@ std::vector ParsedRtcEventLog::GetRouteChanges() if (candidate.remote_address_family == IceCandidatePairAddressFamily::kIpv6) route.send_overhead += kIpv6Overhead - kIpv4Overhead; - if (candidate.remote_candidate_type != IceCandidateType::kLocal) + if (candidate.remote_candidate_type != IceCandidateType::kHost) route.send_overhead += kStunOverhead; route.return_overhead = kUdpOverhead + kSrtpOverhead + kIpv4Overhead; if (candidate.remote_address_family == IceCandidatePairAddressFamily::kIpv6) route.return_overhead += kIpv6Overhead - kIpv4Overhead; - if (candidate.remote_candidate_type != IceCandidateType::kLocal) + if (candidate.remote_candidate_type != IceCandidateType::kHost) route.return_overhead += kStunOverhead; route_changes.push_back(route); } diff --git a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc index be771e3cbb..bd83586456 100644 --- a/logging/rtc_event_log/rtc_event_log_unittest_helper.cc +++ b/logging/rtc_event_log/rtc_event_log_unittest_helper.cc @@ -224,10 +224,10 @@ constexpr uint32_t CandidateTypeCount() { // This switch statement only exists to catch changes to the IceCandidateType // enumeration. If you get an error here, please update the switch statement // and the return value. - IceCandidateType type = IceCandidateType::kLocal; + IceCandidateType type = IceCandidateType::kHost; switch (type) { - case IceCandidateType::kLocal: - case IceCandidateType::kStun: + case IceCandidateType::kHost: + case IceCandidateType::kSrflx: case IceCandidateType::kPrflx: case IceCandidateType::kRelay: break; @@ -237,7 +237,7 @@ constexpr uint32_t CandidateTypeCount() { std::unique_ptr EventGenerator::NewIceCandidatePairConfig() { - static_assert(static_cast(IceCandidateType::kLocal) == 0, + static_assert(static_cast(IceCandidateType::kHost) == 0, "Expect kLocal to be the first enum value, equal to 0"); IceCandidateType local_candidate_type = static_cast(prng_.Rand(CandidateTypeCount() - 1)); diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc index cd5166af06..3809f12232 100644 --- a/p2p/base/connection.cc +++ b/p2p/base/connection.cc @@ -77,9 +77,9 @@ inline bool TooLongWithoutResponse( // enum. webrtc::IceCandidateType GetRtcEventLogCandidateType(const Candidate& c) { if (c.is_local()) { - return webrtc::IceCandidateType::kLocal; + return webrtc::IceCandidateType::kHost; } else if (c.is_stun()) { - return webrtc::IceCandidateType::kStun; + return webrtc::IceCandidateType::kSrflx; } else if (c.is_prflx()) { return webrtc::IceCandidateType::kPrflx; } diff --git a/rtc_tools/rtc_event_log_to_text/converter.cc b/rtc_tools/rtc_event_log_to_text/converter.cc index 79cf03ead4..3c72bfcfeb 100644 --- a/rtc_tools/rtc_event_log_to_text/converter.cc +++ b/rtc_tools/rtc_event_log_to_text/converter.cc @@ -231,8 +231,8 @@ bool Convert(std::string inputfile, {IceCandidatePairConfigType::kNumValues, "NUM_VALUES"}}; static const std::map - candidate_type_name{{IceCandidateType::kLocal, "LOCAL"}, - {IceCandidateType::kStun, "STUN"}, + candidate_type_name{{IceCandidateType::kHost, "LOCAL"}, + {IceCandidateType::kSrflx, "STUN"}, {IceCandidateType::kPrflx, "PRFLX"}, {IceCandidateType::kRelay, "RELAY"}}; diff --git a/rtc_tools/rtc_event_log_visualizer/analyzer.cc b/rtc_tools/rtc_event_log_visualizer/analyzer.cc index 33a7ce3933..0c7775e39f 100644 --- a/rtc_tools/rtc_event_log_visualizer/analyzer.cc +++ b/rtc_tools/rtc_event_log_visualizer/analyzer.cc @@ -261,9 +261,9 @@ const char kNetworkTypeCellular[] = "cellular"; absl::string_view GetIceCandidateTypeAsString(IceCandidateType type) { switch (type) { - case IceCandidateType::kLocal: + case IceCandidateType::kHost: return kIceCandidateTypeLocal; - case IceCandidateType::kStun: + case IceCandidateType::kSrflx: return kIceCandidateTypeStun; case IceCandidateType::kPrflx: return kIceCandidateTypePrflx; From 89cf26f1e0532130745f648cf16b1fb8af2f6b4f Mon Sep 17 00:00:00 2001 From: Tomas Lundqvist Date: Mon, 29 Jan 2024 15:08:37 +0000 Subject: [PATCH 057/170] Remove post-decode VAD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:15806 Change-Id: I6acf8734a70703085cfc1ccf82a79ee0931f59a4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336460 Reviewed-by: Sam Zackrisson Commit-Queue: Tomas Lundqvist Reviewed-by: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41653} --- api/neteq/neteq.cc | 3 +- api/neteq/neteq.h | 8 -- modules/audio_coding/BUILD.gn | 3 - modules/audio_coding/acm2/acm_receiver.cc | 6 +- .../acm2/acm_receiver_unittest.cc | 59 ------------ .../audio_coding/neteq/background_noise.cc | 29 +++--- modules/audio_coding/neteq/background_noise.h | 4 +- modules/audio_coding/neteq/neteq_impl.cc | 71 ++------------- modules/audio_coding/neteq/neteq_impl.h | 11 --- modules/audio_coding/neteq/post_decode_vad.cc | 90 ------------------- modules/audio_coding/neteq/post_decode_vad.h | 71 --------------- .../neteq/post_decode_vad_unittest.cc | 25 ------ test/fuzzers/neteq_signal_fuzzer.cc | 1 - 13 files changed, 23 insertions(+), 358 deletions(-) delete mode 100644 modules/audio_coding/neteq/post_decode_vad.cc delete mode 100644 modules/audio_coding/neteq/post_decode_vad.h delete mode 100644 modules/audio_coding/neteq/post_decode_vad_unittest.cc diff --git a/api/neteq/neteq.cc b/api/neteq/neteq.cc index 155ddf2cf3..d237def23a 100644 --- a/api/neteq/neteq.cc +++ b/api/neteq/neteq.cc @@ -24,8 +24,7 @@ NetEq::Config& NetEq::Config::operator=(Config&&) = default; std::string NetEq::Config::ToString() const { char buf[1024]; rtc::SimpleStringBuilder ss(buf); - ss << "sample_rate_hz=" << sample_rate_hz << ", enable_post_decode_vad=" - << (enable_post_decode_vad ? "true" : "false") + ss << "sample_rate_hz=" << sample_rate_hz << ", max_packets_in_buffer=" << max_packets_in_buffer << ", min_delay_ms=" << min_delay_ms << ", enable_fast_accelerate=" << (enable_fast_accelerate ? "true" : "false") diff --git a/api/neteq/neteq.h b/api/neteq/neteq.h index 43e0e09784..fc0c090254 100644 --- a/api/neteq/neteq.h +++ b/api/neteq/neteq.h @@ -130,7 +130,6 @@ class NetEq { std::string ToString() const; int sample_rate_hz = 48000; // Initial value. Will change with input data. - bool enable_post_decode_vad = false; size_t max_packets_in_buffer = 200; int max_delay_ms = 0; int min_delay_ms = 0; @@ -278,13 +277,6 @@ class NetEq { // statistics are never reset. virtual NetEqOperationsAndState GetOperationsAndState() const = 0; - // Enables post-decode VAD. When enabled, GetAudio() will return - // kOutputVADPassive when the signal contains no speech. - virtual void EnableVad() = 0; - - // Disables post-decode VAD. - virtual void DisableVad() = 0; - // Returns the RTP timestamp for the last sample delivered by GetAudio(). // The return value will be empty if no valid timestamp is available. virtual absl::optional GetPlayoutTimestamp() const = 0; diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index 5de99efa45..8b23955d5b 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -689,8 +689,6 @@ rtc_library("neteq") { "neteq/packet_arrival_history.h", "neteq/packet_buffer.cc", "neteq/packet_buffer.h", - "neteq/post_decode_vad.cc", - "neteq/post_decode_vad.h", "neteq/preemptive_expand.cc", "neteq/preemptive_expand.h", "neteq/random_vector.cc", @@ -1655,7 +1653,6 @@ if (rtc_include_tests) { "neteq/normal_unittest.cc", "neteq/packet_arrival_history_unittest.cc", "neteq/packet_buffer_unittest.cc", - "neteq/post_decode_vad_unittest.cc", "neteq/random_vector_unittest.cc", "neteq/red_payload_splitter_unittest.cc", "neteq/reorder_optimizer_unittest.cc", diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc index a77e472ec1..24a49024c8 100644 --- a/modules/audio_coding/acm2/acm_receiver.cc +++ b/modules/audio_coding/acm2/acm_receiver.cc @@ -50,11 +50,7 @@ std::unique_ptr CreateNetEq( AcmReceiver::Config::Config( rtc::scoped_refptr decoder_factory) - : clock(*Clock::GetRealTimeClock()), decoder_factory(decoder_factory) { - // Post-decode VAD is disabled by default in NetEq, however, Audio - // Conference Mixer relies on VAD decisions and fails without them. - neteq_config.enable_post_decode_vad = true; -} + : clock(*Clock::GetRealTimeClock()), decoder_factory(decoder_factory) {} AcmReceiver::Config::Config(const Config&) = default; AcmReceiver::Config::~Config() = default; diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc index cda6688157..8b35f4a621 100644 --- a/modules/audio_coding/acm2/acm_receiver_unittest.cc +++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc @@ -190,9 +190,6 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { const size_t output_channels = info.num_channels; const size_t samples_per_ms = rtc::checked_cast( rtc::CheckedDivExact(output_sample_rate_hz, 1000)); - const AudioFrame::VADActivity expected_vad_activity = - output_sample_rate_hz > 16000 ? AudioFrame::kVadActive - : AudioFrame::kVadPassive; // Expect the first output timestamp to be 5*fs/8000 samples before the // first inserted timestamp (because of NetEq's look-ahead). (This value is @@ -217,7 +214,6 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { EXPECT_EQ(output_sample_rate_hz, frame.sample_rate_hz_); EXPECT_EQ(output_channels, frame.num_channels_); EXPECT_EQ(AudioFrame::kNormalSpeech, frame.speech_type_); - EXPECT_EQ(expected_vad_activity, frame.vad_activity_); EXPECT_FALSE(muted); } } @@ -242,61 +238,6 @@ TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) { RunVerifyAudioFrame({"opus", 48000, 2}); } -#if defined(WEBRTC_ANDROID) -#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad -#else -#define MAYBE_PostdecodingVad PostdecodingVad -#endif -TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) { - EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad); - constexpr int payload_type = 34; - const SdpAudioFormat codec = {"L16", 16000, 1}; - const AudioCodecInfo info = SetEncoder(payload_type, codec); - receiver_->SetCodecs({{payload_type, codec}}); - constexpr int kNumPackets = 5; - AudioFrame frame; - for (int n = 0; n < kNumPackets; ++n) { - const int num_10ms_frames = InsertOnePacketOfSilence(info); - for (int k = 0; k < num_10ms_frames; ++k) { - bool muted; - ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); - } - } - EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_); -} - -class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi { - protected: - AcmReceiverTestPostDecodeVadPassiveOldApi() { - config_.neteq_config.enable_post_decode_vad = false; - } -}; - -#if defined(WEBRTC_ANDROID) -#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad -#else -#define MAYBE_PostdecodingVad PostdecodingVad -#endif -TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) { - EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad); - constexpr int payload_type = 34; - const SdpAudioFormat codec = {"L16", 16000, 1}; - const AudioCodecInfo info = SetEncoder(payload_type, codec); - auto const value = encoder_factory_->QueryAudioEncoder(codec); - ASSERT_TRUE(value.has_value()); - receiver_->SetCodecs({{payload_type, codec}}); - const int kNumPackets = 5; - AudioFrame frame; - for (int n = 0; n < kNumPackets; ++n) { - const int num_10ms_frames = InsertOnePacketOfSilence(info); - for (int k = 0; k < num_10ms_frames; ++k) { - bool muted; - ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); - } - } - EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_); -} - #if defined(WEBRTC_ANDROID) #define MAYBE_LastAudioCodec DISABLED_LastAudioCodec #else diff --git a/modules/audio_coding/neteq/background_noise.cc b/modules/audio_coding/neteq/background_noise.cc index 2c95d3b390..0c33dba47a 100644 --- a/modules/audio_coding/neteq/background_noise.cc +++ b/modules/audio_coding/neteq/background_noise.cc @@ -17,7 +17,6 @@ #include "common_audio/signal_processing/include/signal_processing_library.h" #include "modules/audio_coding/neteq/audio_multi_vector.h" #include "modules/audio_coding/neteq/cross_correlation.h" -#include "modules/audio_coding/neteq/post_decode_vad.h" namespace webrtc { namespace { @@ -44,17 +43,11 @@ void BackgroundNoise::Reset() { } } -bool BackgroundNoise::Update(const AudioMultiVector& input, - const PostDecodeVad& vad) { +bool BackgroundNoise::Update(const AudioMultiVector& sync_buffer) { bool filter_params_saved = false; - if (vad.running() && vad.active_speech()) { - // Do not update the background noise parameters if we know that the signal - // is active speech. - return filter_params_saved; - } int32_t auto_correlation[kMaxLpcOrder + 1]; - int16_t fiter_output[kMaxLpcOrder + kResidualLength]; + int16_t filter_output[kMaxLpcOrder + kResidualLength]; int16_t reflection_coefficients[kMaxLpcOrder]; int16_t lpc_coefficients[kMaxLpcOrder + 1]; @@ -62,14 +55,13 @@ bool BackgroundNoise::Update(const AudioMultiVector& input, ChannelParameters& parameters = channel_parameters_[channel_ix]; int16_t temp_signal_array[kVecLen + kMaxLpcOrder] = {0}; int16_t* temp_signal = &temp_signal_array[kMaxLpcOrder]; - RTC_DCHECK_GE(input.Size(), kVecLen); - input[channel_ix].CopyTo(kVecLen, input.Size() - kVecLen, temp_signal); + RTC_DCHECK_GE(sync_buffer.Size(), kVecLen); + sync_buffer[channel_ix].CopyTo(kVecLen, sync_buffer.Size() - kVecLen, + temp_signal); int32_t sample_energy = CalculateAutoCorrelation(temp_signal, kVecLen, auto_correlation); - if ((!vad.running() && - sample_energy < parameters.energy_update_threshold) || - (vad.running() && !vad.active_speech())) { + if (sample_energy < parameters.energy_update_threshold) { // Generate LPC coefficients. if (auto_correlation[0] <= 0) { // Center value in auto-correlation is not positive. Do not update. @@ -95,10 +87,10 @@ bool BackgroundNoise::Update(const AudioMultiVector& input, // Generate the CNG gain factor by looking at the energy of the residual. WebRtcSpl_FilterMAFastQ12(temp_signal + kVecLen - kResidualLength, - fiter_output, lpc_coefficients, + filter_output, lpc_coefficients, kMaxLpcOrder + 1, kResidualLength); int32_t residual_energy = WebRtcSpl_DotProductWithScale( - fiter_output, fiter_output, kResidualLength, 0); + filter_output, filter_output, kResidualLength, 0); // Check spectral flatness. // Comparing the residual variance with the input signal variance tells @@ -117,9 +109,8 @@ bool BackgroundNoise::Update(const AudioMultiVector& input, filter_params_saved = true; } } else { - // Will only happen if post-decode VAD is disabled and `sample_energy` is - // not low enough. Increase the threshold for update so that it increases - // by a factor 4 in 4 seconds. + // Will only happen if `sample_energy` is not low enough. Increase the + // threshold for update so that it increases by a factor 4 in 4 seconds. IncrementEnergyThreshold(channel_ix, sample_energy); } } diff --git a/modules/audio_coding/neteq/background_noise.h b/modules/audio_coding/neteq/background_noise.h index 8e6d5890a0..9ef0131c92 100644 --- a/modules/audio_coding/neteq/background_noise.h +++ b/modules/audio_coding/neteq/background_noise.h @@ -39,9 +39,9 @@ class BackgroundNoise { void Reset(); // Updates the parameter estimates based on the signal currently in the - // `sync_buffer`, and on the latest decision in `vad` if it is running. + // `sync_buffer`. // Returns true if the filter parameters are updated. - bool Update(const AudioMultiVector& sync_buffer, const PostDecodeVad& vad); + bool Update(const AudioMultiVector& sync_buffer); // Generates background noise given a random vector and writes the output to // `buffer`. diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc index e5c8bf6c08..81b46e20e2 100644 --- a/modules/audio_coding/neteq/neteq_impl.cc +++ b/modules/audio_coding/neteq/neteq_impl.cc @@ -36,7 +36,6 @@ #include "modules/audio_coding/neteq/normal.h" #include "modules/audio_coding/neteq/packet.h" #include "modules/audio_coding/neteq/packet_buffer.h" -#include "modules/audio_coding/neteq/post_decode_vad.h" #include "modules/audio_coding/neteq/preemptive_expand.h" #include "modules/audio_coding/neteq/red_payload_splitter.h" #include "modules/audio_coding/neteq/statistics_calculator.h" @@ -70,49 +69,26 @@ std::unique_ptr CreateNetEqController( return controller_factory.CreateNetEqController(config); } -void SetAudioFrameActivityAndType(bool vad_enabled, - NetEqImpl::OutputType type, - AudioFrame::VADActivity last_vad_activity, - AudioFrame* audio_frame) { +AudioFrame::SpeechType ToSpeechType(NetEqImpl::OutputType type) { switch (type) { case NetEqImpl::OutputType::kNormalSpeech: { - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - audio_frame->vad_activity_ = AudioFrame::kVadActive; - break; - } - case NetEqImpl::OutputType::kVadPassive: { - // This should only be reached if the VAD is enabled. - RTC_DCHECK(vad_enabled); - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - break; + return AudioFrame::kNormalSpeech; } case NetEqImpl::OutputType::kCNG: { - audio_frame->speech_type_ = AudioFrame::kCNG; - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - break; + return AudioFrame::kCNG; } case NetEqImpl::OutputType::kPLC: { - audio_frame->speech_type_ = AudioFrame::kPLC; - audio_frame->vad_activity_ = last_vad_activity; - break; + return AudioFrame::kPLC; } case NetEqImpl::OutputType::kPLCCNG: { - audio_frame->speech_type_ = AudioFrame::kPLCCNG; - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - break; + return AudioFrame::kPLCCNG; } case NetEqImpl::OutputType::kCodecPLC: { - audio_frame->speech_type_ = AudioFrame::kCodecPLC; - audio_frame->vad_activity_ = last_vad_activity; - break; + return AudioFrame::kCodecPLC; } default: RTC_DCHECK_NOTREACHED(); - } - if (!vad_enabled) { - // Always set kVadUnknown when receive VAD is inactive. - audio_frame->vad_activity_ = AudioFrame::kVadUnknown; + return AudioFrame::kUndefined; } } @@ -169,7 +145,6 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, packet_buffer_(std::move(deps.packet_buffer)), red_payload_splitter_(std::move(deps.red_payload_splitter)), timestamp_scaler_(std::move(deps.timestamp_scaler)), - vad_(new PostDecodeVad()), expand_factory_(std::move(deps.expand_factory)), accelerate_factory_(std::move(deps.accelerate_factory)), preemptive_expand_factory_(std::move(deps.preemptive_expand_factory)), @@ -211,10 +186,6 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, if (create_components) { SetSampleRateAndChannels(fs, 1); // Default is 1 channel. } - RTC_DCHECK(!vad_->enabled()); - if (config.enable_post_decode_vad) { - vad_->Enable(); - } } NetEqImpl::~NetEqImpl() = default; @@ -252,9 +223,7 @@ int NetEqImpl::GetAudio(AudioFrame* audio_frame, audio_frame->sample_rate_hz_, rtc::dchecked_cast(audio_frame->samples_per_channel_ * 100)); RTC_DCHECK_EQ(*muted, audio_frame->muted()); - SetAudioFrameActivityAndType(vad_->enabled(), LastOutputType(), - last_vad_activity_, audio_frame); - last_vad_activity_ = audio_frame->vad_activity_; + audio_frame->speech_type_ = ToSpeechType(LastOutputType()); last_output_sample_rate_hz_ = audio_frame->sample_rate_hz_; RTC_DCHECK(last_output_sample_rate_hz_ == 8000 || last_output_sample_rate_hz_ == 16000 || @@ -398,18 +367,6 @@ NetEqOperationsAndState NetEqImpl::GetOperationsAndState() const { return result; } -void NetEqImpl::EnableVad() { - MutexLock lock(&mutex_); - RTC_DCHECK(vad_.get()); - vad_->Enable(); -} - -void NetEqImpl::DisableVad() { - MutexLock lock(&mutex_); - RTC_DCHECK(vad_.get()); - vad_->Disable(); -} - absl::optional NetEqImpl::GetPlayoutTimestamp() const { MutexLock lock(&mutex_); if (first_packet_ || last_mode_ == Mode::kRfc3389Cng || @@ -858,11 +815,8 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, last_decoded_type_ = speech_type; } - RTC_DCHECK(vad_.get()); bool sid_frame_available = (operation == Operation::kRfc3389Cng && !packet_list.empty()); - vad_->Update(decoded_buffer_.get(), static_cast(length), speech_type, - sid_frame_available, fs_hz_); // This is the criterion that we did decode some data through the speech // decoder, and the operation resulted in comfort noise. @@ -1012,7 +966,7 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, (last_mode_ == Mode::kPreemptiveExpandFail) || (last_mode_ == Mode::kRfc3389Cng) || (last_mode_ == Mode::kCodecInternalCng)) { - background_noise_->Update(*sync_buffer_, *vad_.get()); + background_noise_->Update(*sync_buffer_); } if (operation == Operation::kDtmf) { @@ -2088,10 +2042,6 @@ void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) { if (cng_decoder) cng_decoder->Reset(); - // Reinit post-decode VAD with new sample rate. - RTC_DCHECK(vad_.get()); // Cannot be NULL here. - vad_->Init(); - // Delete algorithm buffer and create a new one. algorithm_buffer_.reset(new AudioMultiVector(channels)); @@ -2132,7 +2082,6 @@ void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) { } NetEqImpl::OutputType NetEqImpl::LastOutputType() { - RTC_DCHECK(vad_.get()); RTC_DCHECK(expand_.get()); if (last_mode_ == Mode::kCodecInternalCng || last_mode_ == Mode::kRfc3389Cng) { @@ -2142,8 +2091,6 @@ NetEqImpl::OutputType NetEqImpl::LastOutputType() { return OutputType::kPLCCNG; } else if (last_mode_ == Mode::kExpand) { return OutputType::kPLC; - } else if (vad_->running() && !vad_->active_speech()) { - return OutputType::kVadPassive; } else if (last_mode_ == Mode::kCodecPlc) { return OutputType::kCodecPLC; } else { diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h index f8f2b06410..6ccbde7293 100644 --- a/modules/audio_coding/neteq/neteq_impl.h +++ b/modules/audio_coding/neteq/neteq_impl.h @@ -48,7 +48,6 @@ class Merge; class NackTracker; class Normal; class RedPayloadSplitter; -class PostDecodeVad; class PreemptiveExpand; class RandomVector; class SyncBuffer; @@ -171,13 +170,6 @@ class NetEqImpl : public webrtc::NetEq { NetEqOperationsAndState GetOperationsAndState() const override; - // Enables post-decode VAD. When enabled, GetAudio() will return - // kOutputVADPassive when the signal contains no speech. - void EnableVad() override; - - // Disables post-decode VAD. - void DisableVad() override; - absl::optional GetPlayoutTimestamp() const override; int last_output_sample_rate_hz() const override; @@ -356,7 +348,6 @@ class NetEqImpl : public webrtc::NetEq { RTC_GUARDED_BY(mutex_); const std::unique_ptr timestamp_scaler_ RTC_GUARDED_BY(mutex_); - const std::unique_ptr vad_ RTC_GUARDED_BY(mutex_); const std::unique_ptr expand_factory_ RTC_GUARDED_BY(mutex_); const std::unique_ptr accelerate_factory_ RTC_GUARDED_BY(mutex_); @@ -397,8 +388,6 @@ class NetEqImpl : public webrtc::NetEq { std::unique_ptr nack_ RTC_GUARDED_BY(mutex_); bool nack_enabled_ RTC_GUARDED_BY(mutex_); const bool enable_muted_state_ RTC_GUARDED_BY(mutex_); - AudioFrame::VADActivity last_vad_activity_ RTC_GUARDED_BY(mutex_) = - AudioFrame::kVadPassive; std::unique_ptr generated_noise_stopwatch_ RTC_GUARDED_BY(mutex_); std::vector last_decoded_packet_infos_ RTC_GUARDED_BY(mutex_); diff --git a/modules/audio_coding/neteq/post_decode_vad.cc b/modules/audio_coding/neteq/post_decode_vad.cc deleted file mode 100644 index 9999d6764b..0000000000 --- a/modules/audio_coding/neteq/post_decode_vad.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013 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 "modules/audio_coding/neteq/post_decode_vad.h" - -namespace webrtc { - -PostDecodeVad::~PostDecodeVad() { - if (vad_instance_) - WebRtcVad_Free(vad_instance_); -} - -void PostDecodeVad::Enable() { - if (!vad_instance_) { - // Create the instance. - vad_instance_ = WebRtcVad_Create(); - if (vad_instance_ == nullptr) { - // Failed to create instance. - Disable(); - return; - } - } - Init(); - enabled_ = true; -} - -void PostDecodeVad::Disable() { - enabled_ = false; - running_ = false; -} - -void PostDecodeVad::Init() { - running_ = false; - if (vad_instance_) { - WebRtcVad_Init(vad_instance_); - WebRtcVad_set_mode(vad_instance_, kVadMode); - running_ = true; - } -} - -void PostDecodeVad::Update(int16_t* signal, - size_t length, - AudioDecoder::SpeechType speech_type, - bool sid_frame, - int fs_hz) { - if (!vad_instance_ || !enabled_) { - return; - } - - if (speech_type == AudioDecoder::kComfortNoise || sid_frame || - fs_hz > 16000) { - // TODO(hlundin): Remove restriction on fs_hz. - running_ = false; - active_speech_ = true; - sid_interval_counter_ = 0; - } else if (!running_) { - ++sid_interval_counter_; - } - - if (sid_interval_counter_ >= kVadAutoEnable) { - Init(); - } - - if (length > 0 && running_) { - size_t vad_sample_index = 0; - active_speech_ = false; - // Loop through frame sizes 30, 20, and 10 ms. - for (int vad_frame_size_ms = 30; vad_frame_size_ms >= 10; - vad_frame_size_ms -= 10) { - size_t vad_frame_size_samples = - static_cast(vad_frame_size_ms * fs_hz / 1000); - while (length - vad_sample_index >= vad_frame_size_samples) { - int vad_return = - WebRtcVad_Process(vad_instance_, fs_hz, &signal[vad_sample_index], - vad_frame_size_samples); - active_speech_ |= (vad_return == 1); - vad_sample_index += vad_frame_size_samples; - } - } - } -} - -} // namespace webrtc diff --git a/modules/audio_coding/neteq/post_decode_vad.h b/modules/audio_coding/neteq/post_decode_vad.h deleted file mode 100644 index 3bd91b9edb..0000000000 --- a/modules/audio_coding/neteq/post_decode_vad.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013 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 MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ -#define MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ - -#include -#include - -#include "api/audio_codecs/audio_decoder.h" -#include "common_audio/vad/include/webrtc_vad.h" - -namespace webrtc { - -class PostDecodeVad { - public: - PostDecodeVad() - : enabled_(false), - running_(false), - active_speech_(true), - sid_interval_counter_(0), - vad_instance_(NULL) {} - - virtual ~PostDecodeVad(); - - PostDecodeVad(const PostDecodeVad&) = delete; - PostDecodeVad& operator=(const PostDecodeVad&) = delete; - - // Enables post-decode VAD. - void Enable(); - - // Disables post-decode VAD. - void Disable(); - - // Initializes post-decode VAD. - void Init(); - - // Updates post-decode VAD with the audio data in `signal` having `length` - // samples. The data is of type `speech_type`, at the sample rate `fs_hz`. - void Update(int16_t* signal, - size_t length, - AudioDecoder::SpeechType speech_type, - bool sid_frame, - int fs_hz); - - // Accessors. - bool enabled() const { return enabled_; } - bool running() const { return running_; } - bool active_speech() const { return active_speech_; } - - private: - static const int kVadMode = 0; // Sets aggressiveness to "Normal". - // Number of Update() calls without CNG/SID before re-enabling VAD. - static const int kVadAutoEnable = 3000; - - bool enabled_; - bool running_; - bool active_speech_; - int sid_interval_counter_; - ::VadInst* vad_instance_; -}; - -} // namespace webrtc -#endif // MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ diff --git a/modules/audio_coding/neteq/post_decode_vad_unittest.cc b/modules/audio_coding/neteq/post_decode_vad_unittest.cc deleted file mode 100644 index da3e4e864e..0000000000 --- a/modules/audio_coding/neteq/post_decode_vad_unittest.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -// Unit tests for PostDecodeVad class. - -#include "modules/audio_coding/neteq/post_decode_vad.h" - -#include "test/gtest.h" - -namespace webrtc { - -TEST(PostDecodeVad, CreateAndDestroy) { - PostDecodeVad vad; -} - -// TODO(hlundin): Write more tests. - -} // namespace webrtc diff --git a/test/fuzzers/neteq_signal_fuzzer.cc b/test/fuzzers/neteq_signal_fuzzer.cc index 485c38085e..3b1f70cdb4 100644 --- a/test/fuzzers/neteq_signal_fuzzer.cc +++ b/test/fuzzers/neteq_signal_fuzzer.cc @@ -179,7 +179,6 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) { // Configure NetEq and the NetEqTest object. NetEqTest::Callbacks callbacks; NetEq::Config config; - config.enable_post_decode_vad = true; config.enable_fast_accelerate = true; auto codecs = NetEqTest::StandardDecoderMap(); // rate_types contains the payload types that will be used for encoding. From c1cc6a36b2fe646d284dd80680f6dbb905d8a207 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Wed, 3 Jan 2024 16:47:05 +0100 Subject: [PATCH 058/170] sdp: backfill default codec parameters for AV1 as required by https://aomediacodec.github.io/av1-rtp-spec/#72-sdp-parameters Also unify usage of profile fmtp parameter. Most notably this causes SDP answers to include the default values. These default values correspond to libaom's default values for AV1E_SET_TARGET_SEQ_LEVEL_IDX, AV1E_SET_TIER_MASK as used in https://source.chromium.org/chromium/chromium/src/+/main:third_party/libaom/source/libaom/aom/aomcx.h and g_profile in aom_codec_enc_cfg https://source.chromium.org/chromium/chromium/src/+/main:third_party/libaom/source/libaom/aom/aom_encoder.h;l=415;drc=b58207f5aecc39db7d3da766e7d171e5d2c3598e Note: AV1 is inconsistently cased in variable/struct/method/class names. The canonical casing should probably be "Av1" since it is an acronym standing for "AOMedia Video 1". BUG=webrtc:15703 Change-Id: I11864b7666fea906cd1a0759c7ad45997beab90e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331360 Reviewed-by: Sergey Silkin Reviewed-by: Harald Alvestrand Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41654} --- api/video_codecs/BUILD.gn | 1 + api/video_codecs/av1_profile.cc | 6 ++---- api/video_codecs/av1_profile.h | 3 --- api/video_codecs/sdp_video_format.cc | 4 ++-- .../video_decoder_factory_template_dav1d_adapter.h | 2 +- media/base/codec_unittest.cc | 10 +++++----- media/base/media_constants.cc | 6 ++++++ media/base/media_constants.h | 6 ++++++ media/engine/internal_decoder_factory.cc | 7 ++++--- media/engine/internal_decoder_factory_unittest.cc | 2 +- pc/webrtc_sdp.cc | 11 +++++++++++ pc/webrtc_sdp_unittest.cc | 14 ++++++++++++-- 12 files changed, 51 insertions(+), 21 deletions(-) diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn index aaa2a5750a..5bdd514a65 100644 --- a/api/video_codecs/BUILD.gn +++ b/api/video_codecs/BUILD.gn @@ -85,6 +85,7 @@ rtc_library("video_codecs_api") { "..:scoped_refptr", "../../api:array_view", "../../api:rtp_parameters", + "../../media:media_constants", "../../modules/video_coding:codec_globals_headers", "../../rtc_base:checks", "../../rtc_base:logging", diff --git a/api/video_codecs/av1_profile.cc b/api/video_codecs/av1_profile.cc index 59d7b13e51..1a953a0c53 100644 --- a/api/video_codecs/av1_profile.cc +++ b/api/video_codecs/av1_profile.cc @@ -13,13 +13,11 @@ #include #include +#include "media/base/media_constants.h" #include "rtc_base/string_to_number.h" namespace webrtc { -// Parameter name in the format parameter map for AV1 video. -const char kAV1FmtpProfile[] = "profile"; - absl::string_view AV1ProfileToString(AV1Profile profile) { switch (profile) { case AV1Profile::kProfile0: @@ -51,7 +49,7 @@ absl::optional StringToAV1Profile(absl::string_view str) { absl::optional ParseSdpForAV1Profile( const CodecParameterMap& params) { - const auto profile_it = params.find(kAV1FmtpProfile); + const auto profile_it = params.find(cricket::kAv1FmtpProfile); if (profile_it == params.end()) return AV1Profile::kProfile0; const std::string& profile_str = profile_it->second; diff --git a/api/video_codecs/av1_profile.h b/api/video_codecs/av1_profile.h index bc9767631c..4651d93ef4 100644 --- a/api/video_codecs/av1_profile.h +++ b/api/video_codecs/av1_profile.h @@ -20,9 +20,6 @@ namespace webrtc { -// Profile information for AV1 video. -extern RTC_EXPORT const char kAV1FmtpProfile[]; - // Profiles can be found at: // https://aomedia.org/av1/specification/annex-a/#profiles // The enum values match the number specified in the SDP. diff --git a/api/video_codecs/sdp_video_format.cc b/api/video_codecs/sdp_video_format.cc index 0f313e84a9..5e311d1134 100644 --- a/api/video_codecs/sdp_video_format.cc +++ b/api/video_codecs/sdp_video_format.cc @@ -20,6 +20,7 @@ #endif #include "api/video_codecs/video_codec.h" #include "api/video_codecs/vp9_profile.h" +#include "media/base/media_constants.h" #include "rtc_base/checks.h" #include "rtc_base/logging.h" #include "rtc_base/strings/string_builder.h" @@ -29,8 +30,7 @@ namespace webrtc { namespace { std::string H264GetPacketizationModeOrDefault(const CodecParameterMap& params) { - constexpr char kH264FmtpPacketizationMode[] = "packetization-mode"; - const auto it = params.find(kH264FmtpPacketizationMode); + const auto it = params.find(cricket::kH264FmtpPacketizationMode); if (it != params.end()) { return it->second; } diff --git a/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h b/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h index bffbdc43d3..f38d46994b 100644 --- a/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h +++ b/api/video_codecs/video_decoder_factory_template_dav1d_adapter.h @@ -23,7 +23,7 @@ struct Dav1dDecoderTemplateAdapter { static std::vector SupportedFormats() { return {SdpVideoFormat("AV1"), SdpVideoFormat( - "AV1", {{kAV1FmtpProfile, + "AV1", {{"profile", AV1ProfileToString(AV1Profile::kProfile1).data()}})}; } diff --git a/media/base/codec_unittest.cc b/media/base/codec_unittest.cc index 4dc3b18c21..e1e69eb082 100644 --- a/media/base/codec_unittest.cc +++ b/media/base/codec_unittest.cc @@ -228,11 +228,11 @@ TEST(CodecTest, TestAV1CodecMatches) { VideoCodec c_no_profile = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); VideoCodec c_profile0 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile0.params[webrtc::kAV1FmtpProfile] = kProfile0; + c_profile0.params[cricket::kAv1FmtpProfile] = kProfile0; VideoCodec c_profile1 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile1.params[webrtc::kAV1FmtpProfile] = kProfile1; + c_profile1.params[cricket::kAv1FmtpProfile] = kProfile1; VideoCodec c_profile2 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile2.params[webrtc::kAV1FmtpProfile] = kProfile2; + c_profile2.params[cricket::kAv1FmtpProfile] = kProfile2; // An AV1 entry with no profile specified should be treated as profile-0. EXPECT_TRUE(c_profile0.Matches(c_no_profile)); @@ -248,7 +248,7 @@ TEST(CodecTest, TestAV1CodecMatches) { // Two AV1 entries with profile 0 specified are treated as duplicates. VideoCodec c_profile0_eq = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile0_eq.params[webrtc::kAV1FmtpProfile] = kProfile0; + c_profile0_eq.params[cricket::kAv1FmtpProfile] = kProfile0; EXPECT_TRUE(c_profile0.Matches(c_profile0_eq)); } @@ -256,7 +256,7 @@ TEST(CodecTest, TestAV1CodecMatches) { // Two AV1 entries with profile 1 specified are treated as duplicates. VideoCodec c_profile1_eq = cricket::CreateVideoCodec(95, cricket::kAv1CodecName); - c_profile1_eq.params[webrtc::kAV1FmtpProfile] = kProfile1; + c_profile1_eq.params[cricket::kAv1FmtpProfile] = kProfile1; EXPECT_TRUE(c_profile1.Matches(c_profile1_eq)); } diff --git a/media/base/media_constants.cc b/media/base/media_constants.cc index 2af0295a5a..1a7561aa52 100644 --- a/media/base/media_constants.cc +++ b/media/base/media_constants.cc @@ -124,8 +124,14 @@ const char kH265FmtpProfileCompatibilityIndicator[] = const char kH265FmtpInteropConstraints[] = "interop-constraints"; const char kH265FmtpTxMode[] = "tx-mode"; +// draft-ietf-payload-vp9 const char kVP9ProfileId[] = "profile-id"; +// https://aomediacodec.github.io/av1-rtp-spec/ +const char kAv1FmtpProfile[] = "profile"; +const char kAv1FmtpLevelIdx[] = "level-idx"; +const char kAv1FmtpTier[] = "tier"; + const int kDefaultVideoMaxFramerate = 60; // Max encode quantizer for VP8/9 and AV1 encoders assuming libvpx/libaom API // range [0, 63] diff --git a/media/base/media_constants.h b/media/base/media_constants.h index 877cc7a296..d5af17eb2a 100644 --- a/media/base/media_constants.h +++ b/media/base/media_constants.h @@ -147,8 +147,14 @@ RTC_EXPORT extern const char kH265FmtpProfileCompatibilityIndicator[]; RTC_EXPORT extern const char kH265FmtpInteropConstraints[]; RTC_EXPORT extern const char kH265FmtpTxMode[]; +// draft-ietf-payload-vp9 extern const char kVP9ProfileId[]; +// https://aomediacodec.github.io/av1-rtp-spec/ +extern const char kAv1FmtpProfile[]; +extern const char kAv1FmtpLevelIdx[]; +extern const char kAv1FmtpTier[]; + extern const int kDefaultVideoMaxFramerate; extern const int kDefaultVideoMaxQpVpx; extern const int kDefaultVideoMaxQpH26x; diff --git a/media/engine/internal_decoder_factory.cc b/media/engine/internal_decoder_factory.cc index e761fd60c8..e623aeb43a 100644 --- a/media/engine/internal_decoder_factory.cc +++ b/media/engine/internal_decoder_factory.cc @@ -51,9 +51,10 @@ std::vector InternalDecoderFactory::GetSupportedFormats() if (kDav1dIsIncluded) { formats.push_back(SdpVideoFormat(cricket::kAv1CodecName)); - formats.push_back(SdpVideoFormat( - cricket::kAv1CodecName, - {{kAV1FmtpProfile, AV1ProfileToString(AV1Profile::kProfile1).data()}})); + formats.push_back( + SdpVideoFormat(cricket::kAv1CodecName, + {{cricket::kAv1FmtpProfile, + AV1ProfileToString(AV1Profile::kProfile1).data()}})); } return formats; diff --git a/media/engine/internal_decoder_factory_unittest.cc b/media/engine/internal_decoder_factory_unittest.cc index 51d6a94dd6..e06b4c3d77 100644 --- a/media/engine/internal_decoder_factory_unittest.cc +++ b/media/engine/internal_decoder_factory_unittest.cc @@ -121,7 +121,7 @@ TEST(InternalDecoderFactoryTest, Av1Profile1_Dav1dDecoderTrialEnabled) { InternalDecoderFactory factory; std::unique_ptr decoder = factory.CreateVideoDecoder( SdpVideoFormat(cricket::kAv1CodecName, - {{kAV1FmtpProfile, + {{cricket::kAv1FmtpProfile, AV1ProfileToString(AV1Profile::kProfile1).data()}})); EXPECT_EQ(static_cast(decoder), kDav1dIsIncluded); } diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc index 88f1ce0d1b..a255233ccc 100644 --- a/pc/webrtc_sdp.cc +++ b/pc/webrtc_sdp.cc @@ -2615,6 +2615,17 @@ static void BackfillCodecParameters(std::vector& codecs) { if (!codec.GetParam(cricket::kH264FmtpPacketizationMode, &unused_value)) { codec.SetParam(cricket::kH264FmtpPacketizationMode, "0"); } + } else if (absl::EqualsIgnoreCase(cricket::kAv1CodecName, codec.name)) { + // https://aomediacodec.github.io/av1-rtp-spec/#72-sdp-parameters + if (!codec.GetParam(cricket::kAv1FmtpProfile, &unused_value)) { + codec.SetParam(cricket::kAv1FmtpProfile, "0"); + } + if (!codec.GetParam(cricket::kAv1FmtpLevelIdx, &unused_value)) { + codec.SetParam(cricket::kAv1FmtpLevelIdx, "5"); + } + if (!codec.GetParam(cricket::kAv1FmtpTier, &unused_value)) { + codec.SetParam(cricket::kAv1FmtpTier, "0"); + } } } } diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc index 0238c97aa0..382a4967d5 100644 --- a/pc/webrtc_sdp_unittest.cc +++ b/pc/webrtc_sdp_unittest.cc @@ -5082,13 +5082,14 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { "a=setup:actpass\r\n" "a=ice-ufrag:ETEn\r\n" "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n" - "m=video 9 UDP/TLS/RTP/SAVPF 96 97\r\n" + "m=video 9 UDP/TLS/RTP/SAVPF 96 97 98\r\n" "c=IN IP4 0.0.0.0\r\n" "a=rtcp-mux\r\n" "a=sendonly\r\n" "a=mid:0\r\n" "a=rtpmap:96 H264/90000\r\n" "a=rtpmap:97 VP9/90000\r\n" + "a=rtpmap:98 AV1/90000\r\n" "a=ssrc:1234 cname:test\r\n"; JsepSessionDescription jdesc(kDummyType); EXPECT_TRUE(SdpDeserialize(sdp, &jdesc)); @@ -5097,7 +5098,7 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { const auto* description = content.media_description(); ASSERT_NE(description, nullptr); const std::vector codecs = description->codecs(); - ASSERT_EQ(codecs.size(), 2u); + ASSERT_EQ(codecs.size(), 3u); std::string value; EXPECT_EQ(codecs[0].name, "H264"); @@ -5107,4 +5108,13 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { EXPECT_EQ(codecs[1].name, "VP9"); EXPECT_TRUE(codecs[1].GetParam("profile-id", &value)); EXPECT_EQ(value, "0"); + + EXPECT_EQ(codecs[2].name, "AV1"); + EXPECT_TRUE(codecs[2].GetParam("profile", &value)); + EXPECT_EQ(value, "0"); + EXPECT_TRUE(codecs[2].GetParam("level-idx", &value)); + EXPECT_EQ(value, "5"); + EXPECT_TRUE(codecs[2].GetParam("tier", &value)); + EXPECT_EQ(value, "0"); + RTC_LOG(LS_ERROR) << sdp; } From b5f2b17fd8a44b9a4e6b47f10b405f070814041a Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Thu, 4 Jan 2024 12:02:08 +0000 Subject: [PATCH 059/170] Remove SOCKS5 support Bug: webrtc:15726 Change-Id: Icd3aca433966f76e1b200b0f4790013cce12095a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331820 Reviewed-by: Tomas Gunnarsson Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41655} --- p2p/base/basic_packet_socket_factory.cc | 6 +- p2p/base/p2p_transport_channel_unittest.cc | 61 ++----- rtc_base/BUILD.gn | 1 - rtc_base/proxy_server.cc | 4 - rtc_base/proxy_server.h | 16 -- rtc_base/proxy_unittest.cc | 68 -------- rtc_base/server_socket_adapters.cc | 131 -------------- rtc_base/server_socket_adapters.h | 34 ---- rtc_base/socket_adapters.cc | 194 --------------------- rtc_base/socket_adapters.h | 36 ---- 10 files changed, 14 insertions(+), 537 deletions(-) delete mode 100644 rtc_base/proxy_unittest.cc diff --git a/p2p/base/basic_packet_socket_factory.cc b/p2p/base/basic_packet_socket_factory.cc index 6a811af71a..816d964360 100644 --- a/p2p/base/basic_packet_socket_factory.cc +++ b/p2p/base/basic_packet_socket_factory.cc @@ -119,11 +119,7 @@ AsyncPacketSocket* BasicPacketSocketFactory::CreateClientTcpSocket( << socket->GetError(); } - // If using a proxy, wrap the socket in a proxy socket. - if (proxy_info.type == PROXY_SOCKS5) { - socket = new AsyncSocksProxySocket( - socket, proxy_info.address, proxy_info.username, proxy_info.password); - } else if (proxy_info.type == PROXY_HTTPS) { + if (proxy_info.type == PROXY_HTTPS) { socket = new AsyncHttpsProxySocket(socket, user_agent, proxy_info.address, proxy_info.username, proxy_info.password); diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index e701998e27..5bcfee0473 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -286,14 +286,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, main_(ss_.get()), stun_server_(TestStunServer::Create(ss_.get(), kStunAddr, main_)), turn_server_(&main_, ss_.get(), kTurnUdpIntAddr, kTurnUdpExtAddr), - socks_server1_(ss_.get(), - kSocksProxyAddrs[0], - ss_.get(), - kSocksProxyAddrs[0]), - socks_server2_(ss_.get(), - kSocksProxyAddrs[1], - ss_.get(), - kSocksProxyAddrs[1]), force_relay_(false) { ep1_.role_ = ICEROLE_CONTROLLING; ep2_.role_ = ICEROLE_CONTROLLED; @@ -330,7 +322,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, BLOCK_UDP_AND_INCOMING_TCP, // Firewall, UDP in/out and TCP in blocked BLOCK_ALL_BUT_OUTGOING_HTTP, // Firewall, only TCP out on 80/443 PROXY_HTTPS, // All traffic through HTTPS proxy - PROXY_SOCKS, // All traffic through SOCKS proxy NUM_CONFIGS }; @@ -1028,8 +1019,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, PendingTaskSafetyFlag::Create(); TestStunServer::StunServerPtr stun_server_; TestTurnServer turn_server_; - rtc::SocksProxyServer socks_server1_; - rtc::SocksProxyServer socks_server2_; Endpoint ep1_; Endpoint ep2_; RemoteIceParameterSource remote_ice_parameter_source_ = FROM_CANDIDATE; @@ -1179,7 +1168,6 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase { case BLOCK_UDP_AND_INCOMING_TCP: case BLOCK_ALL_BUT_OUTGOING_HTTP: case PROXY_HTTPS: - case PROXY_SOCKS: AddAddress(endpoint, kPublicAddrs[endpoint]); // Block all UDP fw()->AddRule(false, rtc::FP_UDP, rtc::FD_ANY, kPublicAddrs[endpoint]); @@ -1202,13 +1190,6 @@ class P2PTransportChannelTest : public P2PTransportChannelTestBase { fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY, kPublicAddrs[endpoint]); SetProxy(endpoint, rtc::PROXY_HTTPS); - } else if (config == PROXY_SOCKS) { - // Block all TCP to/from the endpoint except to the proxy server - fw()->AddRule(true, rtc::FP_TCP, kPublicAddrs[endpoint], - kSocksProxyAddrs[endpoint]); - fw()->AddRule(false, rtc::FP_TCP, rtc::FD_ANY, - kPublicAddrs[endpoint]); - SetProxy(endpoint, rtc::PROXY_SOCKS5); } break; default: @@ -1253,42 +1234,28 @@ class P2PTransportChannelMatrixTest : public P2PTransportChannelTest, const P2PTransportChannelMatrixTest::Result* P2PTransportChannelMatrixTest::kMatrix[NUM_CONFIGS][NUM_CONFIGS] = { // OPEN CONE ADDR PORT SYMM 2CON SCON !UDP !TCP HTTP PRXH - // PRXS - /*OP*/ {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, - NULL, LTPT}, + /*OP*/ + {LULU, LUSU, LUSU, LUSU, LUPU, LUSU, LUPU, LTPT, LTPT, LSRS, NULL}, /*CO*/ - {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL}, /*AD*/ - {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL}, /*PO*/ - {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, RUPU, SUSU, RUPU, NULL, NULL, LSRS, NULL}, /*SY*/ - {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, - LTRT}, + {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL}, /*2C*/ - {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL, - LTRT}, + {SULU, SUSU, SUSU, SUSU, SUPU, SUSU, SUPU, NULL, NULL, LSRS, NULL}, /*SC*/ - {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL, - LTRT}, + {PULU, PUSU, PUSU, PURU, PURU, PUSU, PURU, NULL, NULL, LSRS, NULL}, /*!U*/ - {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL, - LTRT}, + {LTPT, NULL, NULL, NULL, NULL, NULL, NULL, LTPT, LTPT, LSRS, NULL}, /*!T*/ - {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL, - LTRT}, + {PTLT, NULL, NULL, NULL, NULL, NULL, NULL, PTLT, LTRT, LSRS, NULL}, /*HT*/ - {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL, - LSRS}, + {LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, LSRS, NULL}, /*PR*/ - {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL}, - /*PR*/ - {LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LTRT, LSRS, NULL, - LTRT}, + {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, }; // The actual tests that exercise all the various configurations. @@ -1316,8 +1283,7 @@ const P2PTransportChannelMatrixTest::Result* P2P_TEST(x, BLOCK_UDP) \ P2P_TEST(x, BLOCK_UDP_AND_INCOMING_TCP) \ P2P_TEST(x, BLOCK_ALL_BUT_OUTGOING_HTTP) \ - P2P_TEST(x, PROXY_HTTPS) \ - P2P_TEST(x, PROXY_SOCKS) + P2P_TEST(x, PROXY_HTTPS) P2P_TEST_SET(OPEN) P2P_TEST_SET(NAT_FULL_CONE) @@ -1330,7 +1296,6 @@ P2P_TEST_SET(BLOCK_UDP) P2P_TEST_SET(BLOCK_UDP_AND_INCOMING_TCP) P2P_TEST_SET(BLOCK_ALL_BUT_OUTGOING_HTTP) P2P_TEST_SET(PROXY_HTTPS) -P2P_TEST_SET(PROXY_SOCKS) INSTANTIATE_TEST_SUITE_P( All, diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index 8d108bbdec..2cf9c11316 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -2088,7 +2088,6 @@ if (rtc_include_tests) { "nat_unittest.cc", "network_route_unittest.cc", "network_unittest.cc", - "proxy_unittest.cc", "rolling_accumulator_unittest.cc", "rtc_certificate_generator_unittest.cc", "rtc_certificate_unittest.cc", diff --git a/rtc_base/proxy_server.cc b/rtc_base/proxy_server.cc index 84c96213c3..f8fe23da2a 100644 --- a/rtc_base/proxy_server.cc +++ b/rtc_base/proxy_server.cc @@ -149,8 +149,4 @@ void ProxyBinding::Destroy() { SignalDestroyed(this); } -AsyncProxyServerSocket* SocksProxyServer::WrapSocket(Socket* socket) { - return new AsyncSocksProxyServerSocket(socket); -} - } // namespace rtc diff --git a/rtc_base/proxy_server.h b/rtc_base/proxy_server.h index 0b9b655a5e..033dd82118 100644 --- a/rtc_base/proxy_server.h +++ b/rtc_base/proxy_server.h @@ -89,22 +89,6 @@ class ProxyServer : public sigslot::has_slots<> { std::vector> bindings_; }; -// SocksProxyServer is a simple extension of ProxyServer to implement SOCKS. -class SocksProxyServer : public ProxyServer { - public: - SocksProxyServer(SocketFactory* int_factory, - const SocketAddress& int_addr, - SocketFactory* ext_factory, - const SocketAddress& ext_ip) - : ProxyServer(int_factory, int_addr, ext_factory, ext_ip) {} - - SocksProxyServer(const SocksProxyServer&) = delete; - SocksProxyServer& operator=(const SocksProxyServer&) = delete; - - protected: - AsyncProxyServerSocket* WrapSocket(Socket* socket) override; -}; - } // namespace rtc #endif // RTC_BASE_PROXY_SERVER_H_ diff --git a/rtc_base/proxy_unittest.cc b/rtc_base/proxy_unittest.cc deleted file mode 100644 index 9e3898e430..0000000000 --- a/rtc_base/proxy_unittest.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2009 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 -#include - -#include "rtc_base/gunit.h" -#include "rtc_base/proxy_server.h" -#include "rtc_base/socket_adapters.h" -#include "rtc_base/test_client.h" -#include "rtc_base/test_echo_server.h" -#include "rtc_base/virtual_socket_server.h" - -using rtc::Socket; -using rtc::SocketAddress; - -static const SocketAddress kSocksProxyIntAddr("1.2.3.4", 1080); -static const SocketAddress kSocksProxyExtAddr("1.2.3.5", 0); -static const SocketAddress kBogusProxyIntAddr("1.2.3.4", 999); - -// Sets up a virtual socket server and a SOCKS5 proxy server. -class ProxyTest : public ::testing::Test { - public: - ProxyTest() : ss_(new rtc::VirtualSocketServer()), thread_(ss_.get()) { - socks_.reset(new rtc::SocksProxyServer(ss_.get(), kSocksProxyIntAddr, - ss_.get(), kSocksProxyExtAddr)); - } - - rtc::SocketServer* ss() { return ss_.get(); } - - private: - std::unique_ptr ss_; - rtc::AutoSocketServerThread thread_; - std::unique_ptr socks_; -}; - -// Tests whether we can use a SOCKS5 proxy to connect to a server. -TEST_F(ProxyTest, TestSocks5Connect) { - rtc::Socket* socket = - ss()->CreateSocket(kSocksProxyIntAddr.family(), SOCK_STREAM); - rtc::AsyncSocksProxySocket* proxy_socket = new rtc::AsyncSocksProxySocket( - socket, kSocksProxyIntAddr, "", rtc::CryptString()); - // TODO: IPv6-ize these tests when proxy supports IPv6. - - rtc::TestEchoServer server(rtc::Thread::Current(), - SocketAddress(INADDR_ANY, 0)); - - std::unique_ptr packet_socket( - rtc::AsyncTCPSocket::Create(proxy_socket, SocketAddress(INADDR_ANY, 0), - server.address())); - EXPECT_TRUE(packet_socket != nullptr); - rtc::TestClient client(std::move(packet_socket)); - - EXPECT_EQ(Socket::CS_CONNECTING, proxy_socket->GetState()); - EXPECT_TRUE(client.CheckConnected()); - EXPECT_EQ(Socket::CS_CONNECTED, proxy_socket->GetState()); - EXPECT_EQ(server.address(), client.remote_address()); - client.Send("foo", 3); - EXPECT_TRUE(client.CheckNextPacket("foo", 3, nullptr)); - EXPECT_TRUE(client.CheckNoPacket()); -} diff --git a/rtc_base/server_socket_adapters.cc b/rtc_base/server_socket_adapters.cc index 0bef752f1e..5a4db26dd2 100644 --- a/rtc_base/server_socket_adapters.cc +++ b/rtc_base/server_socket_adapters.cc @@ -55,135 +55,4 @@ void AsyncSSLServerSocket::ProcessInput(char* data, size_t* len) { BufferInput(false); } -AsyncSocksProxyServerSocket::AsyncSocksProxyServerSocket(Socket* socket) - : AsyncProxyServerSocket(socket, kBufferSize), state_(SS_HELLO) { - BufferInput(true); -} - -void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) { - RTC_DCHECK(state_ < SS_CONNECT_PENDING); - - ByteBufferReader response( - rtc::MakeArrayView(reinterpret_cast(data), *len)); - if (state_ == SS_HELLO) { - HandleHello(&response); - } else if (state_ == SS_AUTH) { - HandleAuth(&response); - } else if (state_ == SS_CONNECT) { - HandleConnect(&response); - } - - // Consume parsed data - *len = response.Length(); - if (response.Length() > 0) { - memmove(data, response.DataView().data(), *len); - } -} - -void AsyncSocksProxyServerSocket::DirectSend(const ByteBufferWriter& buf) { - BufferedReadAdapter::DirectSend(buf.Data(), buf.Length()); -} - -void AsyncSocksProxyServerSocket::HandleHello(ByteBufferReader* request) { - uint8_t ver, num_methods; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&num_methods)) { - Error(0); - return; - } - - if (ver != 5) { - Error(0); - return; - } - - // Handle either no-auth (0) or user/pass auth (2) - uint8_t method = 0xFF; - if (num_methods > 0 && !request->ReadUInt8(&method)) { - Error(0); - return; - } - - SendHelloReply(method); - if (method == 0) { - state_ = SS_CONNECT; - } else if (method == 2) { - state_ = SS_AUTH; - } else { - state_ = SS_ERROR; - } -} - -void AsyncSocksProxyServerSocket::SendHelloReply(uint8_t method) { - ByteBufferWriter response; - response.WriteUInt8(5); // Socks Version - response.WriteUInt8(method); // Auth method - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleAuth(ByteBufferReader* request) { - uint8_t ver, user_len, pass_len; - std::string user, pass; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&user_len) || - !request->ReadString(&user, user_len) || !request->ReadUInt8(&pass_len) || - !request->ReadString(&pass, pass_len)) { - Error(0); - return; - } - - SendAuthReply(0); - state_ = SS_CONNECT; -} - -void AsyncSocksProxyServerSocket::SendAuthReply(uint8_t result) { - ByteBufferWriter response; - response.WriteUInt8(1); // Negotiation Version - response.WriteUInt8(result); - DirectSend(response); -} - -void AsyncSocksProxyServerSocket::HandleConnect(ByteBufferReader* request) { - uint8_t ver, command, reserved, addr_type; - uint32_t ip; - uint16_t port; - if (!request->ReadUInt8(&ver) || !request->ReadUInt8(&command) || - !request->ReadUInt8(&reserved) || !request->ReadUInt8(&addr_type) || - !request->ReadUInt32(&ip) || !request->ReadUInt16(&port)) { - Error(0); - return; - } - - if (ver != 5 || command != 1 || reserved != 0 || addr_type != 1) { - Error(0); - return; - } - - SignalConnectRequest(this, SocketAddress(ip, port)); - state_ = SS_CONNECT_PENDING; -} - -void AsyncSocksProxyServerSocket::SendConnectResult(int result, - const SocketAddress& addr) { - if (state_ != SS_CONNECT_PENDING) - return; - - ByteBufferWriter response; - response.WriteUInt8(5); // Socks version - response.WriteUInt8((result != 0)); // 0x01 is generic error - response.WriteUInt8(0); // reserved - response.WriteUInt8(1); // IPv4 address - response.WriteUInt32(addr.ip()); - response.WriteUInt16(addr.port()); - DirectSend(response); - BufferInput(false); - state_ = SS_TUNNEL; -} - -void AsyncSocksProxyServerSocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - } // namespace rtc diff --git a/rtc_base/server_socket_adapters.h b/rtc_base/server_socket_adapters.h index b18c7a6a65..05dcd292f8 100644 --- a/rtc_base/server_socket_adapters.h +++ b/rtc_base/server_socket_adapters.h @@ -38,40 +38,6 @@ class AsyncSSLServerSocket : public BufferedReadAdapter { void ProcessInput(char* data, size_t* len) override; }; -// Implements a proxy server socket for the SOCKS protocol. -class AsyncSocksProxyServerSocket : public AsyncProxyServerSocket { - public: - explicit AsyncSocksProxyServerSocket(Socket* socket); - - AsyncSocksProxyServerSocket(const AsyncSocksProxyServerSocket&) = delete; - AsyncSocksProxyServerSocket& operator=(const AsyncSocksProxyServerSocket&) = - delete; - - private: - void ProcessInput(char* data, size_t* len) override; - void DirectSend(const ByteBufferWriter& buf); - - void HandleHello(ByteBufferReader* request); - void SendHelloReply(uint8_t method); - void HandleAuth(ByteBufferReader* request); - void SendAuthReply(uint8_t result); - void HandleConnect(ByteBufferReader* request); - void SendConnectResult(int result, const SocketAddress& addr) override; - - void Error(int error); - - static const int kBufferSize = 1024; - enum State { - SS_HELLO, - SS_AUTH, - SS_CONNECT, - SS_CONNECT_PENDING, - SS_TUNNEL, - SS_ERROR - }; - State state_; -}; - } // namespace rtc #endif // RTC_BASE_SERVER_SOCKET_ADAPTERS_H_ diff --git a/rtc_base/socket_adapters.cc b/rtc_base/socket_adapters.cc index a1eee5bd67..f6fa182f5d 100644 --- a/rtc_base/socket_adapters.cc +++ b/rtc_base/socket_adapters.cc @@ -469,198 +469,4 @@ void AsyncHttpsProxySocket::Error(int error) { SignalCloseEvent(this, error); } -/////////////////////////////////////////////////////////////////////////////// - -AsyncSocksProxySocket::AsyncSocksProxySocket(Socket* socket, - const SocketAddress& proxy, - absl::string_view username, - const CryptString& password) - : BufferedReadAdapter(socket, 1024), - state_(SS_ERROR), - proxy_(proxy), - user_(username), - pass_(password) {} - -AsyncSocksProxySocket::~AsyncSocksProxySocket() = default; - -int AsyncSocksProxySocket::Connect(const SocketAddress& addr) { - int ret; - dest_ = addr; - state_ = SS_INIT; - BufferInput(true); - ret = BufferedReadAdapter::Connect(proxy_); - // TODO: Set state_ appropriately if Connect fails. - return ret; -} - -SocketAddress AsyncSocksProxySocket::GetRemoteAddress() const { - return dest_; -} - -int AsyncSocksProxySocket::Close() { - state_ = SS_ERROR; - dest_.Clear(); - return BufferedReadAdapter::Close(); -} - -Socket::ConnState AsyncSocksProxySocket::GetState() const { - if (state_ < SS_TUNNEL) { - return CS_CONNECTING; - } else if (state_ == SS_TUNNEL) { - return CS_CONNECTED; - } else { - return CS_CLOSED; - } -} - -void AsyncSocksProxySocket::OnConnectEvent(Socket* socket) { - SendHello(); -} - -void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) { - RTC_DCHECK(state_ < SS_TUNNEL); - - ByteBufferReader response( - rtc::MakeArrayView(reinterpret_cast(data), *len)); - - if (state_ == SS_HELLO) { - uint8_t ver, method; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&method)) - return; - - if (ver != 5) { - Error(0); - return; - } - - if (method == 0) { - SendConnect(); - } else if (method == 2) { - SendAuth(); - } else { - Error(0); - return; - } - } else if (state_ == SS_AUTH) { - uint8_t ver, status; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&status)) - return; - - if ((ver != 1) || (status != 0)) { - Error(SOCKET_EACCES); - return; - } - - SendConnect(); - } else if (state_ == SS_CONNECT) { - uint8_t ver, rep, rsv, atyp; - if (!response.ReadUInt8(&ver) || !response.ReadUInt8(&rep) || - !response.ReadUInt8(&rsv) || !response.ReadUInt8(&atyp)) - return; - - if ((ver != 5) || (rep != 0)) { - Error(0); - return; - } - - uint16_t port; - if (atyp == 1) { - uint32_t addr; - if (!response.ReadUInt32(&addr) || !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 3) { - uint8_t length; - std::string addr; - if (!response.ReadUInt8(&length) || !response.ReadString(&addr, length) || - !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on " << addr << ":" << port; - } else if (atyp == 4) { - std::string addr; - if (!response.ReadString(&addr, 16) || !response.ReadUInt16(&port)) - return; - RTC_LOG(LS_VERBOSE) << "Bound on :" << port; - } else { - Error(0); - return; - } - - state_ = SS_TUNNEL; - } - - // Consume parsed data - *len = response.Length(); - memmove(data, response.Data(), *len); - - if (state_ != SS_TUNNEL) - return; - - bool remainder = (*len > 0); - BufferInput(false); - SignalConnectEvent(this); - - // FIX: if SignalConnect causes the socket to be destroyed, we are in trouble - if (remainder) - SignalReadEvent(this); // TODO: signal this?? -} - -void AsyncSocksProxySocket::SendHello() { - ByteBufferWriter request; - request.WriteUInt8(5); // Socks Version - if (user_.empty()) { - request.WriteUInt8(1); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - } else { - request.WriteUInt8(2); // Authentication Mechanisms - request.WriteUInt8(0); // No authentication - request.WriteUInt8(2); // Username/Password - } - DirectSend(request.Data(), request.Length()); - state_ = SS_HELLO; -} - -void AsyncSocksProxySocket::SendAuth() { - ByteBufferWriterT> request; - request.WriteUInt8(1); // Negotiation Version - request.WriteUInt8(static_cast(user_.size())); - request.WriteString(user_); // Username - request.WriteUInt8(static_cast(pass_.GetLength())); - size_t len = pass_.GetLength() + 1; - char* sensitive = new char[len]; - pass_.CopyTo(sensitive, true); - request.WriteString(std::string(sensitive, pass_.GetLength())); // Password - ExplicitZeroMemory(sensitive, len); - delete[] sensitive; - DirectSend(request.Data(), request.Length()); - state_ = SS_AUTH; -} - -void AsyncSocksProxySocket::SendConnect() { - ByteBufferWriter request; - request.WriteUInt8(5); // Socks Version - request.WriteUInt8(1); // CONNECT - request.WriteUInt8(0); // Reserved - if (dest_.IsUnresolvedIP()) { - std::string hostname = dest_.hostname(); - request.WriteUInt8(3); // DOMAINNAME - request.WriteUInt8(static_cast(hostname.size())); - request.WriteString(hostname); // Destination Hostname - } else { - request.WriteUInt8(1); // IPV4 - request.WriteUInt32(dest_.ip()); // Destination IP - } - request.WriteUInt16(dest_.port()); // Destination Port - DirectSend(request.Data(), request.Length()); - state_ = SS_CONNECT; -} - -void AsyncSocksProxySocket::Error(int error) { - state_ = SS_ERROR; - BufferInput(false); - Close(); - SetError(SOCKET_EACCES); - SignalCloseEvent(this, error); -} - } // namespace rtc diff --git a/rtc_base/socket_adapters.h b/rtc_base/socket_adapters.h index e78ee18a27..e67c8d4db9 100644 --- a/rtc_base/socket_adapters.h +++ b/rtc_base/socket_adapters.h @@ -137,42 +137,6 @@ class AsyncHttpsProxySocket : public BufferedReadAdapter { std::string unknown_mechanisms_; }; -/////////////////////////////////////////////////////////////////////////////// - -// Implements a socket adapter that speaks the SOCKS proxy protocol. -class AsyncSocksProxySocket : public BufferedReadAdapter { - public: - AsyncSocksProxySocket(Socket* socket, - const SocketAddress& proxy, - absl::string_view username, - const CryptString& password); - ~AsyncSocksProxySocket() override; - - AsyncSocksProxySocket(const AsyncSocksProxySocket&) = delete; - AsyncSocksProxySocket& operator=(const AsyncSocksProxySocket&) = delete; - - int Connect(const SocketAddress& addr) override; - SocketAddress GetRemoteAddress() const override; - int Close() override; - ConnState GetState() const override; - - protected: - void OnConnectEvent(Socket* socket) override; - void ProcessInput(char* data, size_t* len) override; - - void SendHello(); - void SendConnect(); - void SendAuth(); - void Error(int error); - - private: - enum State { SS_INIT, SS_HELLO, SS_AUTH, SS_CONNECT, SS_TUNNEL, SS_ERROR }; - State state_; - SocketAddress proxy_, dest_; - std::string user_; - CryptString pass_; -}; - } // namespace rtc #endif // RTC_BASE_SOCKET_ADAPTERS_H_ From 53e41a2bc66ae550a9fe9b84114f910690e8da9e Mon Sep 17 00:00:00 2001 From: Jakob Ivarsson Date: Thu, 1 Feb 2024 15:11:37 +0100 Subject: [PATCH 060/170] Ignore old, duplicate and overlapping packets in packet arrival history. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should mostly be a noop, but in a follow up cl we will insert all packets after splitting, which will allow for adapting the delay to FEC (both RED and codec inband) that is useful for decoding (i.e. not already covered by primary packets). A slight behavior change is that reordered packets are no longer included in max delay calculation. Implementation details: - A map ordered by RTP timestamp is used to store the arrivals. - When inserting new packets, we check if the timestamp is too old, already exists or if the packet is fully covered by another packet (based on timestamp and packet duration). - Separate deques are used to keep track of "min" and "max" arrivals (as defined by ordering operators). The queues maintain a strictly increasing/decreasing order so that min/max is always at begin(). Bug: webrtc:13322 Change-Id: I8b6cf5afff77b4adc3c29745b95627e955715b5a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337184 Reviewed-by: Henrik Lundin Commit-Queue: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41656} --- modules/audio_coding/neteq/decision_logic.cc | 14 +- .../neteq/decision_logic_unittest.cc | 13 +- .../neteq/mock/mock_packet_arrival_history.h | 9 +- .../neteq/packet_arrival_history.cc | 131 +++++++++++------- .../neteq/packet_arrival_history.h | 79 +++++++---- .../neteq/packet_arrival_history_unittest.cc | 50 +++++-- 6 files changed, 188 insertions(+), 108 deletions(-) diff --git a/modules/audio_coding/neteq/decision_logic.cc b/modules/audio_coding/neteq/decision_logic.cc index 6648fd8709..f68c05767d 100644 --- a/modules/audio_coding/neteq/decision_logic.cc +++ b/modules/audio_coding/neteq/decision_logic.cc @@ -14,7 +14,6 @@ #include #include -#include #include "absl/types/optional.h" #include "api/neteq/neteq.h" @@ -22,7 +21,6 @@ #include "modules/audio_coding/neteq/packet_arrival_history.h" #include "modules/audio_coding/neteq/packet_buffer.h" #include "rtc_base/checks.h" -#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/experiments/struct_parameters_parser.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/safe_conversions.h" @@ -102,6 +100,7 @@ DecisionLogic::DecisionLogic( packet_arrival_history_(packet_arrival_history ? std::move(packet_arrival_history) : std::make_unique( + config.tick_timer, config_.packet_history_size_ms)), tick_timer_(config.tick_timer), disallow_time_stretching_(!config.allow_time_stretching), @@ -221,14 +220,14 @@ absl::optional DecisionLogic::PacketArrived( packet_length_samples_ = info.packet_length_samples; delay_manager_->SetPacketAudioLength(packet_length_samples_ * 1000 / fs_hz); } - int64_t time_now_ms = tick_timer_->ticks() * tick_timer_->ms_per_tick(); - packet_arrival_history_->Insert(info.main_timestamp, time_now_ms); - if (packet_arrival_history_->size() < 2) { + bool inserted = packet_arrival_history_->Insert(info.main_timestamp, + info.packet_length_samples); + if (!inserted || packet_arrival_history_->size() < 2) { // No meaningful delay estimate unless at least 2 packets have arrived. return absl::nullopt; } int arrival_delay_ms = - packet_arrival_history_->GetDelayMs(info.main_timestamp, time_now_ms); + packet_arrival_history_->GetDelayMs(info.main_timestamp); bool reordered = !packet_arrival_history_->IsNewestRtpTimestamp(info.main_timestamp); delay_manager_->Update(arrival_delay_ms, reordered); @@ -464,8 +463,7 @@ int DecisionLogic::GetPlayoutDelayMs( NetEqController::NetEqStatus status) const { uint32_t playout_timestamp = status.target_timestamp - status.sync_buffer_samples; - return packet_arrival_history_->GetDelayMs( - playout_timestamp, tick_timer_->ticks() * tick_timer_->ms_per_tick()); + return packet_arrival_history_->GetDelayMs(playout_timestamp); } } // namespace webrtc diff --git a/modules/audio_coding/neteq/decision_logic_unittest.cc b/modules/audio_coding/neteq/decision_logic_unittest.cc index 9e9902af50..4b306f2639 100644 --- a/modules/audio_coding/neteq/decision_logic_unittest.cc +++ b/modules/audio_coding/neteq/decision_logic_unittest.cc @@ -14,12 +14,10 @@ #include "api/neteq/neteq_controller.h" #include "api/neteq/tick_timer.h" -#include "modules/audio_coding/neteq/buffer_level_filter.h" #include "modules/audio_coding/neteq/delay_manager.h" #include "modules/audio_coding/neteq/mock/mock_buffer_level_filter.h" #include "modules/audio_coding/neteq/mock/mock_delay_manager.h" #include "modules/audio_coding/neteq/mock/mock_packet_arrival_history.h" -#include "test/field_trial.h" #include "test/gtest.h" namespace webrtc { @@ -64,7 +62,8 @@ class DecisionLogicTest : public ::testing::Test { mock_delay_manager_ = delay_manager.get(); auto buffer_level_filter = std::make_unique(); mock_buffer_level_filter_ = buffer_level_filter.get(); - auto packet_arrival_history = std::make_unique(); + auto packet_arrival_history = + std::make_unique(&tick_timer_); mock_packet_arrival_history_ = packet_arrival_history.get(); decision_logic_ = std::make_unique( config, std::move(delay_manager), std::move(buffer_level_filter), @@ -82,7 +81,7 @@ class DecisionLogicTest : public ::testing::Test { TEST_F(DecisionLogicTest, NormalOperation) { EXPECT_CALL(*mock_delay_manager_, TargetDelayMs()) .WillRepeatedly(Return(100)); - EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_, _)) + EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_)) .WillRepeatedly(Return(100)); EXPECT_CALL(*mock_packet_arrival_history_, GetMaxDelayMs()) .WillRepeatedly(Return(0)); @@ -98,7 +97,7 @@ TEST_F(DecisionLogicTest, NormalOperation) { TEST_F(DecisionLogicTest, Accelerate) { EXPECT_CALL(*mock_delay_manager_, TargetDelayMs()) .WillRepeatedly(Return(100)); - EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_, _)) + EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_)) .WillRepeatedly(Return(150)); EXPECT_CALL(*mock_packet_arrival_history_, GetMaxDelayMs()) .WillRepeatedly(Return(0)); @@ -114,7 +113,7 @@ TEST_F(DecisionLogicTest, Accelerate) { TEST_F(DecisionLogicTest, FastAccelerate) { EXPECT_CALL(*mock_delay_manager_, TargetDelayMs()) .WillRepeatedly(Return(100)); - EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_, _)) + EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_)) .WillRepeatedly(Return(500)); EXPECT_CALL(*mock_packet_arrival_history_, GetMaxDelayMs()) .WillRepeatedly(Return(0)); @@ -130,7 +129,7 @@ TEST_F(DecisionLogicTest, FastAccelerate) { TEST_F(DecisionLogicTest, PreemptiveExpand) { EXPECT_CALL(*mock_delay_manager_, TargetDelayMs()) .WillRepeatedly(Return(100)); - EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_, _)) + EXPECT_CALL(*mock_packet_arrival_history_, GetDelayMs(_)) .WillRepeatedly(Return(50)); EXPECT_CALL(*mock_packet_arrival_history_, GetMaxDelayMs()) .WillRepeatedly(Return(0)); diff --git a/modules/audio_coding/neteq/mock/mock_packet_arrival_history.h b/modules/audio_coding/neteq/mock/mock_packet_arrival_history.h index 1b2080cd94..d4217cf2f8 100644 --- a/modules/audio_coding/neteq/mock/mock_packet_arrival_history.h +++ b/modules/audio_coding/neteq/mock/mock_packet_arrival_history.h @@ -11,6 +11,7 @@ #ifndef MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_PACKET_ARRIVAL_HISTORY_H_ #define MODULES_AUDIO_CODING_NETEQ_MOCK_MOCK_PACKET_ARRIVAL_HISTORY_H_ +#include "api/neteq/tick_timer.h" #include "modules/audio_coding/neteq/packet_arrival_history.h" #include "test/gmock.h" @@ -18,12 +19,10 @@ namespace webrtc { class MockPacketArrivalHistory : public PacketArrivalHistory { public: - MockPacketArrivalHistory() : PacketArrivalHistory(0) {} + MockPacketArrivalHistory(const TickTimer* tick_timer) + : PacketArrivalHistory(tick_timer, 0) {} - MOCK_METHOD(int, - GetDelayMs, - (uint32_t rtp_timestamp, int64_t time_ms), - (const override)); + MOCK_METHOD(int, GetDelayMs, (uint32_t rtp_timestamp), (const override)); MOCK_METHOD(int, GetMaxDelayMs, (), (const override)); }; diff --git a/modules/audio_coding/neteq/packet_arrival_history.cc b/modules/audio_coding/neteq/packet_arrival_history.cc index 2077383f76..a36c8a2b06 100644 --- a/modules/audio_coding/neteq/packet_arrival_history.cc +++ b/modules/audio_coding/neteq/packet_arrival_history.cc @@ -11,95 +11,122 @@ #include "modules/audio_coding/neteq/packet_arrival_history.h" #include +#include #include "api/neteq/tick_timer.h" +#include "rtc_base/checks.h" namespace webrtc { -PacketArrivalHistory::PacketArrivalHistory(int window_size_ms) - : window_size_ms_(window_size_ms) {} +PacketArrivalHistory::PacketArrivalHistory(const TickTimer* tick_timer, + int window_size_ms) + : tick_timer_(tick_timer), window_size_ms_(window_size_ms) {} -void PacketArrivalHistory::Insert(uint32_t rtp_timestamp, - int64_t arrival_time_ms) { - RTC_DCHECK(sample_rate_khz_ > 0); - int64_t unwrapped_rtp_timestamp = timestamp_unwrapper_.Unwrap(rtp_timestamp); - if (!newest_rtp_timestamp_ || - unwrapped_rtp_timestamp > *newest_rtp_timestamp_) { - newest_rtp_timestamp_ = unwrapped_rtp_timestamp; +bool PacketArrivalHistory::Insert(uint32_t rtp_timestamp, + int packet_length_samples) { + int64_t arrival_timestamp = + tick_timer_->ticks() * tick_timer_->ms_per_tick() * sample_rate_khz_; + PacketArrival packet(timestamp_unwrapper_.Unwrap(rtp_timestamp), + arrival_timestamp, packet_length_samples); + if (IsObsolete(packet)) { + return false; } - history_.emplace_back(unwrapped_rtp_timestamp / sample_rate_khz_, - arrival_time_ms); - MaybeUpdateCachedArrivals(history_.back()); - while (history_.front().rtp_timestamp_ms + window_size_ms_ < - unwrapped_rtp_timestamp / sample_rate_khz_) { - if (&history_.front() == min_packet_arrival_) { - min_packet_arrival_ = nullptr; + if (Contains(packet)) { + return false; + } + history_.emplace(packet.rtp_timestamp, packet); + if (packet != history_.rbegin()->second) { + // Packet was reordered. + return true; + } + // Remove old packets. + while (IsObsolete(history_.begin()->second)) { + if (history_.begin()->second == min_packet_arrivals_.front()) { + min_packet_arrivals_.pop_front(); } - if (&history_.front() == max_packet_arrival_) { - max_packet_arrival_ = nullptr; + if (history_.begin()->second == max_packet_arrivals_.front()) { + max_packet_arrivals_.pop_front(); } - history_.pop_front(); + history_.erase(history_.begin()); } - if (!min_packet_arrival_ || !max_packet_arrival_) { - for (const PacketArrival& packet : history_) { - MaybeUpdateCachedArrivals(packet); - } + // Ensure ordering constraints. + while (!min_packet_arrivals_.empty() && + packet <= min_packet_arrivals_.back()) { + min_packet_arrivals_.pop_back(); } -} - -void PacketArrivalHistory::MaybeUpdateCachedArrivals( - const PacketArrival& packet_arrival) { - if (!min_packet_arrival_ || packet_arrival <= *min_packet_arrival_) { - min_packet_arrival_ = &packet_arrival; - } - if (!max_packet_arrival_ || packet_arrival >= *max_packet_arrival_) { - max_packet_arrival_ = &packet_arrival; + while (!max_packet_arrivals_.empty() && + packet >= max_packet_arrivals_.back()) { + max_packet_arrivals_.pop_back(); } + min_packet_arrivals_.push_back(packet); + max_packet_arrivals_.push_back(packet); + return true; } void PacketArrivalHistory::Reset() { history_.clear(); - min_packet_arrival_ = nullptr; - max_packet_arrival_ = nullptr; + min_packet_arrivals_.clear(); + max_packet_arrivals_.clear(); timestamp_unwrapper_.Reset(); - newest_rtp_timestamp_ = absl::nullopt; } -int PacketArrivalHistory::GetDelayMs(uint32_t rtp_timestamp, - int64_t time_ms) const { - RTC_DCHECK(sample_rate_khz_ > 0); - int64_t unwrapped_rtp_timestamp_ms = - timestamp_unwrapper_.PeekUnwrap(rtp_timestamp) / sample_rate_khz_; - PacketArrival packet(unwrapped_rtp_timestamp_ms, time_ms); +int PacketArrivalHistory::GetDelayMs(uint32_t rtp_timestamp) const { + int64_t unwrapped_rtp_timestamp = + timestamp_unwrapper_.PeekUnwrap(rtp_timestamp); + int64_t current_timestamp = + tick_timer_->ticks() * tick_timer_->ms_per_tick() * sample_rate_khz_; + PacketArrival packet(unwrapped_rtp_timestamp, current_timestamp, + /*duration_ms=*/0); return GetPacketArrivalDelayMs(packet); } int PacketArrivalHistory::GetMaxDelayMs() const { - if (!max_packet_arrival_) { + if (max_packet_arrivals_.empty()) { return 0; } - return GetPacketArrivalDelayMs(*max_packet_arrival_); + return GetPacketArrivalDelayMs(max_packet_arrivals_.front()); } bool PacketArrivalHistory::IsNewestRtpTimestamp(uint32_t rtp_timestamp) const { - if (!newest_rtp_timestamp_) { - return false; + if (history_.empty()) { + return true; } int64_t unwrapped_rtp_timestamp = timestamp_unwrapper_.PeekUnwrap(rtp_timestamp); - return unwrapped_rtp_timestamp == *newest_rtp_timestamp_; + return unwrapped_rtp_timestamp == history_.rbegin()->second.rtp_timestamp; } int PacketArrivalHistory::GetPacketArrivalDelayMs( const PacketArrival& packet_arrival) const { - if (!min_packet_arrival_) { + if (min_packet_arrivals_.empty()) { return 0; } - return std::max(static_cast(packet_arrival.arrival_time_ms - - min_packet_arrival_->arrival_time_ms - - (packet_arrival.rtp_timestamp_ms - - min_packet_arrival_->rtp_timestamp_ms)), - 0); + RTC_DCHECK_NE(sample_rate_khz_, 0); + // TODO(jakobi): Timestamps are first converted to millis for bit-exactness. + return std::max( + packet_arrival.arrival_timestamp / sample_rate_khz_ - + min_packet_arrivals_.front().arrival_timestamp / sample_rate_khz_ - + (packet_arrival.rtp_timestamp / sample_rate_khz_ - + min_packet_arrivals_.front().rtp_timestamp / sample_rate_khz_), + 0); +} + +bool PacketArrivalHistory::IsObsolete( + const PacketArrival& packet_arrival) const { + if (history_.empty()) { + return false; + } + return packet_arrival.rtp_timestamp + window_size_ms_ * sample_rate_khz_ < + history_.rbegin()->second.rtp_timestamp; +} + +bool PacketArrivalHistory::Contains(const PacketArrival& packet_arrival) const { + auto it = history_.upper_bound(packet_arrival.rtp_timestamp); + if (it == history_.begin()) { + return false; + } + --it; + return it->second.contains(packet_arrival); } } // namespace webrtc diff --git a/modules/audio_coding/neteq/packet_arrival_history.h b/modules/audio_coding/neteq/packet_arrival_history.h index 722caf5688..3fa1ea1fa9 100644 --- a/modules/audio_coding/neteq/packet_arrival_history.h +++ b/modules/audio_coding/neteq/packet_arrival_history.h @@ -11,10 +11,11 @@ #ifndef MODULES_AUDIO_CODING_NETEQ_PACKET_ARRIVAL_HISTORY_H_ #define MODULES_AUDIO_CODING_NETEQ_PACKET_ARRIVAL_HISTORY_H_ +#include #include #include +#include -#include "absl/types/optional.h" #include "api/neteq/tick_timer.h" #include "rtc_base/numerics/sequence_number_unwrapper.h" @@ -25,19 +26,22 @@ namespace webrtc { // pruned. class PacketArrivalHistory { public: - explicit PacketArrivalHistory(int window_size_ms); + explicit PacketArrivalHistory(const TickTimer* tick_timer, + int window_size_ms); virtual ~PacketArrivalHistory() = default; - // Insert packet with `rtp_timestamp` and `arrival_time_ms` into the history. - void Insert(uint32_t rtp_timestamp, int64_t arrival_time_ms); + // Insert packet with `rtp_timestamp` into the history. Returns true if the + // packet was inserted, false if the timestamp is too old or if the timestamp + // already exists. + bool Insert(uint32_t rtp_timestamp, int packet_length_samples); - // The delay for `rtp_timestamp` at `time_ms` is calculated as - // `(time_ms - p.arrival_time_ms) - (rtp_timestamp - p.rtp_timestamp)` - // where `p` is chosen as the packet arrival in the history that maximizes the - // delay. - virtual int GetDelayMs(uint32_t rtp_timestamp, int64_t time_ms) const; + // The delay for `rtp_timestamp` at time `now` is calculated as + // `(now - p.arrival_timestamp) - (rtp_timestamp - p.rtp_timestamp)` where `p` + // is chosen as the packet arrival in the history that maximizes the delay. + virtual int GetDelayMs(uint32_t rtp_timestamp) const; - // Get the maximum packet arrival delay observed in the history. + // Get the maximum packet arrival delay observed in the history, excluding + // reordered packets. virtual int GetMaxDelayMs() const; bool IsNewestRtpTimestamp(uint32_t rtp_timestamp) const; @@ -52,30 +56,53 @@ class PacketArrivalHistory { private: struct PacketArrival { - PacketArrival(int64_t rtp_timestamp_ms, int64_t arrival_time_ms) - : rtp_timestamp_ms(rtp_timestamp_ms), - arrival_time_ms(arrival_time_ms) {} - int64_t rtp_timestamp_ms; - int64_t arrival_time_ms; + PacketArrival(int64_t rtp_timestamp, + int64_t arrival_timestamp, + int length_samples) + : rtp_timestamp(rtp_timestamp), + arrival_timestamp(arrival_timestamp), + length_samples(length_samples) {} + PacketArrival() = default; + int64_t rtp_timestamp; + int64_t arrival_timestamp; + int length_samples; + bool operator==(const PacketArrival& other) const { + return rtp_timestamp == other.rtp_timestamp && + arrival_timestamp == other.arrival_timestamp && + length_samples == other.length_samples; + } + bool operator!=(const PacketArrival& other) const { + return !(*this == other); + } bool operator<=(const PacketArrival& other) const { - return arrival_time_ms - rtp_timestamp_ms <= - other.arrival_time_ms - other.rtp_timestamp_ms; + return arrival_timestamp - rtp_timestamp <= + other.arrival_timestamp - other.rtp_timestamp; } bool operator>=(const PacketArrival& other) const { - return arrival_time_ms - rtp_timestamp_ms >= - other.arrival_time_ms - other.rtp_timestamp_ms; + return arrival_timestamp - rtp_timestamp >= + other.arrival_timestamp - other.rtp_timestamp; + } + bool contains(const PacketArrival& other) const { + return rtp_timestamp <= other.rtp_timestamp && + rtp_timestamp + length_samples >= + other.rtp_timestamp + other.length_samples; } }; - std::deque history_; int GetPacketArrivalDelayMs(const PacketArrival& packet_arrival) const; - // Updates `min_packet_arrival_` and `max_packet_arrival_`. - void MaybeUpdateCachedArrivals(const PacketArrival& packet); - const PacketArrival* min_packet_arrival_ = nullptr; - const PacketArrival* max_packet_arrival_ = nullptr; + // Checks if the packet is older than the window size. + bool IsObsolete(const PacketArrival& packet_arrival) const; + // Check if the packet exists or fully overlaps with a packet in the history. + bool Contains(const PacketArrival& packet_arrival) const; + const TickTimer* tick_timer_; const int window_size_ms_; - RtpTimestampUnwrapper timestamp_unwrapper_; - absl::optional newest_rtp_timestamp_; int sample_rate_khz_ = 0; + RtpTimestampUnwrapper timestamp_unwrapper_; + // Packet history ordered by rtp timestamp. + std::map history_; + // Tracks min/max packet arrivals in `history_` in ascending/descending order. + // Reordered packets are excluded. + std::deque min_packet_arrivals_; + std::deque max_packet_arrivals_; }; } // namespace webrtc diff --git a/modules/audio_coding/neteq/packet_arrival_history_unittest.cc b/modules/audio_coding/neteq/packet_arrival_history_unittest.cc index 539a318fe1..dd95fec0f7 100644 --- a/modules/audio_coding/neteq/packet_arrival_history_unittest.cc +++ b/modules/audio_coding/neteq/packet_arrival_history_unittest.cc @@ -21,32 +21,36 @@ namespace { constexpr int kFs = 8000; constexpr int kFsKhz = kFs / 1000; constexpr int kFrameSizeMs = 20; +constexpr int kFrameSizeSamples = kFrameSizeMs * kFsKhz; constexpr int kWindowSizeMs = 1000; class PacketArrivalHistoryTest : public testing::Test { public: - PacketArrivalHistoryTest() : history_(kWindowSizeMs) { + PacketArrivalHistoryTest() : history_(&tick_timer_, kWindowSizeMs) { history_.set_sample_rate(kFs); } - void IncrementTime(int delta_ms) { time_ms_ += delta_ms; } + void IncrementTime(int delta_ms) { + tick_timer_.Increment(delta_ms / tick_timer_.ms_per_tick()); + } int InsertPacketAndGetDelay(int timestamp_delta_ms) { uint32_t timestamp = timestamp_ + timestamp_delta_ms * kFsKhz; if (timestamp_delta_ms > 0) { timestamp_ = timestamp; } - history_.Insert(timestamp, time_ms_); + EXPECT_TRUE(history_.Insert(timestamp, kFrameSizeSamples)); EXPECT_EQ(history_.IsNewestRtpTimestamp(timestamp), timestamp_delta_ms >= 0); - return history_.GetDelayMs(timestamp, time_ms_); + return history_.GetDelayMs(timestamp); } protected: - int64_t time_ms_ = 0; + TickTimer tick_timer_; PacketArrivalHistory history_; uint32_t timestamp_ = 0x12345678; }; TEST_F(PacketArrivalHistoryTest, RelativeArrivalDelay) { + // Insert first packet. EXPECT_EQ(InsertPacketAndGetDelay(0), 0); IncrementTime(kFrameSizeMs); @@ -56,7 +60,7 @@ TEST_F(PacketArrivalHistoryTest, RelativeArrivalDelay) { EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 20); // Reordered packet. - EXPECT_EQ(InsertPacketAndGetDelay(-2 * kFrameSizeMs), 60); + EXPECT_EQ(InsertPacketAndGetDelay(-3 * kFrameSizeMs), 80); IncrementTime(2 * kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 40); @@ -68,7 +72,7 @@ TEST_F(PacketArrivalHistoryTest, RelativeArrivalDelay) { EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 20); // Earlier packet is now more delayed due to the new reference packet. - EXPECT_EQ(history_.GetMaxDelayMs(), 100); + EXPECT_EQ(history_.GetMaxDelayMs(), 80); } TEST_F(PacketArrivalHistoryTest, ReorderedPackets) { @@ -86,7 +90,7 @@ TEST_F(PacketArrivalHistoryTest, ReorderedPackets) { IncrementTime(4 * kFrameSizeMs); EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 60); - EXPECT_EQ(history_.GetMaxDelayMs(), 80); + EXPECT_EQ(history_.GetMaxDelayMs(), 60); } TEST_F(PacketArrivalHistoryTest, MaxHistorySize) { @@ -117,7 +121,7 @@ TEST_F(PacketArrivalHistoryTest, TimestampWraparound) { // Insert another in-order packet after the wraparound. EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 0); - EXPECT_EQ(history_.GetMaxDelayMs(), 3 * kFrameSizeMs); + EXPECT_EQ(history_.GetMaxDelayMs(), kFrameSizeMs); } TEST_F(PacketArrivalHistoryTest, TimestampWraparoundBackwards) { @@ -134,7 +138,33 @@ TEST_F(PacketArrivalHistoryTest, TimestampWraparoundBackwards) { // Insert another in-order packet after the wraparound. EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 0); - EXPECT_EQ(history_.GetMaxDelayMs(), 3 * kFrameSizeMs); + EXPECT_EQ(history_.GetMaxDelayMs(), kFrameSizeMs); +} + +TEST_F(PacketArrivalHistoryTest, OldPacketShouldNotBeInserted) { + // Insert first packet as reference. + EXPECT_EQ(InsertPacketAndGetDelay(0), 0); + // Insert packet with timestamp older than the window size compared to the + // first packet. + EXPECT_FALSE(history_.Insert(timestamp_ - kWindowSizeMs * kFsKhz - 1, + kFrameSizeSamples)); +} + +TEST_F(PacketArrivalHistoryTest, DuplicatePacketShouldNotBeInserted) { + // Insert first packet as reference. + uint32_t first_timestamp = timestamp_; + EXPECT_EQ(InsertPacketAndGetDelay(0), 0); + EXPECT_EQ(InsertPacketAndGetDelay(kFrameSizeMs), 0); + // Same timestamp as the first packet. + EXPECT_FALSE(history_.Insert(first_timestamp, kFrameSizeSamples)); +} + +TEST_F(PacketArrivalHistoryTest, OverlappingPacketShouldNotBeInserted) { + // Insert first packet as reference. + EXPECT_EQ(InsertPacketAndGetDelay(0), 0); + // 10 ms overlap with the previous packet. + EXPECT_FALSE(history_.Insert(timestamp_ + kFrameSizeSamples / 2, + kFrameSizeSamples / 2)); } } // namespace From 687ef0a136873c32c6e7d65c68f2cfcb03a717a0 Mon Sep 17 00:00:00 2001 From: Jeremy Leconte Date: Thu, 1 Feb 2024 15:11:31 +0000 Subject: [PATCH 061/170] Revert "Remove post-decode VAD" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 89cf26f1e0532130745f648cf16b1fb8af2f6b4f. Reason for revert: breaking upstream projects Original change's description: > Remove post-decode VAD > > Bug: webrtc:15806 > Change-Id: I6acf8734a70703085cfc1ccf82a79ee0931f59a4 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336460 > Reviewed-by: Sam Zackrisson > Commit-Queue: Tomas Lundqvist > Reviewed-by: Jakob Ivarsson‎ > Cr-Commit-Position: refs/heads/main@{#41653} Bug: webrtc:15806 Change-Id: I20e383a6b6d625d86830ecec1be01b42b22e86a2 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337420 Bot-Commit: rubber-stamper@appspot.gserviceaccount.com Owners-Override: Jeremy Leconte Commit-Queue: Jeremy Leconte Reviewed-by: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41657} --- api/neteq/neteq.cc | 3 +- api/neteq/neteq.h | 8 ++ modules/audio_coding/BUILD.gn | 3 + modules/audio_coding/acm2/acm_receiver.cc | 6 +- .../acm2/acm_receiver_unittest.cc | 59 ++++++++++++ .../audio_coding/neteq/background_noise.cc | 29 +++--- modules/audio_coding/neteq/background_noise.h | 4 +- modules/audio_coding/neteq/neteq_impl.cc | 71 +++++++++++++-- modules/audio_coding/neteq/neteq_impl.h | 11 +++ modules/audio_coding/neteq/post_decode_vad.cc | 90 +++++++++++++++++++ modules/audio_coding/neteq/post_decode_vad.h | 71 +++++++++++++++ .../neteq/post_decode_vad_unittest.cc | 25 ++++++ test/fuzzers/neteq_signal_fuzzer.cc | 1 + 13 files changed, 358 insertions(+), 23 deletions(-) create mode 100644 modules/audio_coding/neteq/post_decode_vad.cc create mode 100644 modules/audio_coding/neteq/post_decode_vad.h create mode 100644 modules/audio_coding/neteq/post_decode_vad_unittest.cc diff --git a/api/neteq/neteq.cc b/api/neteq/neteq.cc index d237def23a..155ddf2cf3 100644 --- a/api/neteq/neteq.cc +++ b/api/neteq/neteq.cc @@ -24,7 +24,8 @@ NetEq::Config& NetEq::Config::operator=(Config&&) = default; std::string NetEq::Config::ToString() const { char buf[1024]; rtc::SimpleStringBuilder ss(buf); - ss << "sample_rate_hz=" << sample_rate_hz + ss << "sample_rate_hz=" << sample_rate_hz << ", enable_post_decode_vad=" + << (enable_post_decode_vad ? "true" : "false") << ", max_packets_in_buffer=" << max_packets_in_buffer << ", min_delay_ms=" << min_delay_ms << ", enable_fast_accelerate=" << (enable_fast_accelerate ? "true" : "false") diff --git a/api/neteq/neteq.h b/api/neteq/neteq.h index fc0c090254..43e0e09784 100644 --- a/api/neteq/neteq.h +++ b/api/neteq/neteq.h @@ -130,6 +130,7 @@ class NetEq { std::string ToString() const; int sample_rate_hz = 48000; // Initial value. Will change with input data. + bool enable_post_decode_vad = false; size_t max_packets_in_buffer = 200; int max_delay_ms = 0; int min_delay_ms = 0; @@ -277,6 +278,13 @@ class NetEq { // statistics are never reset. virtual NetEqOperationsAndState GetOperationsAndState() const = 0; + // Enables post-decode VAD. When enabled, GetAudio() will return + // kOutputVADPassive when the signal contains no speech. + virtual void EnableVad() = 0; + + // Disables post-decode VAD. + virtual void DisableVad() = 0; + // Returns the RTP timestamp for the last sample delivered by GetAudio(). // The return value will be empty if no valid timestamp is available. virtual absl::optional GetPlayoutTimestamp() const = 0; diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index 8b23955d5b..5de99efa45 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -689,6 +689,8 @@ rtc_library("neteq") { "neteq/packet_arrival_history.h", "neteq/packet_buffer.cc", "neteq/packet_buffer.h", + "neteq/post_decode_vad.cc", + "neteq/post_decode_vad.h", "neteq/preemptive_expand.cc", "neteq/preemptive_expand.h", "neteq/random_vector.cc", @@ -1653,6 +1655,7 @@ if (rtc_include_tests) { "neteq/normal_unittest.cc", "neteq/packet_arrival_history_unittest.cc", "neteq/packet_buffer_unittest.cc", + "neteq/post_decode_vad_unittest.cc", "neteq/random_vector_unittest.cc", "neteq/red_payload_splitter_unittest.cc", "neteq/reorder_optimizer_unittest.cc", diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc index 24a49024c8..a77e472ec1 100644 --- a/modules/audio_coding/acm2/acm_receiver.cc +++ b/modules/audio_coding/acm2/acm_receiver.cc @@ -50,7 +50,11 @@ std::unique_ptr CreateNetEq( AcmReceiver::Config::Config( rtc::scoped_refptr decoder_factory) - : clock(*Clock::GetRealTimeClock()), decoder_factory(decoder_factory) {} + : clock(*Clock::GetRealTimeClock()), decoder_factory(decoder_factory) { + // Post-decode VAD is disabled by default in NetEq, however, Audio + // Conference Mixer relies on VAD decisions and fails without them. + neteq_config.enable_post_decode_vad = true; +} AcmReceiver::Config::Config(const Config&) = default; AcmReceiver::Config::~Config() = default; diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc index 8b35f4a621..cda6688157 100644 --- a/modules/audio_coding/acm2/acm_receiver_unittest.cc +++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc @@ -190,6 +190,9 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { const size_t output_channels = info.num_channels; const size_t samples_per_ms = rtc::checked_cast( rtc::CheckedDivExact(output_sample_rate_hz, 1000)); + const AudioFrame::VADActivity expected_vad_activity = + output_sample_rate_hz > 16000 ? AudioFrame::kVadActive + : AudioFrame::kVadPassive; // Expect the first output timestamp to be 5*fs/8000 samples before the // first inserted timestamp (because of NetEq's look-ahead). (This value is @@ -214,6 +217,7 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { EXPECT_EQ(output_sample_rate_hz, frame.sample_rate_hz_); EXPECT_EQ(output_channels, frame.num_channels_); EXPECT_EQ(AudioFrame::kNormalSpeech, frame.speech_type_); + EXPECT_EQ(expected_vad_activity, frame.vad_activity_); EXPECT_FALSE(muted); } } @@ -238,6 +242,61 @@ TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) { RunVerifyAudioFrame({"opus", 48000, 2}); } +#if defined(WEBRTC_ANDROID) +#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad +#else +#define MAYBE_PostdecodingVad PostdecodingVad +#endif +TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) { + EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad); + constexpr int payload_type = 34; + const SdpAudioFormat codec = {"L16", 16000, 1}; + const AudioCodecInfo info = SetEncoder(payload_type, codec); + receiver_->SetCodecs({{payload_type, codec}}); + constexpr int kNumPackets = 5; + AudioFrame frame; + for (int n = 0; n < kNumPackets; ++n) { + const int num_10ms_frames = InsertOnePacketOfSilence(info); + for (int k = 0; k < num_10ms_frames; ++k) { + bool muted; + ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); + } + } + EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_); +} + +class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi { + protected: + AcmReceiverTestPostDecodeVadPassiveOldApi() { + config_.neteq_config.enable_post_decode_vad = false; + } +}; + +#if defined(WEBRTC_ANDROID) +#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad +#else +#define MAYBE_PostdecodingVad PostdecodingVad +#endif +TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) { + EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad); + constexpr int payload_type = 34; + const SdpAudioFormat codec = {"L16", 16000, 1}; + const AudioCodecInfo info = SetEncoder(payload_type, codec); + auto const value = encoder_factory_->QueryAudioEncoder(codec); + ASSERT_TRUE(value.has_value()); + receiver_->SetCodecs({{payload_type, codec}}); + const int kNumPackets = 5; + AudioFrame frame; + for (int n = 0; n < kNumPackets; ++n) { + const int num_10ms_frames = InsertOnePacketOfSilence(info); + for (int k = 0; k < num_10ms_frames; ++k) { + bool muted; + ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); + } + } + EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_); +} + #if defined(WEBRTC_ANDROID) #define MAYBE_LastAudioCodec DISABLED_LastAudioCodec #else diff --git a/modules/audio_coding/neteq/background_noise.cc b/modules/audio_coding/neteq/background_noise.cc index 0c33dba47a..2c95d3b390 100644 --- a/modules/audio_coding/neteq/background_noise.cc +++ b/modules/audio_coding/neteq/background_noise.cc @@ -17,6 +17,7 @@ #include "common_audio/signal_processing/include/signal_processing_library.h" #include "modules/audio_coding/neteq/audio_multi_vector.h" #include "modules/audio_coding/neteq/cross_correlation.h" +#include "modules/audio_coding/neteq/post_decode_vad.h" namespace webrtc { namespace { @@ -43,11 +44,17 @@ void BackgroundNoise::Reset() { } } -bool BackgroundNoise::Update(const AudioMultiVector& sync_buffer) { +bool BackgroundNoise::Update(const AudioMultiVector& input, + const PostDecodeVad& vad) { bool filter_params_saved = false; + if (vad.running() && vad.active_speech()) { + // Do not update the background noise parameters if we know that the signal + // is active speech. + return filter_params_saved; + } int32_t auto_correlation[kMaxLpcOrder + 1]; - int16_t filter_output[kMaxLpcOrder + kResidualLength]; + int16_t fiter_output[kMaxLpcOrder + kResidualLength]; int16_t reflection_coefficients[kMaxLpcOrder]; int16_t lpc_coefficients[kMaxLpcOrder + 1]; @@ -55,13 +62,14 @@ bool BackgroundNoise::Update(const AudioMultiVector& sync_buffer) { ChannelParameters& parameters = channel_parameters_[channel_ix]; int16_t temp_signal_array[kVecLen + kMaxLpcOrder] = {0}; int16_t* temp_signal = &temp_signal_array[kMaxLpcOrder]; - RTC_DCHECK_GE(sync_buffer.Size(), kVecLen); - sync_buffer[channel_ix].CopyTo(kVecLen, sync_buffer.Size() - kVecLen, - temp_signal); + RTC_DCHECK_GE(input.Size(), kVecLen); + input[channel_ix].CopyTo(kVecLen, input.Size() - kVecLen, temp_signal); int32_t sample_energy = CalculateAutoCorrelation(temp_signal, kVecLen, auto_correlation); - if (sample_energy < parameters.energy_update_threshold) { + if ((!vad.running() && + sample_energy < parameters.energy_update_threshold) || + (vad.running() && !vad.active_speech())) { // Generate LPC coefficients. if (auto_correlation[0] <= 0) { // Center value in auto-correlation is not positive. Do not update. @@ -87,10 +95,10 @@ bool BackgroundNoise::Update(const AudioMultiVector& sync_buffer) { // Generate the CNG gain factor by looking at the energy of the residual. WebRtcSpl_FilterMAFastQ12(temp_signal + kVecLen - kResidualLength, - filter_output, lpc_coefficients, + fiter_output, lpc_coefficients, kMaxLpcOrder + 1, kResidualLength); int32_t residual_energy = WebRtcSpl_DotProductWithScale( - filter_output, filter_output, kResidualLength, 0); + fiter_output, fiter_output, kResidualLength, 0); // Check spectral flatness. // Comparing the residual variance with the input signal variance tells @@ -109,8 +117,9 @@ bool BackgroundNoise::Update(const AudioMultiVector& sync_buffer) { filter_params_saved = true; } } else { - // Will only happen if `sample_energy` is not low enough. Increase the - // threshold for update so that it increases by a factor 4 in 4 seconds. + // Will only happen if post-decode VAD is disabled and `sample_energy` is + // not low enough. Increase the threshold for update so that it increases + // by a factor 4 in 4 seconds. IncrementEnergyThreshold(channel_ix, sample_energy); } } diff --git a/modules/audio_coding/neteq/background_noise.h b/modules/audio_coding/neteq/background_noise.h index 9ef0131c92..8e6d5890a0 100644 --- a/modules/audio_coding/neteq/background_noise.h +++ b/modules/audio_coding/neteq/background_noise.h @@ -39,9 +39,9 @@ class BackgroundNoise { void Reset(); // Updates the parameter estimates based on the signal currently in the - // `sync_buffer`. + // `sync_buffer`, and on the latest decision in `vad` if it is running. // Returns true if the filter parameters are updated. - bool Update(const AudioMultiVector& sync_buffer); + bool Update(const AudioMultiVector& sync_buffer, const PostDecodeVad& vad); // Generates background noise given a random vector and writes the output to // `buffer`. diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc index 81b46e20e2..e5c8bf6c08 100644 --- a/modules/audio_coding/neteq/neteq_impl.cc +++ b/modules/audio_coding/neteq/neteq_impl.cc @@ -36,6 +36,7 @@ #include "modules/audio_coding/neteq/normal.h" #include "modules/audio_coding/neteq/packet.h" #include "modules/audio_coding/neteq/packet_buffer.h" +#include "modules/audio_coding/neteq/post_decode_vad.h" #include "modules/audio_coding/neteq/preemptive_expand.h" #include "modules/audio_coding/neteq/red_payload_splitter.h" #include "modules/audio_coding/neteq/statistics_calculator.h" @@ -69,26 +70,49 @@ std::unique_ptr CreateNetEqController( return controller_factory.CreateNetEqController(config); } -AudioFrame::SpeechType ToSpeechType(NetEqImpl::OutputType type) { +void SetAudioFrameActivityAndType(bool vad_enabled, + NetEqImpl::OutputType type, + AudioFrame::VADActivity last_vad_activity, + AudioFrame* audio_frame) { switch (type) { case NetEqImpl::OutputType::kNormalSpeech: { - return AudioFrame::kNormalSpeech; + audio_frame->speech_type_ = AudioFrame::kNormalSpeech; + audio_frame->vad_activity_ = AudioFrame::kVadActive; + break; + } + case NetEqImpl::OutputType::kVadPassive: { + // This should only be reached if the VAD is enabled. + RTC_DCHECK(vad_enabled); + audio_frame->speech_type_ = AudioFrame::kNormalSpeech; + audio_frame->vad_activity_ = AudioFrame::kVadPassive; + break; } case NetEqImpl::OutputType::kCNG: { - return AudioFrame::kCNG; + audio_frame->speech_type_ = AudioFrame::kCNG; + audio_frame->vad_activity_ = AudioFrame::kVadPassive; + break; } case NetEqImpl::OutputType::kPLC: { - return AudioFrame::kPLC; + audio_frame->speech_type_ = AudioFrame::kPLC; + audio_frame->vad_activity_ = last_vad_activity; + break; } case NetEqImpl::OutputType::kPLCCNG: { - return AudioFrame::kPLCCNG; + audio_frame->speech_type_ = AudioFrame::kPLCCNG; + audio_frame->vad_activity_ = AudioFrame::kVadPassive; + break; } case NetEqImpl::OutputType::kCodecPLC: { - return AudioFrame::kCodecPLC; + audio_frame->speech_type_ = AudioFrame::kCodecPLC; + audio_frame->vad_activity_ = last_vad_activity; + break; } default: RTC_DCHECK_NOTREACHED(); - return AudioFrame::kUndefined; + } + if (!vad_enabled) { + // Always set kVadUnknown when receive VAD is inactive. + audio_frame->vad_activity_ = AudioFrame::kVadUnknown; } } @@ -145,6 +169,7 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, packet_buffer_(std::move(deps.packet_buffer)), red_payload_splitter_(std::move(deps.red_payload_splitter)), timestamp_scaler_(std::move(deps.timestamp_scaler)), + vad_(new PostDecodeVad()), expand_factory_(std::move(deps.expand_factory)), accelerate_factory_(std::move(deps.accelerate_factory)), preemptive_expand_factory_(std::move(deps.preemptive_expand_factory)), @@ -186,6 +211,10 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, if (create_components) { SetSampleRateAndChannels(fs, 1); // Default is 1 channel. } + RTC_DCHECK(!vad_->enabled()); + if (config.enable_post_decode_vad) { + vad_->Enable(); + } } NetEqImpl::~NetEqImpl() = default; @@ -223,7 +252,9 @@ int NetEqImpl::GetAudio(AudioFrame* audio_frame, audio_frame->sample_rate_hz_, rtc::dchecked_cast(audio_frame->samples_per_channel_ * 100)); RTC_DCHECK_EQ(*muted, audio_frame->muted()); - audio_frame->speech_type_ = ToSpeechType(LastOutputType()); + SetAudioFrameActivityAndType(vad_->enabled(), LastOutputType(), + last_vad_activity_, audio_frame); + last_vad_activity_ = audio_frame->vad_activity_; last_output_sample_rate_hz_ = audio_frame->sample_rate_hz_; RTC_DCHECK(last_output_sample_rate_hz_ == 8000 || last_output_sample_rate_hz_ == 16000 || @@ -367,6 +398,18 @@ NetEqOperationsAndState NetEqImpl::GetOperationsAndState() const { return result; } +void NetEqImpl::EnableVad() { + MutexLock lock(&mutex_); + RTC_DCHECK(vad_.get()); + vad_->Enable(); +} + +void NetEqImpl::DisableVad() { + MutexLock lock(&mutex_); + RTC_DCHECK(vad_.get()); + vad_->Disable(); +} + absl::optional NetEqImpl::GetPlayoutTimestamp() const { MutexLock lock(&mutex_); if (first_packet_ || last_mode_ == Mode::kRfc3389Cng || @@ -815,8 +858,11 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, last_decoded_type_ = speech_type; } + RTC_DCHECK(vad_.get()); bool sid_frame_available = (operation == Operation::kRfc3389Cng && !packet_list.empty()); + vad_->Update(decoded_buffer_.get(), static_cast(length), speech_type, + sid_frame_available, fs_hz_); // This is the criterion that we did decode some data through the speech // decoder, and the operation resulted in comfort noise. @@ -966,7 +1012,7 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, (last_mode_ == Mode::kPreemptiveExpandFail) || (last_mode_ == Mode::kRfc3389Cng) || (last_mode_ == Mode::kCodecInternalCng)) { - background_noise_->Update(*sync_buffer_); + background_noise_->Update(*sync_buffer_, *vad_.get()); } if (operation == Operation::kDtmf) { @@ -2042,6 +2088,10 @@ void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) { if (cng_decoder) cng_decoder->Reset(); + // Reinit post-decode VAD with new sample rate. + RTC_DCHECK(vad_.get()); // Cannot be NULL here. + vad_->Init(); + // Delete algorithm buffer and create a new one. algorithm_buffer_.reset(new AudioMultiVector(channels)); @@ -2082,6 +2132,7 @@ void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) { } NetEqImpl::OutputType NetEqImpl::LastOutputType() { + RTC_DCHECK(vad_.get()); RTC_DCHECK(expand_.get()); if (last_mode_ == Mode::kCodecInternalCng || last_mode_ == Mode::kRfc3389Cng) { @@ -2091,6 +2142,8 @@ NetEqImpl::OutputType NetEqImpl::LastOutputType() { return OutputType::kPLCCNG; } else if (last_mode_ == Mode::kExpand) { return OutputType::kPLC; + } else if (vad_->running() && !vad_->active_speech()) { + return OutputType::kVadPassive; } else if (last_mode_ == Mode::kCodecPlc) { return OutputType::kCodecPLC; } else { diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h index 6ccbde7293..f8f2b06410 100644 --- a/modules/audio_coding/neteq/neteq_impl.h +++ b/modules/audio_coding/neteq/neteq_impl.h @@ -48,6 +48,7 @@ class Merge; class NackTracker; class Normal; class RedPayloadSplitter; +class PostDecodeVad; class PreemptiveExpand; class RandomVector; class SyncBuffer; @@ -170,6 +171,13 @@ class NetEqImpl : public webrtc::NetEq { NetEqOperationsAndState GetOperationsAndState() const override; + // Enables post-decode VAD. When enabled, GetAudio() will return + // kOutputVADPassive when the signal contains no speech. + void EnableVad() override; + + // Disables post-decode VAD. + void DisableVad() override; + absl::optional GetPlayoutTimestamp() const override; int last_output_sample_rate_hz() const override; @@ -348,6 +356,7 @@ class NetEqImpl : public webrtc::NetEq { RTC_GUARDED_BY(mutex_); const std::unique_ptr timestamp_scaler_ RTC_GUARDED_BY(mutex_); + const std::unique_ptr vad_ RTC_GUARDED_BY(mutex_); const std::unique_ptr expand_factory_ RTC_GUARDED_BY(mutex_); const std::unique_ptr accelerate_factory_ RTC_GUARDED_BY(mutex_); @@ -388,6 +397,8 @@ class NetEqImpl : public webrtc::NetEq { std::unique_ptr nack_ RTC_GUARDED_BY(mutex_); bool nack_enabled_ RTC_GUARDED_BY(mutex_); const bool enable_muted_state_ RTC_GUARDED_BY(mutex_); + AudioFrame::VADActivity last_vad_activity_ RTC_GUARDED_BY(mutex_) = + AudioFrame::kVadPassive; std::unique_ptr generated_noise_stopwatch_ RTC_GUARDED_BY(mutex_); std::vector last_decoded_packet_infos_ RTC_GUARDED_BY(mutex_); diff --git a/modules/audio_coding/neteq/post_decode_vad.cc b/modules/audio_coding/neteq/post_decode_vad.cc new file mode 100644 index 0000000000..9999d6764b --- /dev/null +++ b/modules/audio_coding/neteq/post_decode_vad.cc @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013 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 "modules/audio_coding/neteq/post_decode_vad.h" + +namespace webrtc { + +PostDecodeVad::~PostDecodeVad() { + if (vad_instance_) + WebRtcVad_Free(vad_instance_); +} + +void PostDecodeVad::Enable() { + if (!vad_instance_) { + // Create the instance. + vad_instance_ = WebRtcVad_Create(); + if (vad_instance_ == nullptr) { + // Failed to create instance. + Disable(); + return; + } + } + Init(); + enabled_ = true; +} + +void PostDecodeVad::Disable() { + enabled_ = false; + running_ = false; +} + +void PostDecodeVad::Init() { + running_ = false; + if (vad_instance_) { + WebRtcVad_Init(vad_instance_); + WebRtcVad_set_mode(vad_instance_, kVadMode); + running_ = true; + } +} + +void PostDecodeVad::Update(int16_t* signal, + size_t length, + AudioDecoder::SpeechType speech_type, + bool sid_frame, + int fs_hz) { + if (!vad_instance_ || !enabled_) { + return; + } + + if (speech_type == AudioDecoder::kComfortNoise || sid_frame || + fs_hz > 16000) { + // TODO(hlundin): Remove restriction on fs_hz. + running_ = false; + active_speech_ = true; + sid_interval_counter_ = 0; + } else if (!running_) { + ++sid_interval_counter_; + } + + if (sid_interval_counter_ >= kVadAutoEnable) { + Init(); + } + + if (length > 0 && running_) { + size_t vad_sample_index = 0; + active_speech_ = false; + // Loop through frame sizes 30, 20, and 10 ms. + for (int vad_frame_size_ms = 30; vad_frame_size_ms >= 10; + vad_frame_size_ms -= 10) { + size_t vad_frame_size_samples = + static_cast(vad_frame_size_ms * fs_hz / 1000); + while (length - vad_sample_index >= vad_frame_size_samples) { + int vad_return = + WebRtcVad_Process(vad_instance_, fs_hz, &signal[vad_sample_index], + vad_frame_size_samples); + active_speech_ |= (vad_return == 1); + vad_sample_index += vad_frame_size_samples; + } + } + } +} + +} // namespace webrtc diff --git a/modules/audio_coding/neteq/post_decode_vad.h b/modules/audio_coding/neteq/post_decode_vad.h new file mode 100644 index 0000000000..3bd91b9edb --- /dev/null +++ b/modules/audio_coding/neteq/post_decode_vad.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2013 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 MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ +#define MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ + +#include +#include + +#include "api/audio_codecs/audio_decoder.h" +#include "common_audio/vad/include/webrtc_vad.h" + +namespace webrtc { + +class PostDecodeVad { + public: + PostDecodeVad() + : enabled_(false), + running_(false), + active_speech_(true), + sid_interval_counter_(0), + vad_instance_(NULL) {} + + virtual ~PostDecodeVad(); + + PostDecodeVad(const PostDecodeVad&) = delete; + PostDecodeVad& operator=(const PostDecodeVad&) = delete; + + // Enables post-decode VAD. + void Enable(); + + // Disables post-decode VAD. + void Disable(); + + // Initializes post-decode VAD. + void Init(); + + // Updates post-decode VAD with the audio data in `signal` having `length` + // samples. The data is of type `speech_type`, at the sample rate `fs_hz`. + void Update(int16_t* signal, + size_t length, + AudioDecoder::SpeechType speech_type, + bool sid_frame, + int fs_hz); + + // Accessors. + bool enabled() const { return enabled_; } + bool running() const { return running_; } + bool active_speech() const { return active_speech_; } + + private: + static const int kVadMode = 0; // Sets aggressiveness to "Normal". + // Number of Update() calls without CNG/SID before re-enabling VAD. + static const int kVadAutoEnable = 3000; + + bool enabled_; + bool running_; + bool active_speech_; + int sid_interval_counter_; + ::VadInst* vad_instance_; +}; + +} // namespace webrtc +#endif // MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ diff --git a/modules/audio_coding/neteq/post_decode_vad_unittest.cc b/modules/audio_coding/neteq/post_decode_vad_unittest.cc new file mode 100644 index 0000000000..da3e4e864e --- /dev/null +++ b/modules/audio_coding/neteq/post_decode_vad_unittest.cc @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013 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. + */ + +// Unit tests for PostDecodeVad class. + +#include "modules/audio_coding/neteq/post_decode_vad.h" + +#include "test/gtest.h" + +namespace webrtc { + +TEST(PostDecodeVad, CreateAndDestroy) { + PostDecodeVad vad; +} + +// TODO(hlundin): Write more tests. + +} // namespace webrtc diff --git a/test/fuzzers/neteq_signal_fuzzer.cc b/test/fuzzers/neteq_signal_fuzzer.cc index 3b1f70cdb4..485c38085e 100644 --- a/test/fuzzers/neteq_signal_fuzzer.cc +++ b/test/fuzzers/neteq_signal_fuzzer.cc @@ -179,6 +179,7 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) { // Configure NetEq and the NetEqTest object. NetEqTest::Callbacks callbacks; NetEq::Config config; + config.enable_post_decode_vad = true; config.enable_fast_accelerate = true; auto codecs = NetEqTest::StandardDecoderMap(); // rate_types contains the payload types that will be used for encoding. From 9d653660e9902995b1146b2d63a1c628f41199b2 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Thu, 1 Feb 2024 20:03:16 -0800 Subject: [PATCH 062/170] Update WebRTC code version (2024-02-02T04:03:16). Bug: None Change-Id: Iec8f8291065a0700697ec961cc1cad0c7ea7395a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337290 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41658} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 12ea2ff210..8963578f59 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-01-30T04:07:38"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-02T04:03:16"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From f19c7caeb5beb8e86977381ba1e45e4e1c3c01ca Mon Sep 17 00:00:00 2001 From: Jeremy Leconte Date: Thu, 1 Feb 2024 12:19:40 +0100 Subject: [PATCH 063/170] Fix crash when rolling libaom. The crash is caused by https://aomedia.googlesource.com/aom.git/+/77cf417565ad2c527d5c351927f11db3764fd93c%5E%21 Example of the test failure: https://ci.chromium.org/ui/p/webrtc/builders/try/linux_rel/72442/overview Bug: None Change-Id: I088bf7e45452cdaa71802802e431119e755eca24 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337320 Commit-Queue: Jeremy Leconte Reviewed-by: Marco Paniconi Cr-Commit-Position: refs/heads/main@{#41659} --- DEPS | 2 +- modules/video_coding/codecs/av1/libaom_av1_unittest.cc | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 6cafb926b4..99f2727827 100644 --- a/DEPS +++ b/DEPS @@ -296,7 +296,7 @@ deps = { 'src/third_party/dav1d/libdav1d': 'https://chromium.googlesource.com/external/github.com/videolan/dav1d.git@47107e384bd1dc25674acf04d000a8cdc6195234', 'src/third_party/libaom/source/libaom': - 'https://aomedia.googlesource.com/aom.git@1a72ea323d65e46eb90d08d492c04891abb91926', + 'https://aomedia.googlesource.com/aom.git@77cf417565ad2c527d5c351927f11db3764fd93c', 'src/third_party/libunwindstack': { 'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@a3bb4cd02e0e984a235069f812cbef2b37c389e5', 'condition': 'checkout_android', diff --git a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc index d486c1d062..6a135e2bab 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc @@ -62,6 +62,7 @@ VideoCodec DefaultCodecSettings() { codec_settings.height = kHeight; codec_settings.maxFramerate = kFramerate; codec_settings.maxBitrate = 1000; + codec_settings.startBitrate = 1; codec_settings.qpMax = 63; return codec_settings; } From 8c371f2a9baf8fef9bf3c327a93a709bb8c1e000 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Tue, 30 Jan 2024 07:39:42 +0000 Subject: [PATCH 064/170] Reland "Take out Fuchsia-only SDES-enabling parameters" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a reland of commit 59f3b35013a29f8c73a46fa6fd06aadc96aad892 Landing after taking out the Chrome usages. Original change's description: > Take out Fuchsia-only SDES-enabling parameters > > This does not remove all traces of SDES - we still need to delete > the cricket::CryptoParams struct and all code that uses it. > > Bug: webrtc:11066, chromium:804275 > Change-Id: I811c8d40da7f4af714d53376f24cd53332a15945 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336780 > Reviewed-by: Henrik Boström > Commit-Queue: Harald Alvestrand > Cr-Commit-Position: refs/heads/main@{#41634} Bug: webrtc:11066, chromium:804275 Change-Id: I31414dfb6a0ecfa7b6fd91c68603cfd6146869d9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337260 Reviewed-by: Olga Sharonova Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41660} --- api/peer_connection_interface.h | 9 - pc/peer_connection.cc | 16 +- pc/peer_connection_crypto_unittest.cc | 249 -------------------------- pc/peer_connection_integrationtest.cc | 20 --- pc/sdp_offer_answer.cc | 3 - 5 files changed, 1 insertion(+), 296 deletions(-) diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h index 3c225eb28a..7699f33438 100644 --- a/api/peer_connection_interface.h +++ b/api/peer_connection_interface.h @@ -451,15 +451,6 @@ class RTC_EXPORT PeerConnectionInterface : public webrtc::RefCountInterface { // when switching from a static scene to one with motion. absl::optional screencast_min_bitrate; -#if defined(WEBRTC_FUCHSIA) - // TODO(bugs.webrtc.org/11066): Remove entirely once Fuchsia does not use. - // TODO(bugs.webrtc.org/9891) - Move to crypto_options - // Can be used to disable DTLS-SRTP. This should never be done, but can be - // useful for testing purposes, for example in setting up a loopback call - // with a single PeerConnection. - absl::optional enable_dtls_srtp; -#endif - ///////////////////////////////////////////////// // The below fields are not part of the standard. ///////////////////////////////////////////////// diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index dc784771f8..3ab2c52130 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -348,15 +348,7 @@ bool DtlsEnabled(const PeerConnectionInterface::RTCConfiguration& configuration, return false; // Enable DTLS by default if we have an identity store or a certificate. - bool default_enabled = - (dependencies.cert_generator || !configuration.certificates.empty()); - -#if defined(WEBRTC_FUCHSIA) - // The `configuration` can override the default value. - return configuration.enable_dtls_srtp.value_or(default_enabled); -#else - return default_enabled; -#endif + return (dependencies.cert_generator || !configuration.certificates.empty()); } // Calls `ParseIceServersOrError` to extract ice server information from the @@ -416,9 +408,6 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( int max_ipv6_networks; bool disable_link_local_networks; absl::optional screencast_min_bitrate; -#if defined(WEBRTC_FUCHSIA) - absl::optional enable_dtls_srtp; -#endif TcpCandidatePolicy tcp_candidate_policy; CandidateNetworkPolicy candidate_network_policy; int audio_jitter_buffer_max_packets; @@ -483,9 +472,6 @@ bool PeerConnectionInterface::RTCConfiguration::operator==( max_ipv6_networks == o.max_ipv6_networks && disable_link_local_networks == o.disable_link_local_networks && screencast_min_bitrate == o.screencast_min_bitrate && -#if defined(WEBRTC_FUCHSIA) - enable_dtls_srtp == o.enable_dtls_srtp && -#endif ice_candidate_pool_size == o.ice_candidate_pool_size && prune_turn_ports == o.prune_turn_ports && turn_port_prune_policy == o.turn_port_prune_policy && diff --git a/pc/peer_connection_crypto_unittest.cc b/pc/peer_connection_crypto_unittest.cc index 3b3f502e1f..4274e88b07 100644 --- a/pc/peer_connection_crypto_unittest.cc +++ b/pc/peer_connection_crypto_unittest.cc @@ -258,233 +258,6 @@ TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsEnabled) { answer->description())); } -#if defined(WEBRTC_FUCHSIA) -// When DTLS is disabled, the SDP offer/answer should include SDES cryptos and -// should not have a DTLS fingerprint. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsDisabled) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), - offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsDisabled) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOffer()); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesCryptos(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolSavpf), - answer->description())); -} - -// When encryption is disabled, the SDP offer/answer should have neither a DTLS -// fingerprint nor any SDES crypto options. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenEncryptionDisabled) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), - offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenEncryptionDisabled) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOffer()); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolAvpf), - answer->description())); -} - -// CryptoOptions has been promoted to RTCConfiguration. As such if it is ever -// set in the configuration it should overrite the settings set in the factory. -TEST_P(PeerConnectionCryptoTest, RTCConfigurationCryptoOptionOverridesFactory) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - CryptoOptions crypto_options; - crypto_options.srtp.enable_gcm_crypto_suites = false; - config.crypto_options = crypto_options; - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - // This should exist if GCM is enabled see CorrectCryptoInOfferWithSdesAndGcm - EXPECT_FALSE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); -} - -// When DTLS is disabled and GCM cipher suites are enabled, the SDP offer/answer -// should have the correct ciphers in the SDES crypto options. -// With GCM cipher suites enabled, there will be 3 cryptos in the offer and 1 -// in the answer. -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWithSdesAndGcm) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - - ASSERT_FALSE(offer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(3), offer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWithSdesAndGcm) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - for (cricket::ContentInfo& content : offer->description()->contents()) { - auto cryptos = content.media_description()->cryptos(); - cryptos.erase(cryptos.begin()); // Assumes that non-GCM is the default. - content.media_description()->set_cryptos(cryptos); - } - - callee->SetRemoteDescription(std::move(offer)); - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - - ASSERT_FALSE(answer->description()->contents().empty()); - EXPECT_TRUE(SdpContentsAll(HaveSdesGcmCryptos(1), answer->description())); -} - -TEST_P(PeerConnectionCryptoTest, CanSetSdesGcmRemoteOfferAndLocalAnswer) { - PeerConnectionFactoryInterface::Options options; - options.crypto_options.srtp.enable_gcm_crypto_suites = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswer(); - ASSERT_TRUE(answer); - ASSERT_TRUE(callee->SetLocalDescription(std::move(answer))); -} - -// The following group tests that two PeerConnections can successfully exchange -// an offer/answer when DTLS is off and that they will refuse any offer/answer -// applied locally/remotely if it does not include SDES cryptos. -TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOfferAndSetAsLocal(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswerAndSetAsLocal(); - ASSERT_TRUE(answer); - ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetLocalOfferWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - SdpContentsForEach(RemoveSdesCryptos(), offer->description()); - - EXPECT_FALSE(caller->SetLocalDescription(std::move(offer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetRemoteOfferWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOffer(); - SdpContentsForEach(RemoveSdesCryptos(), offer->description()); - - EXPECT_FALSE(callee->SetRemoteDescription(std::move(offer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetLocalAnswerWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); - auto answer = callee->CreateAnswer(); - SdpContentsForEach(RemoveSdesCryptos(), answer->description()); - - EXPECT_FALSE(callee->SetLocalDescription(std::move(answer))); -} -TEST_P(PeerConnectionCryptoTest, FailToSetRemoteAnswerWithNoCryptosWhenSdesOn) { - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()); - auto answer = callee->CreateAnswerAndSetAsLocal(); - SdpContentsForEach(RemoveSdesCryptos(), answer->description()); - - EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); -} -#endif - // The following group tests that two PeerConnections can successfully exchange // an offer/answer when DTLS is on and that they will refuse any offer/answer // applied locally/remotely if it does not include a DTLS fingerprint. @@ -545,28 +318,6 @@ TEST_P(PeerConnectionCryptoTest, EXPECT_FALSE(caller->SetRemoteDescription(std::move(answer))); } -#if defined(WEBRTC_FUCHSIA) -// Test that an offer/answer can be exchanged when encryption is disabled. -TEST_P(PeerConnectionCryptoTest, ExchangeOfferAnswerWhenNoEncryption) { - PeerConnectionFactoryInterface::Options options; - options.disable_encryption = true; - pc_factory_->SetOptions(options); - - RTCConfiguration config; - config.enable_dtls_srtp.emplace(false); - auto caller = CreatePeerConnectionWithAudioVideo(config); - auto callee = CreatePeerConnectionWithAudioVideo(config); - - auto offer = caller->CreateOfferAndSetAsLocal(); - ASSERT_TRUE(offer); - ASSERT_TRUE(callee->SetRemoteDescription(std::move(offer))); - - auto answer = callee->CreateAnswerAndSetAsLocal(); - ASSERT_TRUE(answer); - ASSERT_TRUE(caller->SetRemoteDescription(std::move(answer))); -} -#endif - // Tests that a DTLS call can be established when the certificate is specified // in the PeerConnection config and no certificate generator is specified. TEST_P(PeerConnectionCryptoTest, diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc index 23c8b1690f..24ca52f619 100644 --- a/pc/peer_connection_integrationtest.cc +++ b/pc/peer_connection_integrationtest.cc @@ -275,26 +275,6 @@ TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithDtls) { ASSERT_TRUE(ExpectNewFrames(media_expectations)); } -#if defined(WEBRTC_FUCHSIA) -// Uses SDES instead of DTLS for key agreement. -TEST_P(PeerConnectionIntegrationTest, EndToEndCallWithSdes) { - PeerConnectionInterface::RTCConfiguration sdes_config; - sdes_config.enable_dtls_srtp.emplace(false); - ASSERT_TRUE(CreatePeerConnectionWrappersWithConfig(sdes_config, sdes_config)); - ConnectFakeSignaling(); - - // Do normal offer/answer and wait for some frames to be received in each - // direction. - caller()->AddAudioVideoTracks(); - callee()->AddAudioVideoTracks(); - caller()->CreateAndSetAndSignalOffer(); - ASSERT_TRUE_WAIT(SignalingStateStable(), kDefaultTimeout); - MediaExpectations media_expectations; - media_expectations.ExpectBidirectionalAudioAndVideo(); - ASSERT_TRUE(ExpectNewFrames(media_expectations)); -} -#endif - // Basic end-to-end test specifying the `enable_encrypted_rtp_header_extensions` // option to offer encrypted versions of all header extensions alongside the // unencrypted versions. diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 67c8d10241..19cd9ba45c 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -285,9 +285,6 @@ RTCError VerifyCrypto(const SessionDescription* desc, if (content_info.rejected) { continue; } -#if !defined(WEBRTC_FUCHSIA) - RTC_CHECK(dtls_enabled) << "SDES protocol is only allowed in Fuchsia"; -#endif const std::string& mid = content_info.name; auto it = bundle_groups_by_mid.find(mid); const cricket::ContentGroup* bundle = From 707296a068f90f814afdaedd8cc7c2c6a197e891 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Fri, 2 Feb 2024 20:02:10 -0800 Subject: [PATCH 065/170] Update WebRTC code version (2024-02-03T04:02:09). Bug: None Change-Id: Iff227abcfe820d562e7f65513c05600f0c8cd4ea Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337640 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41661} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 8963578f59..af448f872e 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-02T04:03:16"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-03T04:02:09"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 2212f86b5ac73b933b1b4e376d3b7d4359fea220 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Sat, 3 Feb 2024 20:03:10 -0800 Subject: [PATCH 066/170] Update WebRTC code version (2024-02-04T04:03:09). Bug: None Change-Id: I6b302d13c08cd7e58e4a79a7715ec462fc4e0245 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337860 Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41662} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index af448f872e..d0c62b7301 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-03T04:02:09"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-04T04:03:09"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From bda5cc63ce7393d95973b6f720d5649d70c66b06 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Fri, 2 Feb 2024 12:02:34 +0100 Subject: [PATCH 067/170] Clean up use of WebRTC-UseStandardBytesStats trial in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG=webrtc:10525 Change-Id: Ia0ec88d5b561ec98af540f849182805d49a327e6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337520 Reviewed-by: Henrik Boström Commit-Queue: Philipp Hancke Reviewed-by: Artem Titov Cr-Commit-Position: refs/heads/main@{#41663} --- test/pc/e2e/network_quality_metrics_reporter.cc | 10 ---------- test/pc/e2e/network_quality_metrics_reporter.h | 2 -- test/pc/e2e/peer_connection_quality_test.cc | 5 +---- .../stats_based_network_quality_metrics_reporter.cc | 10 ---------- .../e2e/stats_based_network_quality_metrics_reporter.h | 3 --- 5 files changed, 1 insertion(+), 29 deletions(-) diff --git a/test/pc/e2e/network_quality_metrics_reporter.cc b/test/pc/e2e/network_quality_metrics_reporter.cc index 257fecf309..3c4f6cabe1 100644 --- a/test/pc/e2e/network_quality_metrics_reporter.cc +++ b/test/pc/e2e/network_quality_metrics_reporter.cc @@ -27,11 +27,6 @@ using ::webrtc::test::Unit; constexpr TimeDelta kStatsWaitTimeout = TimeDelta::Seconds(1); -// Field trial which controls whether to report standard-compliant bytes -// sent/received per stream. If enabled, padding and headers are not included -// in bytes sent or received. -constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats"; - } // namespace NetworkQualityMetricsReporter::NetworkQualityMetricsReporter( @@ -107,11 +102,6 @@ void NetworkQualityMetricsReporter::StopAndReportResults() { ReportStats(alice_network_label_, alice_stats, alice_packets_loss); ReportStats(bob_network_label_, bob_stats, bob_packets_loss); - if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) { - RTC_LOG(LS_ERROR) - << "Non-standard GetStats; \"payload\" counts include RTP headers"; - } - MutexLock lock(&lock_); for (const auto& pair : pc_stats_) { ReportPCStats(pair.first, pair.second); diff --git a/test/pc/e2e/network_quality_metrics_reporter.h b/test/pc/e2e/network_quality_metrics_reporter.h index 1348a58943..fd523cc48d 100644 --- a/test/pc/e2e/network_quality_metrics_reporter.h +++ b/test/pc/e2e/network_quality_metrics_reporter.h @@ -48,8 +48,6 @@ class NetworkQualityMetricsReporter private: struct PCStats { - // TODO(nisse): Separate audio and video counters. Depends on standard stat - // counters, enabled by field trial "WebRTC-UseStandardBytesStats". DataSize payload_received = DataSize::Zero(); DataSize payload_sent = DataSize::Zero(); }; diff --git a/test/pc/e2e/peer_connection_quality_test.cc b/test/pc/e2e/peer_connection_quality_test.cc index 90f201facd..3a6b808167 100644 --- a/test/pc/e2e/peer_connection_quality_test.cc +++ b/test/pc/e2e/peer_connection_quality_test.cc @@ -73,8 +73,6 @@ constexpr TimeDelta kQuickTestModeRunDuration = TimeDelta::Millis(100); // Field trials to enable Flex FEC advertising and receiving. constexpr char kFlexFecEnabledFieldTrials[] = "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/"; -constexpr char kUseStandardsBytesStats[] = - "WebRTC-UseStandardBytesStats/Enabled/"; class FixturePeerConnectionObserver : public MockPeerConnectionObserver { public: @@ -439,8 +437,7 @@ void PeerConnectionE2EQualityTest::Run(RunParams run_params) { std::string PeerConnectionE2EQualityTest::GetFieldTrials( const RunParams& run_params) { - std::vector default_field_trials = { - kUseStandardsBytesStats}; + std::vector default_field_trials = {}; if (run_params.enable_flex_fec_support) { default_field_trials.push_back(kFlexFecEnabledFieldTrials); } diff --git a/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc b/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc index b965a7acd8..706224ce08 100644 --- a/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc +++ b/test/pc/e2e/stats_based_network_quality_metrics_reporter.cc @@ -51,11 +51,6 @@ using NetworkLayerStats = constexpr TimeDelta kStatsWaitTimeout = TimeDelta::Seconds(1); -// Field trial which controls whether to report standard-compliant bytes -// sent/received per stream. If enabled, padding and headers are not included -// in bytes sent or received. -constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats"; - EmulatedNetworkStats PopulateStats(std::vector endpoints, NetworkEmulationManager* network_emulation) { rtc::Event stats_loaded; @@ -325,11 +320,6 @@ void StatsBasedNetworkQualityMetricsReporter::OnStatsReports( void StatsBasedNetworkQualityMetricsReporter::StopAndReportResults() { Timestamp end_time = clock_->CurrentTime(); - if (!webrtc::field_trial::IsEnabled(kUseStandardBytesStats)) { - RTC_LOG(LS_ERROR) - << "Non-standard GetStats; \"payload\" counts include RTP headers"; - } - std::map stats = collector_.GetStats(); for (const auto& entry : stats) { LogNetworkLayerStats(entry.first, entry.second); diff --git a/test/pc/e2e/stats_based_network_quality_metrics_reporter.h b/test/pc/e2e/stats_based_network_quality_metrics_reporter.h index 60daf40c8c..ba6bf04e18 100644 --- a/test/pc/e2e/stats_based_network_quality_metrics_reporter.h +++ b/test/pc/e2e/stats_based_network_quality_metrics_reporter.h @@ -70,9 +70,6 @@ class StatsBasedNetworkQualityMetricsReporter private: struct PCStats { - // TODO(bugs.webrtc.org/10525): Separate audio and video counters. Depends - // on standard stat counters, enabled by field trial - // "WebRTC-UseStandardBytesStats". DataSize payload_received = DataSize::Zero(); DataSize payload_sent = DataSize::Zero(); From 35fe95802df52d8d2d6fdbee4278663076caaac7 Mon Sep 17 00:00:00 2001 From: Artem Titov Date: Fri, 2 Feb 2024 17:51:26 +0100 Subject: [PATCH 068/170] Add RTC_EXPORT for rtc::IPIsLinkLocal and rtc::IPIsLoopback Required to allow private IPv6 addresses in Chromium: https://crrev.com/c/5258983 Bug: chromium:323820219 Change-Id: I25fc931f00feda9bfa2f3b92317b4b4b064f6f69 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337600 Reviewed-by: Harald Alvestrand Commit-Queue: Artem Titov Cr-Commit-Position: refs/heads/main@{#41664} --- rtc_base/ip_address.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtc_base/ip_address.h b/rtc_base/ip_address.h index 897e165565..c015206ab3 100644 --- a/rtc_base/ip_address.h +++ b/rtc_base/ip_address.h @@ -162,8 +162,8 @@ RTC_EXPORT bool IPFromString(absl::string_view str, int flags, InterfaceAddress* out); bool IPIsAny(const IPAddress& ip); -bool IPIsLoopback(const IPAddress& ip); -bool IPIsLinkLocal(const IPAddress& ip); +RTC_EXPORT bool IPIsLoopback(const IPAddress& ip); +RTC_EXPORT bool IPIsLinkLocal(const IPAddress& ip); // Identify a private network address like "192.168.111.222" // (see https://en.wikipedia.org/wiki/Private_network ) bool IPIsPrivateNetwork(const IPAddress& ip); From f6ae657b07eedf95594f76e77dfc2f67132d5bb4 Mon Sep 17 00:00:00 2001 From: Jakob Ivarsson Date: Mon, 5 Feb 2024 11:30:21 +0100 Subject: [PATCH 069/170] Adapt NetEq delay to received FEC (both RED and codec inband). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is achieved by notifing NetEq controller of all received packets after splitting, which then does deduping so that only useful packets are counted. The goal is to reduce underruns when FEC is used. The behavior is default enabled with a field trial kill-switch. Bug: webrtc:13322 Change-Id: I2a1a78ead1a58940ef92da0d43413eda5ba1caf3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337440 Commit-Queue: Jakob Ivarsson‎ Reviewed-by: Henrik Lundin Cr-Commit-Position: refs/heads/main@{#41665} --- experiments/field_trials.py | 3 + modules/audio_coding/neteq/neteq_impl.cc | 65 +++++++++++++++----- modules/audio_coding/neteq/neteq_impl.h | 4 ++ modules/audio_coding/neteq/neteq_unittest.cc | 9 +-- 4 files changed, 61 insertions(+), 20 deletions(-) diff --git a/experiments/field_trials.py b/experiments/field_trials.py index 32ab6bf351..86066ec764 100755 --- a/experiments/field_trials.py +++ b/experiments/field_trials.py @@ -47,6 +47,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-Audio-GainController2', 'webrtc:7494', date(2024, 4, 1)), + FieldTrial('WebRTC-Audio-NetEqFecDelayAdaptation', + 'webrtc:13322', + date(2024, 4, 1)), FieldTrial('WebRTC-Audio-OpusSetSignalVoiceWithDtx', 'webrtc:4559', date(2024, 4, 1)), diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc index e5c8bf6c08..144893b6d3 100644 --- a/modules/audio_coding/neteq/neteq_impl.cc +++ b/modules/audio_coding/neteq/neteq_impl.cc @@ -20,6 +20,7 @@ #include #include "api/audio_codecs/audio_decoder.h" +#include "api/neteq/neteq_controller.h" #include "api/neteq/tick_timer.h" #include "common_audio/signal_processing/include/signal_processing_library.h" #include "modules/audio_coding/codecs/cng/webrtc_cng.h" @@ -50,6 +51,7 @@ #include "rtc_base/strings/audio_format_to_string.h" #include "rtc_base/trace_event.h" #include "system_wrappers/include/clock.h" +#include "system_wrappers/include/field_trial.h" namespace webrtc { namespace { @@ -174,6 +176,8 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, accelerate_factory_(std::move(deps.accelerate_factory)), preemptive_expand_factory_(std::move(deps.preemptive_expand_factory)), stats_(std::move(deps.stats)), + enable_fec_delay_adaptation_( + !field_trial::IsDisabled("WebRTC-Audio-NetEqFecDelayAdaptation")), controller_(std::move(deps.neteq_controller)), last_mode_(Mode::kNormal), decoded_buffer_length_(kMaxFrameSize), @@ -695,6 +699,7 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, packet_buffer_->Flush(); buffer_flush_occured = true; } + NetEqController::PacketArrivedInfo info = ToPacketArrivedInfo(packet); int return_val = packet_buffer_->InsertPacket(std::move(packet)); if (return_val == PacketBuffer::kFlushed) { buffer_flush_occured = true; @@ -702,6 +707,15 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, // An error occurred. return kOtherError; } + if (enable_fec_delay_adaptation_) { + info.buffer_flush = buffer_flush_occured; + const bool should_update_stats = !new_codec_ && !buffer_flush_occured; + auto relative_delay = + controller_->PacketArrived(fs_hz_, should_update_stats, info); + if (relative_delay) { + stats_->RelativePacketArrivalDelay(relative_delay.value()); + } + } } if (buffer_flush_occured) { @@ -752,24 +766,26 @@ int NetEqImpl::InsertPacketInternal(const RTPHeader& rtp_header, } } - const DecoderDatabase::DecoderInfo* dec_info = - decoder_database_->GetDecoderInfo(main_payload_type); - RTC_DCHECK(dec_info); // Already checked that the payload type is known. + if (!enable_fec_delay_adaptation_) { + const DecoderDatabase::DecoderInfo* dec_info = + decoder_database_->GetDecoderInfo(main_payload_type); + RTC_DCHECK(dec_info); // Already checked that the payload type is known. - NetEqController::PacketArrivedInfo info; - info.is_cng_or_dtmf = dec_info->IsComfortNoise() || dec_info->IsDtmf(); - info.packet_length_samples = - number_of_primary_packets * decoder_frame_length_; - info.main_timestamp = main_timestamp; - info.main_sequence_number = main_sequence_number; - info.is_dtx = is_dtx; - info.buffer_flush = buffer_flush_occured; + NetEqController::PacketArrivedInfo info; + info.is_cng_or_dtmf = dec_info->IsComfortNoise() || dec_info->IsDtmf(); + info.packet_length_samples = + number_of_primary_packets * decoder_frame_length_; + info.main_timestamp = main_timestamp; + info.main_sequence_number = main_sequence_number; + info.is_dtx = is_dtx; + info.buffer_flush = buffer_flush_occured; - const bool should_update_stats = !new_codec_; - auto relative_delay = - controller_->PacketArrived(fs_hz_, should_update_stats, info); - if (relative_delay) { - stats_->RelativePacketArrivalDelay(relative_delay.value()); + const bool should_update_stats = !new_codec_; + auto relative_delay = + controller_->PacketArrived(fs_hz_, should_update_stats, info); + if (relative_delay) { + stats_->RelativePacketArrivalDelay(relative_delay.value()); + } } return 0; } @@ -2150,4 +2166,21 @@ NetEqImpl::OutputType NetEqImpl::LastOutputType() { return OutputType::kNormalSpeech; } } + +NetEqController::PacketArrivedInfo NetEqImpl::ToPacketArrivedInfo( + const Packet& packet) const { + const DecoderDatabase::DecoderInfo* dec_info = + decoder_database_->GetDecoderInfo(packet.payload_type); + + NetEqController::PacketArrivedInfo info; + info.is_cng_or_dtmf = + dec_info && (dec_info->IsComfortNoise() || dec_info->IsDtmf()); + info.packet_length_samples = + packet.frame ? packet.frame->Duration() : decoder_frame_length_; + info.main_timestamp = packet.timestamp; + info.main_sequence_number = packet.sequence_number; + info.is_dtx = packet.frame && packet.frame->IsDtxPacket(); + return info; +} + } // namespace webrtc diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h index f8f2b06410..f164238b09 100644 --- a/modules/audio_coding/neteq/neteq_impl.h +++ b/modules/audio_coding/neteq/neteq_impl.h @@ -342,6 +342,9 @@ class NetEqImpl : public webrtc::NetEq { NetEqNetworkStatistics CurrentNetworkStatisticsInternal() const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + NetEqController::PacketArrivedInfo ToPacketArrivedInfo( + const Packet& packet) const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + Clock* const clock_; mutable Mutex mutex_; @@ -363,6 +366,7 @@ class NetEqImpl : public webrtc::NetEq { const std::unique_ptr preemptive_expand_factory_ RTC_GUARDED_BY(mutex_); const std::unique_ptr stats_ RTC_GUARDED_BY(mutex_); + const bool enable_fec_delay_adaptation_ RTC_GUARDED_BY(mutex_); std::unique_ptr background_noise_ RTC_GUARDED_BY(mutex_); std::unique_ptr controller_ RTC_GUARDED_BY(mutex_); diff --git a/modules/audio_coding/neteq/neteq_unittest.cc b/modules/audio_coding/neteq/neteq_unittest.cc index aec7e580ec..7104b7a6dc 100644 --- a/modules/audio_coding/neteq/neteq_unittest.cc +++ b/modules/audio_coding/neteq/neteq_unittest.cc @@ -76,12 +76,13 @@ TEST_F(NetEqDecodingTest, MAYBE_TestOpusBitExactness) { webrtc::test::ResourcePath("audio_coding/neteq_opus", "rtp"); const std::string output_checksum = - "2efdbea92c3fb2383c59f89d881efec9f94001d0|" - "a6831b946b59913852ae3e53f99fa8f209bb23cd"; + "434bdc4ec08546510ee903d001c8be1a01c44e24|" + "4336be0091e2faad7a194c16ee0a05e727325727|" + "cefd2de4adfa8f6a9b66a3639ad63c2f6779d0cd"; const std::string network_stats_checksum = - "dfaf4399fd60293405290476ccf1c05c807c71a0|" - "076662525572dba753b11578330bd491923f7f5e"; + "5f2c8e3dff9cff55dd7a9f4167939de001566d95|" + "80ab17c17da030d4f2dfbf314ac44aacdadd7f0c"; DecodeAndCompare(input_rtp_file, output_checksum, network_stats_checksum, absl::GetFlag(FLAGS_gen_ref)); From ff616269f8759369595e3642263532655b7f096c Mon Sep 17 00:00:00 2001 From: Byoungchan Lee Date: Mon, 5 Feb 2024 15:36:58 +0900 Subject: [PATCH 070/170] Fix Chromium roll failures due to classpath format changes in jni_zero This commit addresses an issue resulting from a change [1] in the jni_zero project, where the format of classpath entries changed (from using slashes 'org/webrtc/PeerConnectionFactory' to dots 'org.webrtc.PeerConnectionFactory'). These changes led to failures in the Chromium rolls in WebRTC, as the Class loader in JNI was not designed to handle class names with dots. This CL fixes this issue by changing webrtc::GetClass to convert class paths to what JNI expects. [1] https://chromium-review.googlesource.com/c/chromium/src/+/5234469 Bug: chromium:1377351 Change-Id: I2f243bb4ed04136f86510fcd5472e9bfc2d4ba85 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337900 Reviewed-by: Jeremy Leconte Reviewed-by: Harald Alvestrand Commit-Queue: Jeremy Leconte Cr-Commit-Position: refs/heads/main@{#41666} --- sdk/android/native_api/jni/class_loader.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sdk/android/native_api/jni/class_loader.cc b/sdk/android/native_api/jni/class_loader.cc index 1789d78c85..48082bd43e 100644 --- a/sdk/android/native_api/jni/class_loader.cc +++ b/sdk/android/native_api/jni/class_loader.cc @@ -69,12 +69,20 @@ void InitClassLoader(JNIEnv* env) { g_class_loader = new ClassLoader(env); } -ScopedJavaLocalRef GetClass(JNIEnv* env, const char* name) { - // The class loader will be null in the JNI code called from the ClassLoader - // ctor when we are bootstrapping ourself. - return (g_class_loader == nullptr) - ? ScopedJavaLocalRef(env, env->FindClass(name)) - : g_class_loader->FindClass(env, name); +ScopedJavaLocalRef GetClass(JNIEnv* env, const char* c_name) { + if (g_class_loader != nullptr) { + // The class loader will be null in the JNI code called from the ClassLoader + // ctor when we are bootstrapping ourself. + return g_class_loader->FindClass(env, c_name); + } + // jni_zero generated code uses dots instead of slashes. + // Convert to use slashes since that's what JNI's FindClass expects. + // See + // https://cs.android.com/android/platform/superproject/main/+/main:art/runtime/jni/check_jni.cc;l=349;drc=0f62043c1670cd365aba1894ad8046cdfc1c905d + + std::string name(c_name); + std::replace(name.begin(), name.end(), '.', '/'); + return ScopedJavaLocalRef(env, env->FindClass(name.c_str())); } } // namespace webrtc From 0358a2c7a5a04746428460622eed6172d20e51c3 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 5 Feb 2024 04:48:42 -0800 Subject: [PATCH 071/170] Roll chromium_revision 844caa73fd..82f331232d (1252127:1256154) Change log: https://chromium.googlesource.com/chromium/src/+log/844caa73fd..82f331232d Full diff: https://chromium.googlesource.com/chromium/src/+/844caa73fd..82f331232d Changed dependencies * fuchsia_version: version:17.20240120.1.1..version:18.20240127.1.1 * reclient_version: re_client_version:0.126.0.4aaef37-gomaip..re_client_version:0.130.0.546556b-gomaip * src/base: https://chromium.googlesource.com/chromium/src/base/+log/1e7f08e968..f35773d19b * src/build: https://chromium.googlesource.com/chromium/src/build/+log/0b7a0198da..f4542781a5 * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/d8688b9036..fc9e646cb3 * src/buildtools/linux64: git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef..git_revision:a2e2717ea670249a34b0de4b3e54f268d320bdfa * src/buildtools/mac: git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef..git_revision:a2e2717ea670249a34b0de4b3e54f268d320bdfa * src/buildtools/reclient: re_client_version:0.126.0.4aaef37-gomaip..re_client_version:0.130.0.546556b-gomaip * src/buildtools/win: git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef..git_revision:a2e2717ea670249a34b0de4b3e54f268d320bdfa * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/2e7ed5b523..8c904c8500 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/d03a2cf751..fa5d894853 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/b2c536b297..f52924d4de * src/third_party/android_build_tools/manifest_merger: fPIg5SQ9nbj982soSMoZlTPVfZ2zVKZRusg-r0ONCxUC.._BpuezAM4mQeQj5WNI7H6zkNx4nV2d8uGzcoJOlLQJcC * src/third_party/androidx: BW2v6j8vjcVQrdX9fXmf686JtkLjxn-KCWhAE1XT_n4C..6uuKw5DN2kX3odjXxnfntoWPy4DOE00A65kTz33wmEYC * src/third_party/boringssl/src: https://boringssl.googlesource.com/boringssl.git/+log/414f69504d..10a2132f50 * src/third_party/breakpad/breakpad: https://chromium.googlesource.com/breakpad/breakpad.git/+log/62ecd46358..6551ac3632 * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/d7ee2f7345..432aa4ae6c * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/2bc81cdf4f..af6eabff53 * src/third_party/ffmpeg: https://chromium.googlesource.com/chromium/third_party/ffmpeg.git/+log/17525de887..7c1b0b524c * src/third_party/fontconfig/src: https://chromium.googlesource.com/external/fontconfig.git/+log/2fb3419a92..14d466b30a * src/third_party/freetype/src: https://chromium.googlesource.com/chromium/src/third_party/freetype2.git/+log/5761778246..47574f7ea4 * src/third_party/libaom/source/libaom: https://aomedia.googlesource.com/aom.git/+log/77cf417565..0cee19cfc8 * src/third_party/libc++/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git/+log/28aa23ffb4..3c2f3884e6 * src/third_party/libc++abi/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git/+log/a46df1f416..0c4e8fac5c * src/third_party/libvpx/source/libvpx: https://chromium.googlesource.com/webm/libvpx.git/+log/eeb1be7f23..c35f3e9e35 * src/third_party/libyuv: https://chromium.googlesource.com/libyuv/libyuv.git/+log/04821d1e7d..d359a9f922 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/d9c3231123..9dec55ff4f * src/third_party/r8: K1NPmXz0aZCAGGtC5UESEmqwT5-x6QNNb0Jo0umsez4C..X4a6wa4_8gQP775zUTVOXJEtzMNByOt6xLvdOc2_i_MC * src/third_party/re2/src: https://chromium.googlesource.com/external/github.com/google/re2.git/+log/826ad10e58..ab7c5918b4 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/80bf17f2a7..8cd7746c96 Added dependency * src/third_party/android_deps/libs/org_jetbrains_kotlinx_atomicfu_jvm DEPS diff: https://chromium.googlesource.com/chromium/src/+/844caa73fd..82f331232d/DEPS No update to Clang. BUG=None Change-Id: I103d6aa89ddc107917b7f9d71dc7d3fb589599aa Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338001 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41667} --- DEPS | 71 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/DEPS b/DEPS index 99f2727827..a6e4ca33f7 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '844caa73fdd4e4f48fd8b57802ae0617dfcb3819', + 'chromium_revision': '82f331232dcb85e9b6fa9fb5cf3871daf84072a4', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -25,7 +25,7 @@ vars = { # By default, download the fuchsia sdk from the public sdk directory. 'fuchsia_sdk_cipd_prefix': 'fuchsia/sdk/core/', - 'fuchsia_version': 'version:17.20240120.1.1', + 'fuchsia_version': 'version:18.20240127.1.1', # By default, download the fuchsia images from the fuchsia GCS bucket. 'fuchsia_images_bucket': 'fuchsia', 'checkout_fuchsia': False, @@ -40,7 +40,7 @@ vars = { # RBE instance to use for running remote builds 'rbe_instance': 'projects/rbe-webrtc-developer/instances/default_instance', # reclient CIPD package version - 'reclient_version': 're_client_version:0.126.0.4aaef37-gomaip', + 'reclient_version': 're_client_version:0.130.0.546556b-gomaip', # ninja CIPD package version # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja @@ -50,30 +50,30 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@1e7f08e968d8354d58e7ff4a818062d99f36d889', + 'https://chromium.googlesource.com/chromium/src/base@f35773d19b451505fdc59b50331bb05a1f9ad03a', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@0b7a0198da6202822e3c9d934327e390760459f1', + 'https://chromium.googlesource.com/chromium/src/build@f4542781a50accded1af4b2eca91e26bb532d35e', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@d8688b9036d46d14ef1f6fc26bcbb1da2b17f897', + 'https://chromium.googlesource.com/chromium/src/buildtools@fc9e646cb3bfd0de93bce731d0f10096c022a63a', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@2e7ed5b52398f0c7ca72e0ac6f5801bb06cabf96', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@8c904c85009e8682d74be21f107c4add008b39b5', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@d03a2cf751fcc23f1ec306a9eb6946b06ecb1f2c', + 'https://chromium.googlesource.com/chromium/src/testing@fa5d894853a65f90493ed71520f42dde51b8168f', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@b2c536b297b9fd34ac67f226d247bf0a6773d912', + 'https://chromium.googlesource.com/chromium/src/third_party@f52924d4de41c19e7f516c094f19c89ef9e9c489', 'src/buildtools/linux64': { 'packages': [ { 'package': 'gn/gn/linux-${{arch}}', - 'version': 'git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef', + 'version': 'git_revision:a2e2717ea670249a34b0de4b3e54f268d320bdfa', } ], 'dep_type': 'cipd', @@ -83,7 +83,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/mac-${{arch}}', - 'version': 'git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef', + 'version': 'git_revision:a2e2717ea670249a34b0de4b3e54f268d320bdfa', } ], 'dep_type': 'cipd', @@ -93,7 +93,7 @@ deps = { 'packages': [ { 'package': 'gn/gn/windows-amd64', - 'version': 'git_revision:fc722252439ea3576c241773f5ee14eb8470e2ef', + 'version': 'git_revision:a2e2717ea670249a34b0de4b3e54f268d320bdfa', } ], 'dep_type': 'cipd', @@ -115,9 +115,9 @@ deps = { 'src/third_party/clang-format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@e5337933f2951cacd3aeacd238ce4578163ca0b9', 'src/third_party/libc++/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@28aa23ffb4c7344914a5b4ac7169f12e5a12333f', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@3c2f3884e62e17b137ede3e2f3e7214ef294e2c9', 'src/third_party/libc++abi/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@a46df1f416d9bbaa25bceaa684418f94ec3935b2', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@0c4e8fac5c5b369eb27093c0bdeae5dfad1aaf5c', 'src/third_party/libunwind/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@fc505746f02c927d792bdeb328307e0e87500342', @@ -185,11 +185,11 @@ deps = { }, 'src/third_party/boringssl/src': - 'https://boringssl.googlesource.com/boringssl.git@414f69504d30d0848b69f6453ea7fb5e88004cb4', + 'https://boringssl.googlesource.com/boringssl.git@10a2132f50aaf7d49db7e258666f447b821588d9', 'src/third_party/breakpad/breakpad': - 'https://chromium.googlesource.com/breakpad/breakpad.git@62ecd463583d09eb7d15b1d410055f30b2c7bcb4', + 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@d7ee2f7345cc7b989b88c5323f9b3e6e380fb0d5', + 'https://chromium.googlesource.com/catapult.git@432aa4ae6c6931b15f595218bffb6c63512ac179', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,9 +202,9 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@2bc81cdf4f2f384527eb2e3a39f2e38a4a8193b5', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@af6eabff5313cfdce7e4ff358e3490d1571ea4cd', 'src/third_party/ffmpeg': - 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@17525de887d54b970ffdd421a0879c1db1952307', + 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': 'https://chromium.googlesource.com/external/github.com/google/flatbuffers.git@bcb9ef187628fe07514e57756d05e6a6296f7dc5', 'src/third_party/grpc/src': { @@ -212,11 +212,11 @@ deps = { }, # Used for embedded builds. CrOS & Linux use the system version. 'src/third_party/fontconfig/src': { - 'url': 'https://chromium.googlesource.com/external/fontconfig.git@2fb3419a92156569bc1ec707401258c922cd0d99', + 'url': 'https://chromium.googlesource.com/external/fontconfig.git@14d466b30a8ab4a9d789977ed94f2c30e7209267', 'condition': 'checkout_linux', }, 'src/third_party/freetype/src': - 'https://chromium.googlesource.com/chromium/src/third_party/freetype2.git@57617782464411201ce7bbc93b086c1b4d7d84a5', + 'https://chromium.googlesource.com/chromium/src/third_party/freetype2.git@47574f7ea445c8bb751da0fa716424c9c29a6807', 'src/third_party/harfbuzz-ng/src': 'https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz.git@155015f4bec434ecc2f94621665844218f05ce51', 'src/third_party/google_benchmark/src': { @@ -296,17 +296,17 @@ deps = { 'src/third_party/dav1d/libdav1d': 'https://chromium.googlesource.com/external/github.com/videolan/dav1d.git@47107e384bd1dc25674acf04d000a8cdc6195234', 'src/third_party/libaom/source/libaom': - 'https://aomedia.googlesource.com/aom.git@77cf417565ad2c527d5c351927f11db3764fd93c', + 'https://aomedia.googlesource.com/aom.git@0cee19cfc8b69661a4c808624d36def44450f14e', 'src/third_party/libunwindstack': { 'url': 'https://chromium.googlesource.com/chromium/src/third_party/libunwindstack.git@a3bb4cd02e0e984a235069f812cbef2b37c389e5', 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@d9c3231123fd6b1d0c1afd49d27c628a3b01c4f6', + 'https://android.googlesource.com/platform/external/perfetto.git@9dec55ff4fab02b2603910bba274fdf514cfbfd1', 'src/third_party/libvpx/source/libvpx': - 'https://chromium.googlesource.com/webm/libvpx.git@eeb1be7f23eee652372df4fa3b14cf542ee2c040', + 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': - 'https://chromium.googlesource.com/libyuv/libyuv.git@04821d1e7d60845525e8db55c7bcd41ef5be9406', + 'https://chromium.googlesource.com/libyuv/libyuv.git@d359a9f922af840b043535d43cf9d38b220d102e', 'src/third_party/lss': { 'url': 'https://chromium.googlesource.com/linux-syscall-support.git@ce877209e11aa69dcfffbd53ef90ea1d07136521', 'condition': 'checkout_android or checkout_linux', @@ -325,13 +325,13 @@ deps = { 'https://chromium.googlesource.com/external/github.com/cisco/openh264@09a4f3ec842a8932341b195c5b01e141c8a16eb7', 'src/third_party/re2/src': - 'https://chromium.googlesource.com/external/github.com/google/re2.git@826ad10e58a042faf57d7c329b0fd0a04b797e0b', + 'https://chromium.googlesource.com/external/github.com/google/re2.git@ab7c5918b418428ed17dbe564e0d8402bd7d743d', 'src/third_party/r8': { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'K1NPmXz0aZCAGGtC5UESEmqwT5-x6QNNb0Jo0umsez4C', + 'version': 'X4a6wa4_8gQP775zUTVOXJEtzMNByOt6xLvdOc2_i_MC', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@80bf17f2a7715bfa381b2ca2e4e31cfb3efb44e8', + 'https://chromium.googlesource.com/chromium/src/tools@8cd7746c9635b12c318bbf1e478939a615424a3e', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -405,7 +405,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'BW2v6j8vjcVQrdX9fXmf686JtkLjxn-KCWhAE1XT_n4C', + 'version': '6uuKw5DN2kX3odjXxnfntoWPy4DOE00A65kTz33wmEYC', }, ], 'condition': 'checkout_android', @@ -416,7 +416,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': 'fPIg5SQ9nbj982soSMoZlTPVfZ2zVKZRusg-r0ONCxUC', + 'version': '_BpuezAM4mQeQj5WNI7H6zkNx4nV2d8uGzcoJOlLQJcC', }, ], 'condition': 'checkout_android', @@ -1890,6 +1890,17 @@ deps = { 'dep_type': 'cipd', }, + 'src/third_party/android_deps/libs/org_jetbrains_kotlinx_atomicfu_jvm': { + 'packages': [ + { + 'package': 'chromium/third_party/android_deps/libs/org_jetbrains_kotlinx_atomicfu_jvm', + 'version': 'version:2@0.23.2.cr1', + }, + ], + 'condition': 'checkout_android', + 'dep_type': 'cipd', + }, + 'src/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android': { 'packages': [ { From 5b90b963de4ff7813b2c35089c5cf5821f9261d4 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 5 Feb 2024 11:57:39 +0100 Subject: [PATCH 072/170] Provide Environment for VideoDecoder in video_coding/ tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:15791 Change-Id: I6345f88f895ee6ff89f4c8224c8d2dc495422152 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337980 Commit-Queue: Danil Chapovalov Reviewed-by: Åsa Persson Cr-Commit-Position: refs/heads/main@{#41668} --- modules/video_coding/BUILD.gn | 4 ++++ .../test/video_encoder_decoder_instantiation_tests.cc | 8 ++++++-- .../codecs/test/videocodec_test_fixture_impl.cc | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 6bf97de9a8..a31d759baa 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -932,6 +932,8 @@ if (rtc_include_tests) { ":webrtc_vp9_helpers", "../../api:array_view", "../../api:videocodec_test_fixture_api", + "../../api/environment", + "../../api/environment:environment_factory", "../../api/test/metrics:global_metrics_logger_and_exporter", "../../api/test/metrics:metric", "../../api/test/video:function_video_factory", @@ -1079,6 +1081,8 @@ if (rtc_include_tests) { "../../api:scoped_refptr", "../../api:videocodec_test_fixture_api", "../../api:videocodec_test_stats_api", + "../../api/environment", + "../../api/environment:environment_factory", "../../api/test/metrics:global_metrics_logger_and_exporter", "../../api/test/video:function_video_factory", "../../api/video:encoded_image", diff --git a/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc b/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc index 41f2304748..581750768d 100644 --- a/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc +++ b/modules/video_coding/codecs/test/video_encoder_decoder_instantiation_tests.cc @@ -11,6 +11,8 @@ #include #include +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder_factory.h" @@ -86,6 +88,8 @@ class VideoEncoderDecoderInstantiationTest } } + const Environment env_ = CreateEnvironment(); + const SdpVideoFormat vp8_format_; const SdpVideoFormat vp9_format_; const SdpVideoFormat h264cbp_format_; @@ -126,7 +130,7 @@ TEST_P(VideoEncoderDecoderInstantiationTest, DISABLED_InstantiateVp8Codecs) { for (int i = 0; i < num_decoders_; ++i) { std::unique_ptr decoder = - decoder_factory_->CreateVideoDecoder(vp8_format_); + decoder_factory_->Create(env_, vp8_format_); ASSERT_THAT(decoder, NotNull()); EXPECT_TRUE(decoder->Configure(DecoderSettings(kVideoCodecVP8))); decoders_.emplace_back(std::move(decoder)); @@ -144,7 +148,7 @@ TEST_P(VideoEncoderDecoderInstantiationTest, for (int i = 0; i < num_decoders_; ++i) { std::unique_ptr decoder = - decoder_factory_->CreateVideoDecoder(h264cbp_format_); + decoder_factory_->Create(env_, h264cbp_format_); ASSERT_THAT(decoder, NotNull()); EXPECT_TRUE(decoder->Configure(DecoderSettings(kVideoCodecH264))); decoders_.push_back(std::move(decoder)); diff --git a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc index 35355d4387..508ac384b0 100644 --- a/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc +++ b/modules/video_coding/codecs/test/videocodec_test_fixture_impl.cc @@ -24,6 +24,8 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/test/metrics/global_metrics_logger_and_exporter.h" #include "api/test/metrics/metric.h" #include "api/transport/field_trial_based_config.h" @@ -685,6 +687,8 @@ void VideoCodecTestFixtureImpl::VerifyVideoStatistic( } bool VideoCodecTestFixtureImpl::CreateEncoderAndDecoder() { + const Environment env = CreateEnvironment(); + SdpVideoFormat encoder_format(CreateSdpVideoFormat(config_)); SdpVideoFormat decoder_format = encoder_format; @@ -709,7 +713,7 @@ bool VideoCodecTestFixtureImpl::CreateEncoderAndDecoder() { config_.NumberOfSimulcastStreams(), config_.NumberOfSpatialLayers()); for (size_t i = 0; i < num_simulcast_or_spatial_layers; ++i) { std::unique_ptr decoder = - decoder_factory_->CreateVideoDecoder(decoder_format); + decoder_factory_->Create(env, decoder_format); EXPECT_TRUE(decoder) << "Decoder not successfully created."; if (decoder == nullptr) { return false; From 5ff04d1b60677e2de86fd99b31efe0b18db81def Mon Sep 17 00:00:00 2001 From: Jakob Ivarsson Date: Mon, 5 Feb 2024 15:03:58 +0100 Subject: [PATCH 073/170] Avoid zero duration packets in NetEq test with replacement audio. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a crash when the timestamp difference between two packets is zero, which can happen due to probing for example. Bug: none Change-Id: If04dfaed0b10aecd7b1a1e5487161c2d82ad9e44 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338020 Commit-Queue: Jakob Ivarsson‎ Reviewed-by: Henrik Lundin Reviewed-by: Henrik Lundin Cr-Commit-Position: refs/heads/main@{#41669} --- modules/audio_coding/neteq/tools/neteq_replacement_input.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/audio_coding/neteq/tools/neteq_replacement_input.cc b/modules/audio_coding/neteq/tools/neteq_replacement_input.cc index 081bd9631f..f1a46cd2df 100644 --- a/modules/audio_coding/neteq/tools/neteq_replacement_input.cc +++ b/modules/audio_coding/neteq/tools/neteq_replacement_input.cc @@ -107,7 +107,7 @@ void NetEqReplacementInput::ReplacePacket() { next_hdr->timestamp - packet_->header.timestamp; const bool opus_dtx = packet_->payload.size() <= 2; if (next_hdr->sequenceNumber == packet_->header.sequenceNumber + 1 && - timestamp_diff <= 120 * 48 && !opus_dtx) { + timestamp_diff <= 120 * 48 && timestamp_diff > 0 && !opus_dtx) { // Packets are in order and the timestamp diff is less than 5760 samples. // Accept the timestamp diff as a valid frame size. input_frame_size_timestamps = timestamp_diff; From 1df269099fcb3c8e7474786a21bcdd32335c43ed Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 5 Feb 2024 10:02:08 -0800 Subject: [PATCH 074/170] Roll chromium_revision 82f331232d..0627ca51a7 (1256154:1256272) Change log: https://chromium.googlesource.com/chromium/src/+log/82f331232d..0627ca51a7 Full diff: https://chromium.googlesource.com/chromium/src/+/82f331232d..0627ca51a7 Changed dependencies * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/fc9e646cb3..d1fe4728f6 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/8c904c8500..5b4a897911 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/fa5d894853..dbb4ea2662 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/f52924d4de..59c1f68114 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/9dec55ff4f..dd3f5e97f3 * src/third_party/r8: X4a6wa4_8gQP775zUTVOXJEtzMNByOt6xLvdOc2_i_MC..yr6NtXUFlwC0IMXpA-KKdgva5QQ8ME9lm0LD3wz3lSQC * src/third_party/turbine: KfCqNpZ5XxbfuKiIsjeMWFX-6aJc5WN37x9weHyVDIkC..7NPeRX_XAc2XOUX7V9moyIEyM8RjjPdAhRK-8DLzk_oC * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/8cd7746c96..130c454a05 DEPS diff: https://chromium.googlesource.com/chromium/src/+/82f331232d..0627ca51a7/DEPS No update to Clang. BUG=None Change-Id: I0a2a2724a2f0686b799d01187416c14d1dabfdc1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338080 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41670} --- DEPS | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DEPS b/DEPS index a6e4ca33f7..1a8514e0b9 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '82f331232dcb85e9b6fa9fb5cf3871daf84072a4', + 'chromium_revision': '0627ca51a7f0fc13649180b41c3ff3c4f269d385', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -54,20 +54,20 @@ deps = { 'src/build': 'https://chromium.googlesource.com/chromium/src/build@f4542781a50accded1af4b2eca91e26bb532d35e', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@fc9e646cb3bfd0de93bce731d0f10096c022a63a', + 'https://chromium.googlesource.com/chromium/src/buildtools@d1fe4728f6bf18e51ded09740ee9aa308618444e', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@8c904c85009e8682d74be21f107c4add008b39b5', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@5b4a897911b5f364220eae7b9f477268a0a9e650', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@fa5d894853a65f90493ed71520f42dde51b8168f', + 'https://chromium.googlesource.com/chromium/src/testing@dbb4ea26624b1f11821105f8b0e96dc206b2e493', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@f52924d4de41c19e7f516c094f19c89ef9e9c489', + 'https://chromium.googlesource.com/chromium/src/third_party@59c1f68114538373de51d9b1375b25732abeb4dc', 'src/buildtools/linux64': { 'packages': [ @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@9dec55ff4fab02b2603910bba274fdf514cfbfd1', + 'https://android.googlesource.com/platform/external/perfetto.git@dd3f5e97f346774ecd3e49a2679f82cbc23fff98', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -331,7 +331,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'X4a6wa4_8gQP775zUTVOXJEtzMNByOt6xLvdOc2_i_MC', + 'version': 'yr6NtXUFlwC0IMXpA-KKdgva5QQ8ME9lm0LD3wz3lSQC', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@8cd7746c9635b12c318bbf1e478939a615424a3e', + 'https://chromium.googlesource.com/chromium/src/tools@130c454a0529d73cd54ee3f294ef5e6ef05fe670', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -498,7 +498,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/turbine', - 'version': 'KfCqNpZ5XxbfuKiIsjeMWFX-6aJc5WN37x9weHyVDIkC', + 'version': '7NPeRX_XAc2XOUX7V9moyIEyM8RjjPdAhRK-8DLzk_oC', }, ], 'condition': 'checkout_android', From 57a1232d754cef63ed286146e647df6661e015be Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Tue, 24 Oct 2023 13:09:02 +0200 Subject: [PATCH 075/170] Remove WebRtcVideoSendChannel::kDefaultQpMax https://webrtc-review.googlesource.com/c/src/+/324282 moved default QP to media/base/media_constants.h. Dependent projects have been switched to the new constant. Bug: webrtc:14852 Change-Id: Ic547a6b08490151d45543b68d4ed4b9da3a1629f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324820 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Sergey Silkin Cr-Commit-Position: refs/heads/main@{#41671} --- media/engine/webrtc_video_engine.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index 57de0b0465..d370a5445b 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -250,10 +250,6 @@ class WebRtcVideoSendChannel : public MediaChannelUtil, ADAPTREASON_BANDWIDTH = 2, }; - // TODO(webrtc:14852): Update downstream projects to use - // cricket::kDefaultVideoMaxQpVpx/H26x and remove. - static constexpr int kDefaultQpMax = 56; - // Implements webrtc::EncoderSwitchRequestCallback. void RequestEncoderFallback() override; void RequestEncoderSwitch(const webrtc::SdpVideoFormat& format, From 559e854da48b4d8e6d4a930603a88704062a9759 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 5 Feb 2024 14:01:59 -0800 Subject: [PATCH 076/170] Roll chromium_revision 0627ca51a7..224f3cf6ba (1256272:1256436) Change log: https://chromium.googlesource.com/chromium/src/+log/0627ca51a7..224f3cf6ba Full diff: https://chromium.googlesource.com/chromium/src/+/0627ca51a7..224f3cf6ba Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/f35773d19b..6dbc4c091b * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/5b4a897911..e6de825b66 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/dbb4ea2662..2c38863320 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/59c1f68114..6ae371969a * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/af6eabff53..0696c428b0 * src/third_party/libc++abi/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git/+log/0c4e8fac5c..fb278689d9 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/dd3f5e97f3..3deb235814 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/130c454a05..71ab0c4b0b DEPS diff: https://chromium.googlesource.com/chromium/src/+/0627ca51a7..224f3cf6ba/DEPS No update to Clang. BUG=None Change-Id: I5d5dfedebb1f3ec9023c985b89740be6e361976d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338120 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41672} --- DEPS | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DEPS b/DEPS index 1a8514e0b9..39ed98cc54 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '0627ca51a7f0fc13649180b41c3ff3c4f269d385', + 'chromium_revision': '224f3cf6ba715fcddd26ca796bbf146e496bc789', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,7 +50,7 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@f35773d19b451505fdc59b50331bb05a1f9ad03a', + 'https://chromium.googlesource.com/chromium/src/base@6dbc4c091bec1b885393b556cb0180aa05dfddda', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@f4542781a50accded1af4b2eca91e26bb532d35e', 'src/buildtools': @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@5b4a897911b5f364220eae7b9f477268a0a9e650', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@e6de825b662928f94b72198e5b416d1352f00cd4', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@dbb4ea26624b1f11821105f8b0e96dc206b2e493', + 'https://chromium.googlesource.com/chromium/src/testing@2c38863320d2a33a9f69b9705f2bd776a7ea3075', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@59c1f68114538373de51d9b1375b25732abeb4dc', + 'https://chromium.googlesource.com/chromium/src/third_party@6ae371969a79d98d6ba894ed86e7449e6146adad', 'src/buildtools/linux64': { 'packages': [ @@ -117,7 +117,7 @@ deps = { 'src/third_party/libc++/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@3c2f3884e62e17b137ede3e2f3e7214ef294e2c9', 'src/third_party/libc++abi/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@0c4e8fac5c5b369eb27093c0bdeae5dfad1aaf5c', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@fb278689d948a9a02e9c5ff4bdc9d524be2d4e82', 'src/third_party/libunwind/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@fc505746f02c927d792bdeb328307e0e87500342', @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@af6eabff5313cfdce7e4ff358e3490d1571ea4cd', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@0696c428b04513254d3b3e0b1fba5e5afdb11cf4', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@dd3f5e97f346774ecd3e49a2679f82cbc23fff98', + 'https://android.googlesource.com/platform/external/perfetto.git@3deb2358149574207c12407c7a6b2a885a5cef3b', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@130c454a0529d73cd54ee3f294ef5e6ef05fe670', + 'https://chromium.googlesource.com/chromium/src/tools@71ab0c4b0b0764a91fc90a7db4af03231790cc24', 'src/third_party/accessibility_test_framework': { 'packages': [ From 1188d0849f18baf91ab0061781ea1a521363b8bd Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 5 Feb 2024 18:02:22 -0800 Subject: [PATCH 077/170] Roll chromium_revision 224f3cf6ba..9983c30299 (1256436:1256551) Change log: https://chromium.googlesource.com/chromium/src/+log/224f3cf6ba..9983c30299 Full diff: https://chromium.googlesource.com/chromium/src/+/224f3cf6ba..9983c30299 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/6dbc4c091b..1613c3fb68 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/e6de825b66..8ef68e5171 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/2c38863320..065afd5a19 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/6ae371969a..b17629eef8 * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/432aa4ae6c..c2c3cef34d * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/3deb235814..786ec3a414 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/71ab0c4b0b..e232065eb7 DEPS diff: https://chromium.googlesource.com/chromium/src/+/224f3cf6ba..9983c30299/DEPS No update to Clang. BUG=None Change-Id: I4a75b934a17b407bea73081762bdb6b5e6065c1b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338121 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41673} --- DEPS | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DEPS b/DEPS index 39ed98cc54..3fdedf522a 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '224f3cf6ba715fcddd26ca796bbf146e496bc789', + 'chromium_revision': '9983c30299b6895ddefcde2e0cb3fb8f9db135b3', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,7 +50,7 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@6dbc4c091bec1b885393b556cb0180aa05dfddda', + 'https://chromium.googlesource.com/chromium/src/base@1613c3fb683884b2e37648035a330720d7423a62', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@f4542781a50accded1af4b2eca91e26bb532d35e', 'src/buildtools': @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@e6de825b662928f94b72198e5b416d1352f00cd4', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@8ef68e5171b2bf0a0700ba7d0281bf02a769c61a', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@2c38863320d2a33a9f69b9705f2bd776a7ea3075', + 'https://chromium.googlesource.com/chromium/src/testing@065afd5a19a71be5ff9bdec2af3d7c4f9e03688b', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@6ae371969a79d98d6ba894ed86e7449e6146adad', + 'https://chromium.googlesource.com/chromium/src/third_party@b17629eef8fd18764bfb99f94594513056b6777d', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@432aa4ae6c6931b15f595218bffb6c63512ac179', + 'https://chromium.googlesource.com/catapult.git@c2c3cef34d1a1cee17fffcf34c98a6a9a352d064', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@3deb2358149574207c12407c7a6b2a885a5cef3b', + 'https://android.googlesource.com/platform/external/perfetto.git@786ec3a414ad41aa627a88b83c7fd9bae5d59136', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@71ab0c4b0b0764a91fc90a7db4af03231790cc24', + 'https://chromium.googlesource.com/chromium/src/tools@e232065eb79f27308bdefac7130c8ce9d50e0434', 'src/third_party/accessibility_test_framework': { 'packages': [ From 26540f60717f976bb2be34086be07ef44d01cbef Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Mon, 5 Feb 2024 20:02:16 -0800 Subject: [PATCH 078/170] Update WebRTC code version (2024-02-06T04:02:15). Bug: None Change-Id: I8e652b68f1163cbf8c447d4181c73d11510a5b63 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338141 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41674} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index d0c62b7301..149af50d56 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-04T04:03:09"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-06T04:02:15"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 310c9d4cbe0f3d7bbf3e5bcc2a2a92c8c350372f Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Tue, 6 Feb 2024 02:01:54 -0800 Subject: [PATCH 079/170] Roll chromium_revision 9983c30299..4433ef31eb (1256551:1256671) Change log: https://chromium.googlesource.com/chromium/src/+log/9983c30299..4433ef31eb Full diff: https://chromium.googlesource.com/chromium/src/+/9983c30299..4433ef31eb Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/1613c3fb68..1e9268e9db * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/8ef68e5171..4ddde51c01 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/065afd5a19..730e222741 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/b17629eef8..1ec697ee9c * src/third_party/android_build_tools/manifest_merger: _BpuezAM4mQeQj5WNI7H6zkNx4nV2d8uGzcoJOlLQJcC..xxtHLi-sldjnrAZqfTewA7Ai7T_i46GDTkbeOQm4Da4C * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/c2c3cef34d..f092a8625f * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/0696c428b0..120efcb475 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/e232065eb7..1c38757126 DEPS diff: https://chromium.googlesource.com/chromium/src/+/9983c30299..4433ef31eb/DEPS No update to Clang. BUG=None Change-Id: I509536431fc25476bc5c941b5f6d3c23df638820 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338180 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41675} --- DEPS | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DEPS b/DEPS index 3fdedf522a..0c27f6f28e 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '9983c30299b6895ddefcde2e0cb3fb8f9db135b3', + 'chromium_revision': '4433ef31eb4de3ee3dede4818678240c38fb3e06', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,7 +50,7 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@1613c3fb683884b2e37648035a330720d7423a62', + 'https://chromium.googlesource.com/chromium/src/base@1e9268e9db707d44631387e3d5ebb8e47f4a2a28', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@f4542781a50accded1af4b2eca91e26bb532d35e', 'src/buildtools': @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@8ef68e5171b2bf0a0700ba7d0281bf02a769c61a', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@4ddde51c011cbe1e8fc19e981f5ed6d5df3c0714', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@065afd5a19a71be5ff9bdec2af3d7c4f9e03688b', + 'https://chromium.googlesource.com/chromium/src/testing@730e222741df80e9905d4cf0fc35bdc2627ab1b6', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@b17629eef8fd18764bfb99f94594513056b6777d', + 'https://chromium.googlesource.com/chromium/src/third_party@1ec697ee9c7bf956c0cbfab139a5fe2ea2d134d3', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@c2c3cef34d1a1cee17fffcf34c98a6a9a352d064', + 'https://chromium.googlesource.com/catapult.git@f092a8625f3f04979970ace175bd99c2f4196c08', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@0696c428b04513254d3b3e0b1fba5e5afdb11cf4', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@120efcb475aa5f8c6f38c4598c602f4713015112', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@e232065eb79f27308bdefac7130c8ce9d50e0434', + 'https://chromium.googlesource.com/chromium/src/tools@1c38757126c43ca9c6c8a9b0bb68b7f8767a2c7e', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -416,7 +416,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': '_BpuezAM4mQeQj5WNI7H6zkNx4nV2d8uGzcoJOlLQJcC', + 'version': 'xxtHLi-sldjnrAZqfTewA7Ai7T_i46GDTkbeOQm4Da4C', }, ], 'condition': 'checkout_android', From 8bb54c1c42d44b6e3aed3d5b88e39477e4cce168 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Tue, 6 Feb 2024 15:24:03 +0000 Subject: [PATCH 080/170] Penultimate split-up of rtc_p2p build target This takes the rest of the .cc files out of the rtc_p2p build target, leaving only one entangled target to clean up. Bug: webrtc:15796 Change-Id: I4312b70ffe96a8affc1a02456ac466eea05dd44c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338220 Commit-Queue: Harald Alvestrand Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41676} --- examples/BUILD.gn | 2 + p2p/BUILD.gn | 335 +++++++++++++++++++++++++++--- pc/BUILD.gn | 35 ++++ rtc_tools/network_tester/BUILD.gn | 1 + test/fuzzers/BUILD.gn | 1 + test/network/BUILD.gn | 3 + test/pc/e2e/BUILD.gn | 1 + test/peer_scenario/BUILD.gn | 1 + 8 files changed, 347 insertions(+), 32 deletions(-) diff --git a/examples/BUILD.gn b/examples/BUILD.gn index c3f66e0b98..d6940e2cba 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -809,6 +809,7 @@ if (is_linux || is_chromeos || is_win) { sources = [ "turnserver/turnserver_main.cc" ] deps = [ ":read_auth_file", + "../p2p:basic_packet_socket_factory", "../p2p:p2p_server_utils", "../p2p:port_interface", "../p2p:rtc_p2p", @@ -951,6 +952,7 @@ if (!build_with_chromium) { testonly = true sources = [ "stunprober/main.cc" ] deps = [ + "../p2p:basic_packet_socket_factory", "../p2p:libstunprober", "../p2p:rtc_p2p", "../rtc_base:checks", diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn index 8a5c8df065..5b7f07e361 100644 --- a/p2p/BUILD.gn +++ b/p2p/BUILD.gn @@ -23,18 +23,13 @@ rtc_library("rtc_p2p") { "base/active_ice_controller_factory_interface.h", # To be removed (Chrome) "base/active_ice_controller_interface.h", # To be removed (Internal) "base/basic_ice_controller.h", # To be removed (Chrome) - "base/basic_packet_socket_factory.cc", - "base/basic_packet_socket_factory.h", + "base/basic_packet_socket_factory.h", # To be removed "base/candidate_pair_interface.h", # To be removed "base/connection.h", # To be removed "base/connection_info.h", # To be removed - "base/default_ice_transport_factory.cc", - "base/default_ice_transport_factory.h", - "base/dtls_transport.cc", - "base/dtls_transport.h", - "base/dtls_transport_factory.h", - "base/dtls_transport_internal.cc", - "base/dtls_transport_internal.h", + "base/default_ice_transport_factory.h", # To be removed (Chrome) + "base/dtls_transport.h", # To be removed + "base/dtls_transport_internal.h", # To be removed "base/ice_agent_interface.h", # To be removed (Chrome) "base/ice_controller_interface.h", # To be removed (Chrome) "base/ice_credentials_iterator.h", # To be removed @@ -47,25 +42,15 @@ rtc_library("rtc_p2p") { "base/port.h", # To be removed (Chrome) "base/port_allocator.h", # To be removed (Chrome) "base/port_interface.h", # To be removed - "base/pseudo_tcp.cc", - "base/pseudo_tcp.h", + "base/pseudo_tcp.h", # To be removed "base/stun_dictionary.h", # To be removed - "base/stun_port.cc", - "base/stun_port.h", - "base/tcp_port.cc", - "base/tcp_port.h", + "base/stun_port.h", # To be removed + "base/tcp_port.h", # To be removed "base/transport_description.h", # To be removed - "base/transport_description_factory.cc", - "base/transport_description_factory.h", - "base/transport_info.h", - "base/turn_port.cc", - "base/turn_port.h", - "base/udp_port.h", - "client/basic_port_allocator.cc", - "client/basic_port_allocator.h", - "client/relay_port_factory_interface.h", - "client/turn_port_factory.cc", - "client/turn_port_factory.h", + "base/transport_info.h", # To be removed + "base/turn_port.h", # To be removed + "client/basic_port_allocator.h", # To be removed + "client/turn_port_factory.h", # To be removed ] deps = [ @@ -73,9 +58,12 @@ rtc_library("rtc_p2p") { ":async_stun_tcp_socket", ":basic_async_resolver_factory", ":basic_ice_controller", + ":basic_packet_socket_factory", ":candidate_pair_interface", ":connection", ":connection_info", + ":dtls_transport", + ":dtls_transport_internal", ":ice_agent_interface", ":ice_controller_factory_interface", ":ice_controller_interface", @@ -87,10 +75,14 @@ rtc_library("rtc_p2p") { ":p2p_transport_channel_ice_field_trials", ":packet_transport_internal", ":port_interface", + ":pseudo_tcp", ":regathering_controller", + ":relay_port_factory_interface", ":stun_dictionary", ":stun_request", + ":tcp_port", ":transport_description", + ":udp_port", ":wrapping_active_ice_controller", "../api:array_view", "../api:async_dns_resolver", @@ -107,6 +99,7 @@ rtc_library("rtc_p2p") { "../api/crypto:options", "../api/rtc_event_log", "../api/task_queue", + "../api/task_queue:pending_task_safety_flag", "../api/transport:enums", "../api/transport:field_trial_based_config", "../api/transport:stun_types", @@ -139,6 +132,7 @@ rtc_library("rtc_p2p") { "../rtc_base:rate_tracker", "../rtc_base:refcount", "../rtc_base:rtc_numerics", + "../rtc_base:safe_minmax", "../rtc_base:socket", "../rtc_base:socket_adapters", "../rtc_base:socket_address", @@ -149,18 +143,14 @@ rtc_library("rtc_p2p") { "../rtc_base:stringutils", "../rtc_base:threading", "../rtc_base:timeutils", + "../rtc_base:weak_ptr", "../rtc_base/containers:flat_map", "../rtc_base/experiments:field_trial_parser", "../rtc_base/memory:always_valid_pointer", - "../rtc_base/system:no_unique_address", - - # Needed by pseudo_tcp, which should move to a separate target. - "../api/task_queue:pending_task_safety_flag", - "../rtc_base:safe_minmax", - "../rtc_base:weak_ptr", "../rtc_base/network:received_packet", "../rtc_base/network:sent_packet", "../rtc_base/synchronization:mutex", + "../rtc_base/system:no_unique_address", "../rtc_base/system:rtc_export", "../rtc_base/third_party/base64", "../rtc_base/third_party/sigslot", @@ -242,6 +232,32 @@ rtc_library("basic_ice_controller") { ] } +rtc_library("basic_packet_socket_factory") { + sources = [ + "base/basic_packet_socket_factory.cc", + "base/basic_packet_socket_factory.h", + ] + deps = [ + ":async_stun_tcp_socket", + "../api:async_dns_resolver", + "../api:packet_socket_factory", + "../rtc_base:async_dns_resolver", + "../rtc_base:async_packet_socket", + "../rtc_base:async_tcp_socket", + "../rtc_base:async_udp_socket", + "../rtc_base:checks", + "../rtc_base:logging", + "../rtc_base:proxy_info", + "../rtc_base:socket", + "../rtc_base:socket_adapters", + "../rtc_base:socket_address", + "../rtc_base:socket_factory", + "../rtc_base:ssl", + "../rtc_base/system:rtc_export", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] +} + rtc_source_set("candidate_pair_interface") { sources = [ "base/candidate_pair_interface.h" ] } @@ -331,6 +347,81 @@ rtc_library("connection_info") { absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } +rtc_library("default_ice_transport_factory") { + sources = [ + "base/default_ice_transport_factory.cc", + "base/default_ice_transport_factory.h", + ] + deps = [ + ":basic_ice_controller", + ":ice_controller_factory_interface", + ":p2p_transport_channel", + "../api:ice_transport_interface", + "../api:make_ref_counted", + "../rtc_base:threading", + ] +} + +rtc_library("dtls_transport") { + sources = [ + "base/dtls_transport.cc", + "base/dtls_transport.h", + ] + deps = [ + ":dtls_transport_internal", + ":ice_transport_internal", + ":packet_transport_internal", + "../api:array_view", + "../api:dtls_transport_interface", + "../api:sequence_checker", + "../api/crypto:options", + "../api/rtc_event_log", + "../logging:ice_log", + "../rtc_base:buffer", + "../rtc_base:buffer_queue", + "../rtc_base:checks", + "../rtc_base:dscp", + "../rtc_base:logging", + "../rtc_base:ssl", + "../rtc_base:stream", + "../rtc_base:stringutils", + "../rtc_base:threading", + "../rtc_base/system:no_unique_address", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings:string_view", + ] +} + +rtc_source_set("dtls_transport_factory") { + sources = [ "base/dtls_transport_factory.h" ] + deps = [ + ":dtls_transport_internal", + ":ice_transport_internal", + ] +} + +rtc_library("dtls_transport_internal") { + sources = [ + "base/dtls_transport_internal.cc", + "base/dtls_transport_internal.h", + ] + deps = [ + ":ice_transport_internal", + ":packet_transport_internal", + "../api:dtls_transport_interface", + "../api:scoped_refptr", + "../api/crypto:options", + "../rtc_base:callback_list", + "../rtc_base:ssl", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/strings:string_view", + ] +} + rtc_source_set("ice_agent_interface") { sources = [ "base/ice_agent_interface.h" ] deps = [ @@ -616,6 +707,24 @@ rtc_library("port_interface") { ] } +rtc_library("pseudo_tcp") { + sources = [ + "base/pseudo_tcp.cc", + "base/pseudo_tcp.h", + ] + deps = [ + "../rtc_base:byte_buffer", + "../rtc_base:byte_order", + "../rtc_base:checks", + "../rtc_base:logging", + "../rtc_base:safe_minmax", + "../rtc_base:socket", + "../rtc_base:timeutils", + "../rtc_base/synchronization:mutex", + "../rtc_base/system:rtc_export", + ] +} + rtc_library("regathering_controller") { sources = [ "base/regathering_controller.cc", @@ -643,6 +752,35 @@ rtc_library("stun_dictionary") { ] } +rtc_library("stun_port") { + sources = [ + "base/stun_port.cc", + "base/stun_port.h", + ] + deps = [ + ":connection", + ":p2p_constants", + ":port", + ":port_allocator", + ":stun_request", + "../api/task_queue:pending_task_safety_flag", + "../api/transport:stun_types", + "../rtc_base:async_packet_socket", + "../rtc_base:checks", + "../rtc_base:ip_address", + "../rtc_base:logging", + "../rtc_base:ssl", + "../rtc_base:stringutils", + "../rtc_base/experiments:field_trial_parser", + "../rtc_base/network:received_packet", + "../rtc_base/system:rtc_export", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings:string_view", + ] +} + rtc_library("stun_request") { sources = [ "base/stun_request.cc", @@ -662,6 +800,34 @@ rtc_library("stun_request") { absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] } +rtc_library("tcp_port") { + sources = [ + "base/tcp_port.cc", + "base/tcp_port.h", + ] + deps = [ + ":connection", + ":p2p_constants", + ":port", + "../api/task_queue:pending_task_safety_flag", + "../api/units:time_delta", + "../rtc_base:async_packet_socket", + "../rtc_base:checks", + "../rtc_base:ip_address", + "../rtc_base:logging", + "../rtc_base:net_helper", + "../rtc_base:rate_tracker", + "../rtc_base:threading", + "../rtc_base/containers:flat_map", + "../rtc_base/network:received_packet", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings:string_view", + ] +} + rtc_library("transport_description") { sources = [ "base/transport_description.cc", @@ -684,6 +850,98 @@ rtc_library("transport_description") { ] } +rtc_library("transport_description_factory") { + sources = [ + "base/transport_description_factory.cc", + "base/transport_description_factory.h", + ] + deps = [ + ":ice_credentials_iterator", + ":rtc_p2p", + "../api:field_trials_view", + "../rtc_base:logging", + "../rtc_base:ssl", + ] +} + +rtc_source_set("transport_info") { + sources = [ "base/transport_info.h" ] + deps = [ + ":p2p_constants", + ":rtc_p2p", + "../api:candidate", + "../rtc_base:ssl", + ] +} + +rtc_source_set("udp_port") { + sources = [ "base/udp_port.h" ] + deps = [ ":stun_port" ] +} + +rtc_library("basic_port_allocator_and_turn_port") { + sources = [ + "base/turn_port.cc", + "base/turn_port.h", + "client/basic_port_allocator.cc", + "client/basic_port_allocator.h", + "client/turn_port_factory.cc", + "client/turn_port_factory.h", + ] + deps = [ + ":basic_packet_socket_factory", + ":connection", + ":p2p_constants", + ":port", + ":port_allocator", + ":relay_port_factory_interface", + ":stun_port", + ":tcp_port", + ":udp_port", + "../api:async_dns_resolver", + "../api:field_trials_view", + "../api:turn_customizer", + "../api/task_queue", + "../api/task_queue:pending_task_safety_flag", + "../api/transport:field_trial_based_config", + "../api/transport:stun_types", + "../api/units:time_delta", + "../rtc_base:async_packet_socket", + "../rtc_base:byte_order", + "../rtc_base:checks", + "../rtc_base:event_tracer", + "../rtc_base:logging", + "../rtc_base:macromagic", + "../rtc_base:net_helpers", + "../rtc_base:network", + "../rtc_base:network_constants", + "../rtc_base:socket_address", + "../rtc_base:ssl", + "../rtc_base:stringutils", + "../rtc_base:threading", + "../rtc_base/experiments:field_trial_parser", + "../rtc_base/memory:always_valid_pointer", + "../rtc_base/network:received_packet", + "../rtc_base/system:rtc_export", + "../system_wrappers:metrics", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings", + "//third_party/abseil-cpp/absl/strings:string_view", + "//third_party/abseil-cpp/absl/types:optional", + ] +} + +rtc_source_set("relay_port_factory_interface") { + sources = [ "client/relay_port_factory_interface.h" ] + deps = [ + ":port_interface", + "../rtc_base:refcount", + ] +} + rtc_library("wrapping_active_ice_controller") { sources = [ "base/wrapping_active_ice_controller.cc", @@ -736,8 +994,10 @@ if (rtc_include_tests) { visibility = [ "*" ] sources = [ "base/fake_port_allocator.h" ] deps = [ + ":basic_packet_socket_factory", ":connection", ":rtc_p2p", + ":udp_port", "../rtc_base:net_helpers", "../rtc_base:net_test_helpers", "../rtc_base:task_queue_for_test", @@ -765,7 +1025,9 @@ if (rtc_include_tests) { deps = [ ":active_ice_controller_factory_interface", ":active_ice_controller_interface", + ":basic_packet_socket_factory", ":connection", + ":dtls_transport_internal", ":fake_ice_transport", ":fake_port_allocator", ":ice_agent_interface", @@ -833,7 +1095,10 @@ if (rtc_include_tests) { ":active_ice_controller_interface", ":async_stun_tcp_socket", ":basic_ice_controller", + ":basic_packet_socket_factory", + ":basic_port_allocator_and_turn_port", ":connection", + ":dtls_transport", ":fake_ice_transport", ":fake_port_allocator", ":ice_credentials_iterator", @@ -844,11 +1109,16 @@ if (rtc_include_tests) { ":p2p_transport_channel", ":packet_transport_internal", ":port_interface", + ":pseudo_tcp", ":regathering_controller", + ":relay_port_factory_interface", ":rtc_p2p", ":stun_dictionary", + ":stun_port", ":stun_request", + ":tcp_port", ":transport_description", + ":transport_description_factory", ":wrapping_active_ice_controller", "../api:array_view", "../api:candidate", @@ -981,6 +1251,7 @@ if (rtc_include_tests) { sources = [ "stunprober/stun_prober_unittest.cc" ] deps = [ + ":basic_packet_socket_factory", ":libstunprober", ":p2p_test_utils", ":rtc_p2p", diff --git a/pc/BUILD.gn b/pc/BUILD.gn index a426e9b8c5..92eae42a46 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -87,6 +87,7 @@ rtc_source_set("channel") { "../media:rtp_utils", "../media:stream_params", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:dtls_transport_internal", "../p2p:rtc_p2p", "../rtc_base:async_packet_socket", "../rtc_base:checks", @@ -134,6 +135,7 @@ rtc_source_set("dtls_srtp_transport") { "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", "../api:rtc_error", + "../p2p:dtls_transport_internal", "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../rtc_base:buffer", @@ -158,6 +160,8 @@ rtc_source_set("dtls_transport") { "../api:make_ref_counted", "../api:scoped_refptr", "../api:sequence_checker", + "../p2p:dtls_transport", + "../p2p:dtls_transport_internal", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:logging", @@ -226,11 +230,14 @@ rtc_source_set("jsep_transport") { "../api:sequence_checker", "../api/transport:datagram_transport_interface", "../media:rtc_data_sctp_transport_internal", + "../p2p:dtls_transport", + "../p2p:dtls_transport_internal", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", "../rtc_base:event_tracer", @@ -302,12 +309,16 @@ rtc_source_set("jsep_transport_controller") { "../api/transport:sctp_transport_factory_interface", "../media:rtc_data_sctp_transport_internal", "../p2p:connection", + "../p2p:dtls_transport", + "../p2p:dtls_transport_factory", + "../p2p:dtls_transport_internal", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:callback_list", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", @@ -363,6 +374,8 @@ rtc_source_set("media_session") { "../p2p:p2p_constants", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_description_factory", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:ssl", @@ -522,6 +535,7 @@ rtc_source_set("sctp_transport") { "../api:sequence_checker", "../api/transport:datagram_transport_interface", "../media:rtc_data_sctp_transport_internal", + "../p2p:dtls_transport_internal", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:logging", @@ -655,6 +669,7 @@ rtc_source_set("transport_stats") { "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", "../p2p:connection", + "../p2p:dtls_transport_internal", "../p2p:ice_transport_internal", "../p2p:rtc_p2p", "../rtc_base:ssl", @@ -714,6 +729,7 @@ rtc_source_set("session_description") { "../media:stream_params", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:socket_address", "../rtc_base:stringutils", @@ -823,6 +839,7 @@ rtc_library("connection_context") { "../api/transport:sctp_transport_factory_interface", "../media:rtc_data_sctp_transport_factory", "../media:rtc_media_base", + "../p2p:basic_packet_socket_factory", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:macromagic", @@ -1035,6 +1052,8 @@ rtc_source_set("sdp_offer_answer") { "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_description_factory", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:event_tracer", "../rtc_base:logging", @@ -1142,11 +1161,13 @@ rtc_source_set("peer_connection") { "../p2p:basic_async_resolver_factory", "../p2p:connection", "../p2p:connection_info", + "../p2p:dtls_transport_internal", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", "../rtc_base:event_tracer", @@ -1202,6 +1223,7 @@ rtc_source_set("sdp_utils") { ":session_description", "../api:libjingle_peerconnection_api", "../p2p:rtc_p2p", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base/system:rtc_export", ] @@ -1321,6 +1343,7 @@ rtc_source_set("webrtc_sdp") { "../p2p:port_interface", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:checks", "../rtc_base:ip_address", "../rtc_base:logging", @@ -1356,6 +1379,7 @@ rtc_source_set("webrtc_session_description_factory") { "../api/task_queue", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_description_factory", "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:rtc_certificate_generator", @@ -1446,7 +1470,10 @@ rtc_source_set("peer_connection_factory") { "../call:rtp_interfaces", "../call:rtp_sender", "../media:rtc_media_base", + "../p2p:basic_packet_socket_factory", + "../p2p:basic_port_allocator_and_turn_port", "../p2p:connection", + "../p2p:default_ice_transport_factory", "../p2p:rtc_p2p", "../pc:audio_track", "../pc:connection_context", @@ -2078,6 +2105,8 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_tests_utils", "../modules/rtp_rtcp:rtp_rtcp_format", "../p2p:candidate_pair_interface", + "../p2p:dtls_transport_factory", + "../p2p:dtls_transport_internal", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", "../p2p:ice_transport_internal", @@ -2086,6 +2115,7 @@ if (rtc_include_tests && !build_with_chromium) { "../p2p:packet_transport_internal", "../p2p:rtc_p2p", "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:async_packet_socket", "../rtc_base:buffer", "../rtc_base:byte_order", @@ -2167,6 +2197,7 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_tests_utils", "../modules/audio_device:audio_device_api", "../modules/audio_processing:api", + "../p2p:basic_port_allocator_and_turn_port", "../p2p:connection", "../p2p:p2p_test_utils", "../p2p:port_interface", @@ -2403,14 +2434,17 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_device:audio_device_api", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:basic_port_allocator_and_turn_port", "../p2p:connection", "../p2p:connection_info", + "../p2p:dtls_transport_internal", "../p2p:fake_port_allocator", "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_server_utils", "../p2p:port_interface", "../p2p:transport_description", + "../p2p:transport_info", "../rtc_base:byte_buffer", "../rtc_base:checks", "../rtc_base:copy_on_write_buffer", @@ -2619,6 +2653,7 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing:audio_processing_statistics", "../modules/audio_processing:audioproc_test_utils", "../modules/rtp_rtcp:rtp_rtcp_format", + "../p2p:basic_port_allocator_and_turn_port", "../p2p:connection", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", diff --git a/rtc_tools/network_tester/BUILD.gn b/rtc_tools/network_tester/BUILD.gn index e44681441a..da62266520 100644 --- a/rtc_tools/network_tester/BUILD.gn +++ b/rtc_tools/network_tester/BUILD.gn @@ -44,6 +44,7 @@ if (rtc_enable_protobuf) { "../../api/task_queue:default_task_queue_factory", "../../api/task_queue:pending_task_safety_flag", "../../api/units:timestamp", + "../../p2p:basic_packet_socket_factory", "../../p2p:rtc_p2p", "../../rtc_base:async_packet_socket", "../../rtc_base:checks", diff --git a/test/fuzzers/BUILD.gn b/test/fuzzers/BUILD.gn index 4f6a542e54..642b0c8e08 100644 --- a/test/fuzzers/BUILD.gn +++ b/test/fuzzers/BUILD.gn @@ -476,6 +476,7 @@ webrtc_fuzzer_test("stun_validator_fuzzer") { webrtc_fuzzer_test("pseudotcp_parser_fuzzer") { sources = [ "pseudotcp_parser_fuzzer.cc" ] deps = [ + "../../p2p:pseudo_tcp", "../../p2p:rtc_p2p", "../../rtc_base:threading", ] diff --git a/test/network/BUILD.gn b/test/network/BUILD.gn index 6df563d31d..8f1e0d6f80 100644 --- a/test/network/BUILD.gn +++ b/test/network/BUILD.gn @@ -56,6 +56,7 @@ rtc_library("emulated_network") { "../../api/units:time_delta", "../../api/units:timestamp", "../../call:simulated_network", + "../../p2p:basic_packet_socket_factory", "../../p2p:p2p_server_utils", "../../p2p:rtc_p2p", "../../rtc_base:async_packet_socket", @@ -128,6 +129,8 @@ if (rtc_include_tests && !build_with_chromium) { "../../call:simulated_network", "../../media:rtc_audio_video", "../../modules/audio_device:test_audio_device_module", + "../../p2p:basic_packet_socket_factory", + "../../p2p:basic_port_allocator_and_turn_port", "../../p2p:rtc_p2p", "../../pc:pc_test_utils", "../../pc:peerconnection_wrapper", diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn index e0d3dbe0bc..eca7b1b353 100644 --- a/test/pc/e2e/BUILD.gn +++ b/test/pc/e2e/BUILD.gn @@ -109,6 +109,7 @@ if (!build_with_chromium) { "../../../api/video_codecs:builtin_video_encoder_factory", "../../../modules/audio_device:test_audio_device_module", "../../../modules/audio_processing/aec_dump", + "../../../p2p:basic_port_allocator_and_turn_port", "../../../p2p:rtc_p2p", "../../../rtc_base:threading", "analyzer/video:quality_analyzing_video_encoder", diff --git a/test/peer_scenario/BUILD.gn b/test/peer_scenario/BUILD.gn index 4736f675ef..bfd9f4617b 100644 --- a/test/peer_scenario/BUILD.gn +++ b/test/peer_scenario/BUILD.gn @@ -53,6 +53,7 @@ if (rtc_include_tests) { "../../media:rtp_utils", "../../modules/audio_device:test_audio_device_module", "../../modules/rtp_rtcp:rtp_rtcp_format", + "../../p2p:basic_port_allocator_and_turn_port", "../../p2p:rtc_p2p", "../../p2p:transport_description", "../../pc:channel", From 0a92fe8b617334e11e296f0bf571c4b329181c94 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Tue, 6 Feb 2024 10:14:18 -0800 Subject: [PATCH 081/170] Roll chromium_revision 4433ef31eb..b77c10eec3 (1256671:1256869) Change log: https://chromium.googlesource.com/chromium/src/+log/4433ef31eb..b77c10eec3 Full diff: https://chromium.googlesource.com/chromium/src/+/4433ef31eb..b77c10eec3 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/1e9268e9db..bd360beaa8 * src/build: https://chromium.googlesource.com/chromium/src/build/+log/f4542781a5..5347b65643 * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/d1fe4728f6..2bda660f98 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/4ddde51c01..5bae19f119 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/730e222741..03acf75d86 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/1ec697ee9c..676beca3fb * src/third_party/libc++/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git/+log/3c2f3884e6..6024b26887 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/786ec3a414..5cafd5f37c * src/third_party/r8: yr6NtXUFlwC0IMXpA-KKdgva5QQ8ME9lm0LD3wz3lSQC..Wpuxcm9gcq_RziIlCD0O_dgjRUr75g61LfP2iXo4FTsC * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/1c38757126..4a580ac431 DEPS diff: https://chromium.googlesource.com/chromium/src/+/4433ef31eb..b77c10eec3/DEPS No update to Clang. BUG=None Change-Id: Id8ae348cd27c9d5692a205f48ff641dd7b6b616d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338300 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41677} --- DEPS | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/DEPS b/DEPS index 0c27f6f28e..90e5324adb 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '4433ef31eb4de3ee3dede4818678240c38fb3e06', + 'chromium_revision': 'b77c10eec36981a11c8c8f32db84b844c09d1c72', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@1e9268e9db707d44631387e3d5ebb8e47f4a2a28', + 'https://chromium.googlesource.com/chromium/src/base@bd360beaa8716c1673cbd69ddad23b97c5eced5a', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@f4542781a50accded1af4b2eca91e26bb532d35e', + 'https://chromium.googlesource.com/chromium/src/build@5347b6564336aaa53809dd92ddf7173f242ca7a8', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@d1fe4728f6bf18e51ded09740ee9aa308618444e', + 'https://chromium.googlesource.com/chromium/src/buildtools@2bda660f9814845f0d9a109b6927da7bf0a3a11f', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@4ddde51c011cbe1e8fc19e981f5ed6d5df3c0714', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@5bae19f1194d4bb475e84ee989f5404b53a007f1', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@730e222741df80e9905d4cf0fc35bdc2627ab1b6', + 'https://chromium.googlesource.com/chromium/src/testing@03acf75d865ad9f7a0d809e5e4215815c3ac5874', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@1ec697ee9c7bf956c0cbfab139a5fe2ea2d134d3', + 'https://chromium.googlesource.com/chromium/src/third_party@676beca3fb077c1218fe994b702c64e1a6582a8a', 'src/buildtools/linux64': { 'packages': [ @@ -115,7 +115,7 @@ deps = { 'src/third_party/clang-format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@e5337933f2951cacd3aeacd238ce4578163ca0b9', 'src/third_party/libc++/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@3c2f3884e62e17b137ede3e2f3e7214ef294e2c9', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@6024b26887625fef52ea0f227d888c4b815488be', 'src/third_party/libc++abi/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@fb278689d948a9a02e9c5ff4bdc9d524be2d4e82', 'src/third_party/libunwind/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@786ec3a414ad41aa627a88b83c7fd9bae5d59136', + 'https://android.googlesource.com/platform/external/perfetto.git@5cafd5f37c15d474540c4a3439129381f4184f39', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -331,7 +331,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'yr6NtXUFlwC0IMXpA-KKdgva5QQ8ME9lm0LD3wz3lSQC', + 'version': 'Wpuxcm9gcq_RziIlCD0O_dgjRUr75g61LfP2iXo4FTsC', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@1c38757126c43ca9c6c8a9b0bb68b7f8767a2c7e', + 'https://chromium.googlesource.com/chromium/src/tools@4a580ac431f0a54988bf607905a6b60c0c4b4800', 'src/third_party/accessibility_test_framework': { 'packages': [ From f0895f77336696995b173a89fea5815d17fd9b47 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Tue, 6 Feb 2024 14:02:03 -0800 Subject: [PATCH 082/170] Roll chromium_revision b77c10eec3..553b5dd870 (1256869:1257025) Change log: https://chromium.googlesource.com/chromium/src/+log/b77c10eec3..553b5dd870 Full diff: https://chromium.googlesource.com/chromium/src/+/b77c10eec3..553b5dd870 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/bd360beaa8..f018f4f734 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/5bae19f119..6dc8bd1ec4 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/03acf75d86..7328b96358 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/676beca3fb..3a5018f262 * src/third_party/androidx: 6uuKw5DN2kX3odjXxnfntoWPy4DOE00A65kTz33wmEYC..7mJZ3v-PCBM6d2aoz8s5V6ix1M_RJi-94No7oO0IIC0C * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/120efcb475..1f441eb375 * src/third_party/libc++abi/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git/+log/fb278689d9..a7b3d968a3 * src/third_party/libyuv: https://chromium.googlesource.com/libyuv/libyuv.git/+log/d359a9f922..2f2c04c157 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/5cafd5f37c..cae24fbd60 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/4a580ac431..982af6cab0 Added dependencies * src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_parcelize_runtime * src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_android_extensions_runtime DEPS diff: https://chromium.googlesource.com/chromium/src/+/b77c10eec3..553b5dd870/DEPS No update to Clang. BUG=None Change-Id: I8ef4c62c577492d6fcb3ffd505ff0e6a861f2712 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338203 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41678} --- DEPS | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/DEPS b/DEPS index 90e5324adb..b2cc017f47 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'b77c10eec36981a11c8c8f32db84b844c09d1c72', + 'chromium_revision': '553b5dd87036c98b712ab88ab13ac5ec1dedcb54', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,7 +50,7 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@bd360beaa8716c1673cbd69ddad23b97c5eced5a', + 'https://chromium.googlesource.com/chromium/src/base@f018f4f734fecbac9bc814e7f3f94b9464a4a2d6', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@5347b6564336aaa53809dd92ddf7173f242ca7a8', 'src/buildtools': @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@5bae19f1194d4bb475e84ee989f5404b53a007f1', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@6dc8bd1ec4b2e5fd923ded448c83dfaff4956e09', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@03acf75d865ad9f7a0d809e5e4215815c3ac5874', + 'https://chromium.googlesource.com/chromium/src/testing@7328b963585dbe66a53330052b73102b7527d9e1', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@676beca3fb077c1218fe994b702c64e1a6582a8a', + 'https://chromium.googlesource.com/chromium/src/third_party@3a5018f26295088029eec98ec3b7bcd74afcd732', 'src/buildtools/linux64': { 'packages': [ @@ -117,7 +117,7 @@ deps = { 'src/third_party/libc++/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@6024b26887625fef52ea0f227d888c4b815488be', 'src/third_party/libc++abi/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@fb278689d948a9a02e9c5ff4bdc9d524be2d4e82', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@a7b3d968a3a923886fea64b424bd770e69dc4ea4', 'src/third_party/libunwind/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@fc505746f02c927d792bdeb328307e0e87500342', @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@120efcb475aa5f8c6f38c4598c602f4713015112', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@1f441eb375f1eb37c9b2b2e923f48cce656bb443', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,11 +302,11 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@5cafd5f37c15d474540c4a3439129381f4184f39', + 'https://android.googlesource.com/platform/external/perfetto.git@cae24fbd60a9407dbd4063abc8240681d30e8967', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': - 'https://chromium.googlesource.com/libyuv/libyuv.git@d359a9f922af840b043535d43cf9d38b220d102e', + 'https://chromium.googlesource.com/libyuv/libyuv.git@2f2c04c1576534a7df953c2dc7c7ccf30beacd89', 'src/third_party/lss': { 'url': 'https://chromium.googlesource.com/linux-syscall-support.git@ce877209e11aa69dcfffbd53ef90ea1d07136521', 'condition': 'checkout_android or checkout_linux', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@4a580ac431f0a54988bf607905a6b60c0c4b4800', + 'https://chromium.googlesource.com/chromium/src/tools@982af6cab08dbc642fc09bf571d2e7ef3cfd7a5b', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -405,7 +405,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '6uuKw5DN2kX3odjXxnfntoWPy4DOE00A65kTz33wmEYC', + 'version': '7mJZ3v-PCBM6d2aoz8s5V6ix1M_RJi-94No7oO0IIC0C', }, ], 'condition': 'checkout_android', @@ -1868,6 +1868,28 @@ deps = { 'dep_type': 'cipd', }, + 'src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_android_extensions_runtime': { + 'packages': [ + { + 'package': 'chromium/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_android_extensions_runtime', + 'version': 'version:2@1.9.22.cr1', + }, + ], + 'condition': 'checkout_android', + 'dep_type': 'cipd', + }, + + 'src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_parcelize_runtime': { + 'packages': [ + { + 'package': 'chromium/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_parcelize_runtime', + 'version': 'version:2@1.9.22.cr1', + }, + ], + 'condition': 'checkout_android', + 'dep_type': 'cipd', + }, + 'src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7': { 'packages': [ { From 72fdb6533065c0ad5f6987afe64d223409a1d8df Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Tue, 6 Feb 2024 18:02:00 -0800 Subject: [PATCH 083/170] Roll chromium_revision 553b5dd870..5c1222c039 (1257025:1257135) Change log: https://chromium.googlesource.com/chromium/src/+log/553b5dd870..5c1222c039 Full diff: https://chromium.googlesource.com/chromium/src/+/553b5dd870..5c1222c039 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/f018f4f734..cdd683921b * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/2bda660f98..262e0f6f64 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/6dc8bd1ec4..525498cea9 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/7328b96358..faa67274bf * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/3a5018f262..a59d781695 * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/f092a8625f..6d39c23fce * src/third_party/libc++/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git/+log/6024b26887..9d119c1f4a * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/cae24fbd60..450c05cd3b * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/982af6cab0..71a8b59f46 DEPS diff: https://chromium.googlesource.com/chromium/src/+/553b5dd870..5c1222c039/DEPS No update to Clang. BUG=None Change-Id: I279634c3fd7e2e3cf8e4f408534f41cd83a4ec9f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338205 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41679} --- DEPS | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/DEPS b/DEPS index b2cc017f47..ce0c24d779 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '553b5dd87036c98b712ab88ab13ac5ec1dedcb54', + 'chromium_revision': '5c1222c039c4c405474143f6beb91904da6375e0', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@f018f4f734fecbac9bc814e7f3f94b9464a4a2d6', + 'https://chromium.googlesource.com/chromium/src/base@cdd683921b46fb95b9fd9dc867b823385abf3c5e', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@5347b6564336aaa53809dd92ddf7173f242ca7a8', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@2bda660f9814845f0d9a109b6927da7bf0a3a11f', + 'https://chromium.googlesource.com/chromium/src/buildtools@262e0f6f649a83f5ac98f3bac6eefff66fb90133', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@6dc8bd1ec4b2e5fd923ded448c83dfaff4956e09', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@525498cea9c712ecd59200a9f5752e7737d6dcfa', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@7328b963585dbe66a53330052b73102b7527d9e1', + 'https://chromium.googlesource.com/chromium/src/testing@faa67274bf4519d5b5cbde7b2604ad1adf3b44ad', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@3a5018f26295088029eec98ec3b7bcd74afcd732', + 'https://chromium.googlesource.com/chromium/src/third_party@a59d781695ef8650f9cc3d16fd90e3d121497693', 'src/buildtools/linux64': { 'packages': [ @@ -115,7 +115,7 @@ deps = { 'src/third_party/clang-format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@e5337933f2951cacd3aeacd238ce4578163ca0b9', 'src/third_party/libc++/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@6024b26887625fef52ea0f227d888c4b815488be', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@9d119c1f4a097b7d27210874f4eba3fc91a83a4e', 'src/third_party/libc++abi/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@a7b3d968a3a923886fea64b424bd770e69dc4ea4', 'src/third_party/libunwind/src': @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@f092a8625f3f04979970ace175bd99c2f4196c08', + 'https://chromium.googlesource.com/catapult.git@6d39c23fce9fdf9e5ce7c5730de4bc14556ec159', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@cae24fbd60a9407dbd4063abc8240681d30e8967', + 'https://android.googlesource.com/platform/external/perfetto.git@450c05cd3bd3e596f4757cca3217182d764b9ba9', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@982af6cab08dbc642fc09bf571d2e7ef3cfd7a5b', + 'https://chromium.googlesource.com/chromium/src/tools@71a8b59f465754b542f9151447144ff88f622b56', 'src/third_party/accessibility_test_framework': { 'packages': [ From 5c7bc9fa02d3d9a154fa073eeb23132b8f243137 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Tue, 6 Feb 2024 20:02:18 -0800 Subject: [PATCH 084/170] Update WebRTC code version (2024-02-07T04:02:17). Bug: None Change-Id: I878a5152ec03159e65d82dd9962ee5830d39d3ba Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338380 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41680} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 149af50d56..c07f1262c4 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-06T04:02:15"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-07T04:02:17"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 6de9d6add0bf7b5a83d8853bc8d348f4b0ca6d93 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Wed, 7 Feb 2024 07:51:39 +0100 Subject: [PATCH 085/170] Add default AV1 parameters to SdpVideoFormat comparison BUG=webrtc:15703 Change-Id: Ib3195b61b27c38a27d851119cdbf55c679b839c8 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337540 Commit-Queue: Philipp Hancke Reviewed-by: Sergey Silkin Reviewed-by: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41681} --- api/video_codecs/sdp_video_format.cc | 40 +++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/api/video_codecs/sdp_video_format.cc b/api/video_codecs/sdp_video_format.cc index 5e311d1134..5abde8fbb0 100644 --- a/api/video_codecs/sdp_video_format.cc +++ b/api/video_codecs/sdp_video_format.cc @@ -29,14 +29,21 @@ namespace webrtc { namespace { -std::string H264GetPacketizationModeOrDefault(const CodecParameterMap& params) { - const auto it = params.find(cricket::kH264FmtpPacketizationMode); +std::string GetFmtpParameterOrDefault(const CodecParameterMap& params, + const std::string& name, + const std::string& default_value) { + const auto it = params.find(name); if (it != params.end()) { return it->second; } + return default_value; +} + +std::string H264GetPacketizationModeOrDefault(const CodecParameterMap& params) { // If packetization-mode is not present, default to "0". // https://tools.ietf.org/html/rfc6184#section-6.2 - return "0"; + return GetFmtpParameterOrDefault(params, cricket::kH264FmtpPacketizationMode, + "0"); } bool H264IsSamePacketizationMode(const CodecParameterMap& left, @@ -45,6 +52,28 @@ bool H264IsSamePacketizationMode(const CodecParameterMap& left, H264GetPacketizationModeOrDefault(right); } +std::string AV1GetTierOrDefault(const CodecParameterMap& params) { + // If the parameter is not present, the tier MUST be inferred to be 0. + // https://aomediacodec.github.io/av1-rtp-spec/#72-sdp-parameters + return GetFmtpParameterOrDefault(params, cricket::kAv1FmtpTier, "0"); +} + +bool AV1IsSameTier(const CodecParameterMap& left, + const CodecParameterMap& right) { + return AV1GetTierOrDefault(left) == AV1GetTierOrDefault(right); +} + +std::string AV1GetLevelIdxOrDefault(const CodecParameterMap& params) { + // If the parameter is not present, it MUST be inferred to be 5 (level 3.1). + // https://aomediacodec.github.io/av1-rtp-spec/#72-sdp-parameters + return GetFmtpParameterOrDefault(params, cricket::kAv1FmtpLevelIdx, "5"); +} + +bool AV1IsSameLevelIdx(const CodecParameterMap& left, + const CodecParameterMap& right) { + return AV1GetLevelIdxOrDefault(left) == AV1GetLevelIdxOrDefault(right); +} + // Some (video) codecs are actually families of codecs and rely on parameters // to distinguish different incompatible family members. bool IsSameCodecSpecific(const SdpVideoFormat& format1, @@ -62,7 +91,9 @@ bool IsSameCodecSpecific(const SdpVideoFormat& format1, case kVideoCodecVP9: return VP9IsSameProfile(format1.parameters, format2.parameters); case kVideoCodecAV1: - return AV1IsSameProfile(format1.parameters, format2.parameters); + return AV1IsSameProfile(format1.parameters, format2.parameters) && + AV1IsSameTier(format1.parameters, format2.parameters) && + AV1IsSameLevelIdx(format1.parameters, format2.parameters); #ifdef RTC_ENABLE_H265 case kVideoCodecH265: return H265IsSameProfileTierLevel(format1.parameters, format2.parameters); @@ -71,6 +102,7 @@ bool IsSameCodecSpecific(const SdpVideoFormat& format1, return true; } } + } // namespace SdpVideoFormat::SdpVideoFormat(const std::string& name) : name(name) {} From 9d9b3a355377e899d1b3d7170d9e82e5664770db Mon Sep 17 00:00:00 2001 From: Jakob Ivarsson Date: Wed, 7 Feb 2024 09:44:31 +0100 Subject: [PATCH 086/170] Add option for the audio encoder to allocate a bitrate range. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:15834 Change-Id: I3223162e747621983dbe2704661bb87f7890b3fa Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338221 Reviewed-by: Mirko Bonadei Commit-Queue: Jakob Ivarsson‎ Reviewed-by: Tomas Lundqvist Cr-Commit-Position: refs/heads/main@{#41682} --- api/audio_codecs/BUILD.gn | 1 + api/audio_codecs/audio_encoder.h | 15 ++++++++++++--- audio/audio_send_stream.cc | 7 +++++++ audio/audio_send_stream.h | 2 ++ audio/audio_send_stream_unittest.cc | 26 ++++++++++++++++++++++++++ test/mock_audio_encoder.h | 4 ++++ 6 files changed, 52 insertions(+), 3 deletions(-) diff --git a/api/audio_codecs/BUILD.gn b/api/audio_codecs/BUILD.gn index 2719942488..fc02b2d834 100644 --- a/api/audio_codecs/BUILD.gn +++ b/api/audio_codecs/BUILD.gn @@ -42,6 +42,7 @@ rtc_library("audio_codecs_api") { "../../rtc_base:refcount", "../../rtc_base:sanitizer", "../../rtc_base/system:rtc_export", + "../units:data_rate", "../units:time_delta", ] absl_deps = [ diff --git a/api/audio_codecs/audio_encoder.h b/api/audio_codecs/audio_encoder.h index 7f5a34214f..7b5ee7a866 100644 --- a/api/audio_codecs/audio_encoder.h +++ b/api/audio_codecs/audio_encoder.h @@ -20,6 +20,7 @@ #include "absl/types/optional.h" #include "api/array_view.h" #include "api/call/bitrate_allocation.h" +#include "api/units/data_rate.h" #include "api/units/time_delta.h" #include "rtc_base/buffer.h" @@ -240,12 +241,20 @@ class AudioEncoder { // Get statistics related to audio network adaptation. virtual ANAStats GetANAStats() const; - // The range of frame lengths that are supported or nullopt if there's no sch - // information. This is used to calculated the full bitrate range, including - // overhead. + // The range of frame lengths that are supported or nullopt if there's no such + // information. This is used together with the bitrate range to calculate the + // full bitrate range, including overhead. virtual absl::optional> GetFrameLengthRange() const = 0; + // The range of payload bitrates that are supported. This is used together + // with the frame length range to calculate the full bitrate range, including + // overhead. + virtual absl::optional> GetBitrateRange() + const { + return absl::nullopt; + } + // The maximum number of audio channels supported by WebRTC encoders. static constexpr int kMaxNumberOfChannels = 24; diff --git a/audio/audio_send_stream.cc b/audio/audio_send_stream.cc index 2fdb5e63e7..59b0ea5b5e 100644 --- a/audio/audio_send_stream.cc +++ b/audio/audio_send_stream.cc @@ -333,6 +333,7 @@ void AudioSendStream::ConfigureStream( return; } frame_length_range_ = encoder->GetFrameLengthRange(); + bitrate_range_ = encoder->GetBitrateRange(); }); if (sending_) { @@ -848,6 +849,12 @@ AudioSendStream::GetMinMaxBitrateConstraints() const { if (allocation_settings_.max_bitrate) constraints.max = *allocation_settings_.max_bitrate; + // Use encoder defined bitrate range if available. + if (bitrate_range_) { + constraints.min = bitrate_range_->first; + constraints.max = bitrate_range_->second; + } + RTC_DCHECK_GE(constraints.min, DataRate::Zero()); RTC_DCHECK_GE(constraints.max, DataRate::Zero()); if (constraints.max < constraints.min) { diff --git a/audio/audio_send_stream.h b/audio/audio_send_stream.h index cf55ff6524..a37c8fd452 100644 --- a/audio/audio_send_stream.h +++ b/audio/audio_send_stream.h @@ -216,6 +216,8 @@ class AudioSendStream final : public webrtc::AudioSendStream, false; absl::optional> frame_length_range_ RTC_GUARDED_BY(worker_thread_checker_); + absl::optional> bitrate_range_ + RTC_GUARDED_BY(worker_thread_checker_); }; } // namespace internal } // namespace webrtc diff --git a/audio/audio_send_stream_unittest.cc b/audio/audio_send_stream_unittest.cc index 43f2fb14e7..60d87eb080 100644 --- a/audio/audio_send_stream_unittest.cc +++ b/audio/audio_send_stream_unittest.cc @@ -959,5 +959,31 @@ TEST(AudioSendStreamTest, OverridesPriorityBitrate) { send_stream->Stop(); } +TEST(AudioSendStreamTest, UseEncoderBitrateRange) { + ConfigHelper helper(true, true, true); + std::pair bitrate_range{DataRate::BitsPerSec(5000), + DataRate::BitsPerSec(10000)}; + EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _, _)) + .WillOnce(Invoke([&](int payload_type, const SdpAudioFormat& format, + absl::optional codec_pair_id, + std::unique_ptr* return_value) { + auto mock_encoder = SetupAudioEncoderMock(payload_type, format); + EXPECT_CALL(*mock_encoder, GetBitrateRange()) + .WillRepeatedly(Return(bitrate_range)); + *return_value = std::move(mock_encoder); + })); + auto send_stream = helper.CreateAudioSendStream(); + EXPECT_CALL(*helper.bitrate_allocator(), AddObserver(send_stream.get(), _)) + .WillOnce(Invoke( + [&](BitrateAllocatorObserver*, MediaStreamAllocationConfig config) { + EXPECT_EQ(config.min_bitrate_bps, bitrate_range.first.bps()); + EXPECT_EQ(config.max_bitrate_bps, bitrate_range.second.bps()); + })); + EXPECT_CALL(*helper.channel_send(), StartSend()); + send_stream->Start(); + EXPECT_CALL(*helper.channel_send(), StopSend()); + send_stream->Stop(); +} + } // namespace test } // namespace webrtc diff --git a/test/mock_audio_encoder.h b/test/mock_audio_encoder.h index 1f4510e885..30518e8f49 100644 --- a/test/mock_audio_encoder.h +++ b/test/mock_audio_encoder.h @@ -33,6 +33,10 @@ class MockAudioEncoder : public AudioEncoder { GetFrameLengthRange, (), (const, override)); + MOCK_METHOD((absl::optional>), + GetBitrateRange, + (), + (const, override)); MOCK_METHOD(void, Reset, (), (override)); MOCK_METHOD(bool, SetFec, (bool enable), (override)); From 3bddaed569fc0a00f25fd283d59347a4f1d73234 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Tue, 6 Feb 2024 22:54:25 +0000 Subject: [PATCH 087/170] rtc_p2p: Split turn port and basic port allocator This completes the breakup of the rtc_p2p target. Remaining cleanup is to delete the rtc_p2p target and make clients depend on the base targets. Bug: webrtc:15796 Change-Id: I67bbeee9abf0bb663283ec3420a9a00bd3a2436a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338340 Reviewed-by: Mirko Bonadei Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41683} --- api/BUILD.gn | 2 + api/test/pclf/BUILD.gn | 1 + examples/BUILD.gn | 1 + p2p/BUILD.gn | 95 ++++++++++++++++++++++++++----------- p2p/base/turn_port.cc | 1 + p2p/base/turn_port.h | 3 +- pc/BUILD.gn | 28 +++++++++-- test/network/BUILD.gn | 2 +- test/pc/e2e/BUILD.gn | 2 +- test/peer_scenario/BUILD.gn | 2 +- 10 files changed, 100 insertions(+), 37 deletions(-) diff --git a/api/BUILD.gn b/api/BUILD.gn index dce687e76b..1f03468d65 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -335,6 +335,7 @@ rtc_library("libjingle_peerconnection_api") { ":turn_customizer", "../call:rtp_interfaces", "../p2p:connection", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../pc:media_factory", "../rtc_base:copy_on_write_buffer", @@ -940,6 +941,7 @@ rtc_library("ice_transport_factory") { "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../rtc_base:threading", "../rtc_base/system:rtc_export", diff --git a/api/test/pclf/BUILD.gn b/api/test/pclf/BUILD.gn index 20d7077449..68f1688556 100644 --- a/api/test/pclf/BUILD.gn +++ b/api/test/pclf/BUILD.gn @@ -75,6 +75,7 @@ rtc_library("media_quality_test_params") { "../../../api/video_codecs:video_codecs_api", "../../../modules/audio_processing:api", "../../../p2p:connection", + "../../../p2p:port_allocator", "../../../p2p:rtc_p2p", "../../../rtc_base:network", "../../../rtc_base:rtc_certificate_generator", diff --git a/examples/BUILD.gn b/examples/BUILD.gn index d6940e2cba..941d62c962 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -703,6 +703,7 @@ if (is_linux || is_chromeos || is_win) { "../media:media_channel", "../media:rtc_media_base", "../p2p:connection", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../pc:video_track_source", "../rtc_base:async_dns_resolver", diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn index 5b7f07e361..05db81ad96 100644 --- a/p2p/BUILD.gn +++ b/p2p/BUILD.gn @@ -19,7 +19,6 @@ rtc_library("rtc_p2p") { visibility = [ "*" ] sources = [ # TODO(bugs.webrtc.org/15769): Finish cleanup and remove. - "base/active_ice_controller_factory_interface.h", # To be removed (Chrome) "base/active_ice_controller_interface.h", # To be removed (Internal) "base/basic_ice_controller.h", # To be removed (Chrome) @@ -258,13 +257,53 @@ rtc_library("basic_packet_socket_factory") { absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] } +rtc_library("basic_port_allocator") { + sources = [ + "client/basic_port_allocator.cc", + "client/basic_port_allocator.h", + ] + deps = [ + ":basic_packet_socket_factory", + ":port", + ":port_allocator", + ":relay_port_factory_interface", + ":rtc_p2p", + ":stun_port", + ":tcp_port", + ":turn_port", + ":turn_port_factory", + ":udp_port", + "../api:field_trials_view", + "../api:turn_customizer", + "../api/task_queue:pending_task_safety_flag", + "../api/transport:field_trial_based_config", + "../api/units:time_delta", + "../rtc_base:checks", + "../rtc_base:event_tracer", + "../rtc_base:logging", + "../rtc_base:macromagic", + "../rtc_base:network", + "../rtc_base:network_constants", + "../rtc_base:ssl", + "../rtc_base:stringutils", + "../rtc_base:threading", + "../rtc_base/experiments:field_trial_parser", + "../rtc_base/memory:always_valid_pointer", + "../rtc_base/network:received_packet", + "../rtc_base/system:rtc_export", + "../system_wrappers:metrics", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/algorithm:container", + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/strings:string_view", + ] +} + rtc_source_set("candidate_pair_interface") { sources = [ "base/candidate_pair_interface.h" ] } -# This set of files is too intertwined to break into separate -# targets at this point. -# TODO(bugs.webrtc.org/15796): Finish breakup rtc_library("connection") { sources = [ "base/connection.cc", @@ -857,7 +896,7 @@ rtc_library("transport_description_factory") { ] deps = [ ":ice_credentials_iterator", - ":rtc_p2p", + ":transport_description", "../api:field_trials_view", "../rtc_base:logging", "../rtc_base:ssl", @@ -869,6 +908,7 @@ rtc_source_set("transport_info") { deps = [ ":p2p_constants", ":rtc_p2p", + ":transport_description", "../api:candidate", "../rtc_base:ssl", ] @@ -879,51 +919,32 @@ rtc_source_set("udp_port") { deps = [ ":stun_port" ] } -rtc_library("basic_port_allocator_and_turn_port") { +rtc_library("turn_port") { sources = [ "base/turn_port.cc", "base/turn_port.h", - "client/basic_port_allocator.cc", - "client/basic_port_allocator.h", - "client/turn_port_factory.cc", - "client/turn_port_factory.h", ] deps = [ - ":basic_packet_socket_factory", ":connection", ":p2p_constants", ":port", ":port_allocator", ":relay_port_factory_interface", - ":stun_port", - ":tcp_port", - ":udp_port", "../api:async_dns_resolver", - "../api:field_trials_view", "../api:turn_customizer", "../api/task_queue", "../api/task_queue:pending_task_safety_flag", - "../api/transport:field_trial_based_config", "../api/transport:stun_types", - "../api/units:time_delta", "../rtc_base:async_packet_socket", "../rtc_base:byte_order", "../rtc_base:checks", - "../rtc_base:event_tracer", "../rtc_base:logging", - "../rtc_base:macromagic", "../rtc_base:net_helpers", - "../rtc_base:network", - "../rtc_base:network_constants", "../rtc_base:socket_address", "../rtc_base:ssl", "../rtc_base:stringutils", - "../rtc_base:threading", "../rtc_base/experiments:field_trial_parser", - "../rtc_base/memory:always_valid_pointer", "../rtc_base/network:received_packet", - "../rtc_base/system:rtc_export", - "../system_wrappers:metrics", ] absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", @@ -934,6 +955,21 @@ rtc_library("basic_port_allocator_and_turn_port") { ] } +rtc_library("turn_port_factory") { + sources = [ + "client/turn_port_factory.cc", + "client/turn_port_factory.h", + ] + deps = [ + ":port", + ":port_allocator", + ":relay_port_factory_interface", + ":rtc_p2p", + ":turn_port", + "../rtc_base:async_packet_socket", + ] +} + rtc_source_set("relay_port_factory_interface") { sources = [ "client/relay_port_factory_interface.h" ] deps = [ @@ -996,7 +1032,7 @@ if (rtc_include_tests) { deps = [ ":basic_packet_socket_factory", ":connection", - ":rtc_p2p", + ":port_allocator", ":udp_port", "../rtc_base:net_helpers", "../rtc_base:net_test_helpers", @@ -1037,7 +1073,6 @@ if (rtc_include_tests) { ":ice_transport_internal", ":p2p_server_utils", ":packet_transport_internal", - ":rtc_p2p", ":transport_description", "../api:dtls_transport_interface", "../api:libjingle_peerconnection_api", @@ -1096,7 +1131,7 @@ if (rtc_include_tests) { ":async_stun_tcp_socket", ":basic_ice_controller", ":basic_packet_socket_factory", - ":basic_port_allocator_and_turn_port", + ":basic_port_allocator", ":connection", ":dtls_transport", ":fake_ice_transport", @@ -1108,6 +1143,8 @@ if (rtc_include_tests) { ":p2p_test_utils", ":p2p_transport_channel", ":packet_transport_internal", + ":port", + ":port_allocator", ":port_interface", ":pseudo_tcp", ":regathering_controller", @@ -1119,6 +1156,7 @@ if (rtc_include_tests) { ":tcp_port", ":transport_description", ":transport_description_factory", + ":turn_port", ":wrapping_active_ice_controller", "../api:array_view", "../api:candidate", @@ -1254,7 +1292,6 @@ if (rtc_include_tests) { ":basic_packet_socket_factory", ":libstunprober", ":p2p_test_utils", - ":rtc_p2p", "../rtc_base:checks", "../rtc_base:gunit_helpers", "../rtc_base:ip_address", diff --git a/p2p/base/turn_port.cc b/p2p/base/turn_port.cc index 1fb3b38bfd..bc35a2250a 100644 --- a/p2p/base/turn_port.cc +++ b/p2p/base/turn_port.cc @@ -22,6 +22,7 @@ #include "absl/types/optional.h" #include "api/task_queue/pending_task_safety_flag.h" #include "api/transport/stun.h" +#include "api/turn_customizer.h" #include "p2p/base/connection.h" #include "p2p/base/p2p_constants.h" #include "rtc_base/async_packet_socket.h" diff --git a/p2p/base/turn_port.h b/p2p/base/turn_port.h index b56f862e61..099d8b258a 100644 --- a/p2p/base/turn_port.h +++ b/p2p/base/turn_port.h @@ -25,7 +25,8 @@ #include "api/task_queue/pending_task_safety_flag.h" #include "api/task_queue/task_queue_base.h" #include "p2p/base/port.h" -#include "p2p/client/basic_port_allocator.h" +#include "p2p/base/port_allocator.h" +#include "p2p/client/relay_port_factory_interface.h" #include "rtc_base/async_packet_socket.h" #include "rtc_base/network/received_packet.h" #include "rtc_base/ssl_certificate.h" diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 92eae42a46..1734ab551c 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -316,6 +316,8 @@ rtc_source_set("jsep_transport_controller") { "../p2p:p2p_constants", "../p2p:p2p_transport_channel", "../p2p:packet_transport_internal", + "../p2p:port", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../p2p:transport_description", "../p2p:transport_info", @@ -671,6 +673,7 @@ rtc_source_set("transport_stats") { "../p2p:connection", "../p2p:dtls_transport_internal", "../p2p:ice_transport_internal", + "../p2p:port", "../p2p:rtc_p2p", "../rtc_base:ssl", ] @@ -953,6 +956,7 @@ rtc_source_set("rtc_stats_collector") { "../p2p:connection_info", "../p2p:ice_transport_internal", "../p2p:p2p_constants", + "../p2p:port", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:event_tracer", @@ -1050,6 +1054,8 @@ rtc_source_set("sdp_offer_answer") { "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", + "../p2p:port", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../p2p:transport_description", "../p2p:transport_description_factory", @@ -1165,6 +1171,8 @@ rtc_source_set("peer_connection") { "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_transport_channel", + "../p2p:port", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../p2p:transport_description", "../p2p:transport_info", @@ -1263,6 +1271,7 @@ rtc_source_set("legacy_stats_collector") { "../p2p:connection_info", "../p2p:ice_transport_internal", "../p2p:p2p_constants", + "../p2p:port", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:event_tracer", @@ -1340,6 +1349,7 @@ rtc_source_set("webrtc_sdp") { "../p2p:connection", "../p2p:ice_transport_internal", "../p2p:p2p_constants", + "../p2p:port", "../p2p:port_interface", "../p2p:rtc_p2p", "../p2p:transport_description", @@ -1407,6 +1417,8 @@ rtc_library("ice_server_parsing") { "../api:libjingle_peerconnection_api", "../api:rtc_error", "../p2p:connection", + "../p2p:port", + "../p2p:port_allocator", "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", @@ -1471,9 +1483,10 @@ rtc_source_set("peer_connection_factory") { "../call:rtp_sender", "../media:rtc_media_base", "../p2p:basic_packet_socket_factory", - "../p2p:basic_port_allocator_and_turn_port", + "../p2p:basic_port_allocator", "../p2p:connection", "../p2p:default_ice_transport_factory", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../pc:audio_track", "../pc:connection_context", @@ -2197,9 +2210,10 @@ if (rtc_include_tests && !build_with_chromium) { "../media:rtc_media_tests_utils", "../modules/audio_device:audio_device_api", "../modules/audio_processing:api", - "../p2p:basic_port_allocator_and_turn_port", + "../p2p:basic_port_allocator", "../p2p:connection", "../p2p:p2p_test_utils", + "../p2p:port_allocator", "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", @@ -2254,6 +2268,7 @@ if (rtc_include_tests && !build_with_chromium) { "../p2p:connection", "../p2p:p2p_server_utils", "../p2p:p2p_test_utils", + "../p2p:port_allocator", "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:gunit_helpers", @@ -2434,7 +2449,7 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_device:audio_device_api", "../modules/audio_processing:audio_processing_statistics", "../modules/rtp_rtcp:rtp_rtcp_format", - "../p2p:basic_port_allocator_and_turn_port", + "../p2p:basic_port_allocator", "../p2p:connection", "../p2p:connection_info", "../p2p:dtls_transport_internal", @@ -2442,6 +2457,8 @@ if (rtc_include_tests && !build_with_chromium) { "../p2p:ice_transport_internal", "../p2p:p2p_constants", "../p2p:p2p_server_utils", + "../p2p:port", + "../p2p:port_allocator", "../p2p:port_interface", "../p2p:transport_description", "../p2p:transport_info", @@ -2653,7 +2670,7 @@ if (rtc_include_tests && !build_with_chromium) { "../modules/audio_processing:audio_processing_statistics", "../modules/audio_processing:audioproc_test_utils", "../modules/rtp_rtcp:rtp_rtcp_format", - "../p2p:basic_port_allocator_and_turn_port", + "../p2p:basic_port_allocator", "../p2p:connection", "../p2p:fake_ice_transport", "../p2p:fake_port_allocator", @@ -2661,6 +2678,8 @@ if (rtc_include_tests && !build_with_chromium) { "../p2p:p2p_constants", "../p2p:p2p_server_utils", "../p2p:p2p_test_utils", + "../p2p:port", + "../p2p:port_allocator", "../p2p:port_interface", "../p2p:rtc_p2p", "../rtc_base:checks", @@ -2811,6 +2830,7 @@ if (rtc_include_tests && !build_with_chromium) { "../p2p:connection", "../p2p:fake_port_allocator", "../p2p:p2p_test_utils", + "../p2p:port_allocator", "../p2p:rtc_p2p", "../rtc_base:checks", "../rtc_base:gunit_helpers", diff --git a/test/network/BUILD.gn b/test/network/BUILD.gn index 8f1e0d6f80..e9bd263ed9 100644 --- a/test/network/BUILD.gn +++ b/test/network/BUILD.gn @@ -130,7 +130,7 @@ if (rtc_include_tests && !build_with_chromium) { "../../media:rtc_audio_video", "../../modules/audio_device:test_audio_device_module", "../../p2p:basic_packet_socket_factory", - "../../p2p:basic_port_allocator_and_turn_port", + "../../p2p:basic_port_allocator", "../../p2p:rtc_p2p", "../../pc:pc_test_utils", "../../pc:peerconnection_wrapper", diff --git a/test/pc/e2e/BUILD.gn b/test/pc/e2e/BUILD.gn index eca7b1b353..22c9ee48d2 100644 --- a/test/pc/e2e/BUILD.gn +++ b/test/pc/e2e/BUILD.gn @@ -109,7 +109,7 @@ if (!build_with_chromium) { "../../../api/video_codecs:builtin_video_encoder_factory", "../../../modules/audio_device:test_audio_device_module", "../../../modules/audio_processing/aec_dump", - "../../../p2p:basic_port_allocator_and_turn_port", + "../../../p2p:basic_port_allocator", "../../../p2p:rtc_p2p", "../../../rtc_base:threading", "analyzer/video:quality_analyzing_video_encoder", diff --git a/test/peer_scenario/BUILD.gn b/test/peer_scenario/BUILD.gn index bfd9f4617b..e1d164a47d 100644 --- a/test/peer_scenario/BUILD.gn +++ b/test/peer_scenario/BUILD.gn @@ -53,7 +53,7 @@ if (rtc_include_tests) { "../../media:rtp_utils", "../../modules/audio_device:test_audio_device_module", "../../modules/rtp_rtcp:rtp_rtcp_format", - "../../p2p:basic_port_allocator_and_turn_port", + "../../p2p:basic_port_allocator", "../../p2p:rtc_p2p", "../../p2p:transport_description", "../../pc:channel", From 4eb72a0867a50392c125e2bdcfaee41eaef6617a Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Wed, 7 Feb 2024 02:01:20 -0800 Subject: [PATCH 088/170] Roll chromium_revision 5c1222c039..ed8169cbb0 (1257135:1257259) Change log: https://chromium.googlesource.com/chromium/src/+log/5c1222c039..ed8169cbb0 Full diff: https://chromium.googlesource.com/chromium/src/+/5c1222c039..ed8169cbb0 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/cdd683921b..81ad254d3c * src/build: https://chromium.googlesource.com/chromium/src/build/+log/5347b65643..afc7f0f08a * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/525498cea9..386f1b2ae9 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/faa67274bf..d0f1ef3ee0 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/a59d781695..18c651389f * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/1f441eb375..a8f0954411 * src/third_party/fuzztest/src: https://chromium.googlesource.com/external/github.com/google/fuzztest.git/+log/a6db991e3e..61d95200e7 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/71a8b59f46..ceb5eb8417 * src/tools/luci-go: git_revision:0d11be367258bfe14a13ff1afcf43a0bc6aedb45..git_revision:c7b026b3a6a1f877ce46a90c5f761b10e5149891 * src/tools/luci-go: git_revision:0d11be367258bfe14a13ff1afcf43a0bc6aedb45..git_revision:c7b026b3a6a1f877ce46a90c5f761b10e5149891 DEPS diff: https://chromium.googlesource.com/chromium/src/+/5c1222c039..ed8169cbb0/DEPS No update to Clang. BUG=None Change-Id: Idc2a965ac942878f9987efd9bbbf0421258f8d2f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338460 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41684} --- DEPS | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/DEPS b/DEPS index ce0c24d779..ebc13d622b 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '5c1222c039c4c405474143f6beb91904da6375e0', + 'chromium_revision': 'ed8169cbb00c3d73ba0f9b60da641e55d4d062f2', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,9 +50,9 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@cdd683921b46fb95b9fd9dc867b823385abf3c5e', + 'https://chromium.googlesource.com/chromium/src/base@81ad254d3cf38a2ccd5ce32a2ec9907b5a84acca', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@5347b6564336aaa53809dd92ddf7173f242ca7a8', + 'https://chromium.googlesource.com/chromium/src/build@afc7f0f08a77d1ff83c327617afd6fe2cb0b3431', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@262e0f6f649a83f5ac98f3bac6eefff66fb90133', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@525498cea9c712ecd59200a9f5752e7737d6dcfa', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@386f1b2ae92f3005617b8d7d9d6c42b3892255d0', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@faa67274bf4519d5b5cbde7b2604ad1adf3b44ad', + 'https://chromium.googlesource.com/chromium/src/testing@d0f1ef3ee07d54d407f8e17c0761fc76c50b6dfd', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@a59d781695ef8650f9cc3d16fd90e3d121497693', + 'https://chromium.googlesource.com/chromium/src/third_party@18c651389fbdc155e3271dccb908edf2ebc6f652', 'src/buildtools/linux64': { 'packages': [ @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@1f441eb375f1eb37c9b2b2e923f48cce656bb443', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@a8f095441135fc2a95b5d45c9f66b242906ddfc1', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -288,7 +288,7 @@ deps = { 'src/third_party/libFuzzer/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/compiler-rt/lib/fuzzer.git@758bd21f103a501b362b1ca46fa8fcb692eaa303', 'src/third_party/fuzztest/src': - 'https://chromium.googlesource.com/external/github.com/google/fuzztest.git@a6db991e3e487c4bf131fe8de737267e2b1ecfa4', + 'https://chromium.googlesource.com/external/github.com/google/fuzztest.git@61d95200e7ece7d121cab26f0c39fbf392e6566e', 'src/third_party/libjpeg_turbo': 'https://chromium.googlesource.com/chromium/deps/libjpeg_turbo.git@9b894306ec3b28cea46e84c32b56773a98c483da', 'src/third_party/libsrtp': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@71a8b59f465754b542f9151447144ff88f622b56', + 'https://chromium.googlesource.com/chromium/src/tools@ceb5eb8417e3c47c8392056eba19488713027198', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -509,11 +509,11 @@ deps = { 'packages': [ { 'package': 'infra/tools/luci/isolate/${{platform}}', - 'version': 'git_revision:0d11be367258bfe14a13ff1afcf43a0bc6aedb45', + 'version': 'git_revision:c7b026b3a6a1f877ce46a90c5f761b10e5149891', }, { 'package': 'infra/tools/luci/swarming/${{platform}}', - 'version': 'git_revision:0d11be367258bfe14a13ff1afcf43a0bc6aedb45', + 'version': 'git_revision:c7b026b3a6a1f877ce46a90c5f761b10e5149891', }, ], 'dep_type': 'cipd', From 2425c8ddea1ac98e07731b4a47706db5fa5dfc04 Mon Sep 17 00:00:00 2001 From: Tomas Lundqvist Date: Wed, 7 Feb 2024 09:16:36 +0000 Subject: [PATCH 089/170] Added EnableVad() and DisableVad() default implementations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:15806 Change-Id: I3870029ef788ed44b19484a2413c3b3473d3a1a5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338440 Reviewed-by: Jakob Ivarsson‎ Commit-Queue: Tomas Lundqvist Cr-Commit-Position: refs/heads/main@{#41685} --- api/neteq/neteq.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/neteq/neteq.h b/api/neteq/neteq.h index 43e0e09784..c8185bc1ce 100644 --- a/api/neteq/neteq.h +++ b/api/neteq/neteq.h @@ -280,10 +280,10 @@ class NetEq { // Enables post-decode VAD. When enabled, GetAudio() will return // kOutputVADPassive when the signal contains no speech. - virtual void EnableVad() = 0; + virtual void EnableVad() {} // Disables post-decode VAD. - virtual void DisableVad() = 0; + virtual void DisableVad() {} // Returns the RTP timestamp for the last sample delivered by GetAudio(). // The return value will be empty if no valid timestamp is available. From 22b6564d77af5aa637c0da59219bfb681cc55156 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Tue, 6 Feb 2024 21:31:44 +0100 Subject: [PATCH 090/170] Propagate webrtc::Environment to create VideoDecoder through java wrappers Bug: webrtc:15791 Change-Id: I25976158ef780211355deb934e83d275d4f881e2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336980 Reviewed-by: Sergey Silkin Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41686} --- sdk/android/BUILD.gn | 7 +++++- .../webrtc/SoftwareVideoDecoderFactory.java | 17 +++++++++---- sdk/android/api/org/webrtc/VideoDecoder.java | 10 ++++++-- .../api/org/webrtc/VideoDecoderFallback.java | 8 ++++++ .../org/webrtc/WrappedNativeVideoDecoder.java | 4 ++- .../src/jni/software_video_decoder_factory.cc | 25 +++++++++++++++++++ .../src/jni/video_decoder_factory_wrapper.cc | 6 +++-- .../src/jni/video_decoder_factory_wrapper.h | 5 ++-- sdk/android/src/jni/video_decoder_fallback.cc | 18 +++++++++++++ sdk/android/src/jni/video_decoder_wrapper.cc | 15 +++++++++++ sdk/android/src/jni/video_decoder_wrapper.h | 7 ++++++ 11 files changed, 109 insertions(+), 13 deletions(-) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 5296e54076..13c27c0a44 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -663,6 +663,7 @@ if (current_os == "linux" || is_android) { "../../api:libjingle_peerconnection_api", "../../api:media_stream_interface", "../../api:sequence_checker", + "../../api/environment", "../../api/task_queue", "../../api/video:encoded_image", "../../api/video:render_resolution", @@ -689,7 +690,10 @@ if (current_os == "linux" || is_android) { "../../rtc_base/synchronization:mutex", "//third_party/libyuv", ] - absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] + absl_deps = [ + "//third_party/abseil-cpp/absl/memory", + "//third_party/abseil-cpp/absl/types:optional", + ] } # Sources here require -lEGL linker flag. It is separated from video_jni @@ -908,6 +912,7 @@ if (current_os == "linux" || is_android) { ":libvpx_vp9_jni", ":native_api_jni", ":video_jni", + "../../api/environment", "../../api/video_codecs:builtin_video_decoder_factory", "../../api/video_codecs:builtin_video_encoder_factory", "../../api/video_codecs:video_codecs_api", diff --git a/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java b/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java index 2ac42e834e..ac815d395b 100644 --- a/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java +++ b/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java @@ -11,7 +11,6 @@ package org.webrtc; import androidx.annotation.Nullable; -import java.util.Arrays; import java.util.List; public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { @@ -26,16 +25,19 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { @Nullable @Override public VideoDecoder createDecoder(VideoCodecInfo info) { - long nativeDecoder = nativeCreateDecoder(nativeFactory, info); - if (nativeDecoder == 0) { + if (!nativeIsSupported(nativeFactory, info)) { Logging.w(TAG, "Trying to create decoder for unsupported format. " + info); return null; } - return new WrappedNativeVideoDecoder() { @Override public long createNativeVideoDecoder() { - return nativeDecoder; + return nativeCreateDecoder(nativeFactory, info); + } + + @Override + public long createNative(long webrtcEnvRef) { + return nativeCreate(nativeFactory, webrtcEnvRef, info); } }; } @@ -49,5 +51,10 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { private static native long nativeCreateDecoder(long factory, VideoCodecInfo videoCodecInfo); + private static native boolean nativeIsSupported(long factory, VideoCodecInfo info); + + private static native long nativeCreate( + long factory, long webrtcEnvRef, VideoCodecInfo info); + private static native List nativeGetSupportedCodecs(long factory); } diff --git a/sdk/android/api/org/webrtc/VideoDecoder.java b/sdk/android/api/org/webrtc/VideoDecoder.java index a80fa4fef2..f44672da08 100644 --- a/sdk/android/api/org/webrtc/VideoDecoder.java +++ b/sdk/android/api/org/webrtc/VideoDecoder.java @@ -56,11 +56,11 @@ public interface VideoDecoder { * decoder (e.g., an Android platform decoder), or alternatively 2) a native * decoder (e.g., a software decoder or a C++ decoder adapter). * - * For case 1), createNativeVideoDecoder() should return zero. + * For case 1), createNative() should return zero. * In this case, we expect the native library to call the decoder through * JNI using the Java interface declared below. * - * For case 2), createNativeVideoDecoder() should return a non-zero value. + * For case 2), createNative() should return a non-zero value. * In this case, we expect the native library to treat the returned value as * a raw pointer of type webrtc::VideoDecoder* (ownership is transferred to * the caller). The native library should then directly call the @@ -69,6 +69,12 @@ public interface VideoDecoder { * UnsupportedOperationException. */ @CalledByNative + default long createNative(long webrtcEnvRef) { + return createNativeVideoDecoder(); + } + + @CalledByNative + @Deprecated default long createNativeVideoDecoder() { return 0; } diff --git a/sdk/android/api/org/webrtc/VideoDecoderFallback.java b/sdk/android/api/org/webrtc/VideoDecoderFallback.java index ddfa3ecd40..dc2e2eeabe 100644 --- a/sdk/android/api/org/webrtc/VideoDecoderFallback.java +++ b/sdk/android/api/org/webrtc/VideoDecoderFallback.java @@ -27,5 +27,13 @@ public class VideoDecoderFallback extends WrappedNativeVideoDecoder { return nativeCreateDecoder(fallback, primary); } + @Override + public long createNative(long webrtcEnvRef) { + return nativeCreate(webrtcEnvRef, fallback, primary); + } + private static native long nativeCreateDecoder(VideoDecoder fallback, VideoDecoder primary); + + private static native long nativeCreate( + long webrtcEnvRef, VideoDecoder fallback, VideoDecoder primary); } diff --git a/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java b/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java index 027120e48e..ac9886e6a3 100644 --- a/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java +++ b/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java @@ -14,7 +14,9 @@ package org.webrtc; * Wraps a native webrtc::VideoDecoder. */ public abstract class WrappedNativeVideoDecoder implements VideoDecoder { - @Override public abstract long createNativeVideoDecoder(); + // TODO: bugs.webrtc.org/15791 - uncomment when implemented by all + // derived classes instead of the createNativeVideoDecoder + // @Override public abstract long createNative(long webrtcEnvRef); @Override public final VideoCodecStatus initDecode(Settings settings, Callback decodeCallback) { diff --git a/sdk/android/src/jni/software_video_decoder_factory.cc b/sdk/android/src/jni/software_video_decoder_factory.cc index 151bf5f205..46b67b88eb 100644 --- a/sdk/android/src/jni/software_video_decoder_factory.cc +++ b/sdk/android/src/jni/software_video_decoder_factory.cc @@ -8,8 +8,12 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include + +#include "api/environment/environment.h" #include "api/video_codecs/builtin_video_decoder_factory.h" #include "api/video_codecs/video_decoder.h" +#include "api/video_codecs/video_decoder_factory.h" #include "sdk/android/generated_swcodecs_jni/SoftwareVideoDecoderFactory_jni.h" #include "sdk/android/native_api/jni/java_types.h" #include "sdk/android/src/jni/jni_helpers.h" @@ -39,6 +43,27 @@ static jlong JNI_SoftwareVideoDecoderFactory_CreateDecoder( return webrtc::NativeToJavaPointer(decoder.release()); } +jboolean JNI_SoftwareVideoDecoderFactory_IsSupported( + JNIEnv* env, + jlong j_factory, + const JavaParamRef& j_info) { + return VideoCodecInfoToSdpVideoFormat(env, j_info) + .IsCodecInList(reinterpret_cast(j_factory) + ->GetSupportedFormats()); +} + +jlong JNI_SoftwareVideoDecoderFactory_Create( + JNIEnv* env, + jlong j_factory, + jlong j_webrtc_env_ref, + const JavaParamRef& j_info) { + return NativeToJavaPointer( + reinterpret_cast(j_factory) + ->Create(*reinterpret_cast(j_webrtc_env_ref), + VideoCodecInfoToSdpVideoFormat(env, j_info)) + .release()); +} + static webrtc::ScopedJavaLocalRef JNI_SoftwareVideoDecoderFactory_GetSupportedCodecs(JNIEnv* env, jlong j_factory) { diff --git a/sdk/android/src/jni/video_decoder_factory_wrapper.cc b/sdk/android/src/jni/video_decoder_factory_wrapper.cc index 2d9240493a..1f6f4a0b8d 100644 --- a/sdk/android/src/jni/video_decoder_factory_wrapper.cc +++ b/sdk/android/src/jni/video_decoder_factory_wrapper.cc @@ -10,6 +10,7 @@ #include "sdk/android/src/jni/video_decoder_factory_wrapper.h" +#include "api/environment/environment.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "rtc_base/logging.h" @@ -27,7 +28,8 @@ VideoDecoderFactoryWrapper::VideoDecoderFactoryWrapper( : decoder_factory_(jni, decoder_factory) {} VideoDecoderFactoryWrapper::~VideoDecoderFactoryWrapper() = default; -std::unique_ptr VideoDecoderFactoryWrapper::CreateVideoDecoder( +std::unique_ptr VideoDecoderFactoryWrapper::Create( + const Environment& env, const SdpVideoFormat& format) { JNIEnv* jni = AttachCurrentThreadIfNeeded(); ScopedJavaLocalRef j_codec_info = @@ -36,7 +38,7 @@ std::unique_ptr VideoDecoderFactoryWrapper::CreateVideoDecoder( jni, decoder_factory_, j_codec_info); if (!decoder.obj()) return nullptr; - return JavaToNativeVideoDecoder(jni, decoder); + return JavaToNativeVideoDecoder(jni, decoder, NativeToJavaPointer(&env)); } std::vector VideoDecoderFactoryWrapper::GetSupportedFormats() diff --git a/sdk/android/src/jni/video_decoder_factory_wrapper.h b/sdk/android/src/jni/video_decoder_factory_wrapper.h index 2122fdc008..689e829128 100644 --- a/sdk/android/src/jni/video_decoder_factory_wrapper.h +++ b/sdk/android/src/jni/video_decoder_factory_wrapper.h @@ -13,6 +13,7 @@ #include +#include "api/environment/environment.h" #include "api/video_codecs/video_decoder_factory.h" #include "sdk/android/src/jni/jni_helpers.h" @@ -28,8 +29,8 @@ class VideoDecoderFactoryWrapper : public VideoDecoderFactory { ~VideoDecoderFactoryWrapper() override; std::vector GetSupportedFormats() const override; - std::unique_ptr CreateVideoDecoder( - const SdpVideoFormat& format) override; + std::unique_ptr Create(const Environment& env, + const SdpVideoFormat& format) override; private: const ScopedJavaGlobalRef decoder_factory_; diff --git a/sdk/android/src/jni/video_decoder_fallback.cc b/sdk/android/src/jni/video_decoder_fallback.cc index a678280f69..8b521c8f2f 100644 --- a/sdk/android/src/jni/video_decoder_fallback.cc +++ b/sdk/android/src/jni/video_decoder_fallback.cc @@ -35,5 +35,23 @@ static jlong JNI_VideoDecoderFallback_CreateDecoder( return jlongFromPointer(nativeWrapper); } +static jlong JNI_VideoDecoderFallback_Create( + JNIEnv* jni, + jlong j_webrtc_env_ref, + const JavaParamRef& j_fallback_decoder, + const JavaParamRef& j_primary_decoder) { + std::unique_ptr fallback_decoder = + JavaToNativeVideoDecoder(jni, j_fallback_decoder, j_webrtc_env_ref); + std::unique_ptr primary_decoder = + JavaToNativeVideoDecoder(jni, j_primary_decoder, j_webrtc_env_ref); + + VideoDecoder* native_wrapper = + CreateVideoDecoderSoftwareFallbackWrapper(std::move(fallback_decoder), + std::move(primary_decoder)) + .release(); + + return NativeToJavaPointer(native_wrapper); +} + } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/video_decoder_wrapper.cc b/sdk/android/src/jni/video_decoder_wrapper.cc index e083df5ae8..c96961879c 100644 --- a/sdk/android/src/jni/video_decoder_wrapper.cc +++ b/sdk/android/src/jni/video_decoder_wrapper.cc @@ -10,6 +10,8 @@ #include "sdk/android/src/jni/video_decoder_wrapper.h" +#include "absl/memory/memory.h" +#include "api/environment/environment.h" #include "api/video/render_resolution.h" #include "api/video/video_frame.h" #include "api/video_codecs/video_decoder.h" @@ -281,5 +283,18 @@ std::unique_ptr JavaToNativeVideoDecoder( return std::unique_ptr(decoder); } +std::unique_ptr JavaToNativeVideoDecoder( + JNIEnv* jni, + const JavaRef& j_decoder, + jlong webrtcEnvRef) { + if (jlong native_decoder = + Java_VideoDecoder_createNative(jni, j_decoder, webrtcEnvRef); + native_decoder != 0) { + return absl::WrapUnique(reinterpret_cast(native_decoder)); + } else { + return std::make_unique(jni, j_decoder); + } +} + } // namespace jni } // namespace webrtc diff --git a/sdk/android/src/jni/video_decoder_wrapper.h b/sdk/android/src/jni/video_decoder_wrapper.h index 53246f380e..80638a7b61 100644 --- a/sdk/android/src/jni/video_decoder_wrapper.h +++ b/sdk/android/src/jni/video_decoder_wrapper.h @@ -116,10 +116,17 @@ class VideoDecoderWrapper : public VideoDecoder { /* If the j_decoder is a wrapped native decoder, unwrap it. If it is not, * wrap it in a VideoDecoderWrapper. */ +// TODO: bugs.webrtc.org/15791 - delete variant without the webrtcEnvRef +// parameter when unused. std::unique_ptr JavaToNativeVideoDecoder( JNIEnv* jni, const JavaRef& j_decoder); +std::unique_ptr JavaToNativeVideoDecoder( + JNIEnv* jni, + const JavaRef& j_decoder, + jlong webrtcEnvRef); + } // namespace jni } // namespace webrtc From 39ac25d6ecc9bd035bb5191d46186915cd1bf445 Mon Sep 17 00:00:00 2001 From: Per K Date: Wed, 7 Feb 2024 14:16:20 +0100 Subject: [PATCH 091/170] Add PeerConnectionInterface::ReconfigureBandwidthEstimation Using the Api, BWE components are recreated and new settings can be applied. Initially, the only configuration available is allowing BWE probes without media". Note that BWE components are created when transport first becomes writable. So calling this method before a PeerConnection is connected is cheap and only changes configuration. Integration test in https://webrtc-review.googlesource.com/c/src/+/337322 Bug: webrtc:14928 Change-Id: If2c848489bf94a1f7a5ebf90d2886d90c202c7c3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336240 Reviewed-by: Harald Alvestrand Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/main@{#41687} --- api/BUILD.gn | 1 + api/peer_connection_interface.h | 8 +++ api/test/mock_peerconnectioninterface.h | 4 ++ api/transport/BUILD.gn | 6 +++ api/transport/bandwidth_estimation_settings.h | 27 ++++++++++ call/BUILD.gn | 1 + call/rtp_transport_config.h | 4 -- call/rtp_transport_controller_send.cc | 50 ++++++++++++++----- call/rtp_transport_controller_send.h | 5 +- .../rtp_transport_controller_send_interface.h | 4 ++ .../test/mock_rtp_transport_controller_send.h | 4 ++ pc/BUILD.gn | 1 + pc/peer_connection.cc | 9 ++++ pc/peer_connection.h | 2 + pc/peer_connection_proxy.h | 4 ++ pc/test/fake_peer_connection_base.h | 3 ++ pc/test/mock_peer_connection_internal.h | 4 ++ 17 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 api/transport/bandwidth_estimation_settings.h diff --git a/api/BUILD.gn b/api/BUILD.gn index 1f03468d65..61c000d3f0 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -355,6 +355,7 @@ rtc_library("libjingle_peerconnection_api") { "neteq:neteq_api", "rtc_event_log", "task_queue", + "transport:bandwidth_estimation_settings", "transport:bitrate_settings", "transport:enums", "transport:network_control", diff --git a/api/peer_connection_interface.h b/api/peer_connection_interface.h index 7699f33438..38699ec98a 100644 --- a/api/peer_connection_interface.h +++ b/api/peer_connection_interface.h @@ -112,6 +112,7 @@ #include "api/set_remote_description_observer_interface.h" #include "api/stats/rtc_stats_collector_callback.h" #include "api/task_queue/task_queue_factory.h" +#include "api/transport/bandwidth_estimation_settings.h" #include "api/transport/bitrate_settings.h" #include "api/transport/enums.h" #include "api/transport/network_control.h" @@ -1133,6 +1134,13 @@ class RTC_EXPORT PeerConnectionInterface : public webrtc::RefCountInterface { // to the provided value. virtual RTCError SetBitrate(const BitrateSettings& bitrate) = 0; + // Allows an application to reconfigure bandwidth estimation. + // The method can be called both before and after estimation has started. + // Estimation starts when the first RTP packet is sent. + // Estimation will be restarted if already started. + virtual void ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) {} + // Enable/disable playout of received audio streams. Enabled by default. Note // that even if playout is enabled, streams will only be played out if the // appropriate SDP is also applied. Setting `playout` to false will stop diff --git a/api/test/mock_peerconnectioninterface.h b/api/test/mock_peerconnectioninterface.h index ccc6ce46b1..22a77d7dfe 100644 --- a/api/test/mock_peerconnectioninterface.h +++ b/api/test/mock_peerconnectioninterface.h @@ -177,6 +177,10 @@ class MockPeerConnectionInterface : public webrtc::PeerConnectionInterface { (const std::vector&), (override)); MOCK_METHOD(RTCError, SetBitrate, (const BitrateSettings&), (override)); + MOCK_METHOD(void, + ReconfigureBandwidthEstimation, + (const BandwidthEstimationSettings&), + (override)); MOCK_METHOD(void, SetAudioPlayout, (bool), (override)); MOCK_METHOD(void, SetAudioRecording, (bool), (override)); MOCK_METHOD(rtc::scoped_refptr, diff --git a/api/transport/BUILD.gn b/api/transport/BUILD.gn index 84a0968ee9..f7a27c5899 100644 --- a/api/transport/BUILD.gn +++ b/api/transport/BUILD.gn @@ -18,6 +18,12 @@ rtc_library("bitrate_settings") { absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } +rtc_library("bandwidth_estimation_settings") { + visibility = [ "*" ] + sources = [ "bandwidth_estimation_settings.h" ] + deps = [ "../../rtc_base/system:rtc_export" ] +} + rtc_source_set("enums") { visibility = [ "*" ] sources = [ "enums.h" ] diff --git a/api/transport/bandwidth_estimation_settings.h b/api/transport/bandwidth_estimation_settings.h new file mode 100644 index 0000000000..7ae8cc9ef8 --- /dev/null +++ b/api/transport/bandwidth_estimation_settings.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 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_TRANSPORT_BANDWIDTH_ESTIMATION_SETTINGS_H_ +#define API_TRANSPORT_BANDWIDTH_ESTIMATION_SETTINGS_H_ + +#include "rtc_base/system/rtc_export.h" +namespace webrtc { +// Configuration settings affecting bandwidth estimation. +// These settings can be set and changed by an application. +struct RTC_EXPORT BandwidthEstimationSettings { + // A bandwith estimation probe may be sent using a RtpTransceiver with + // direction SendOnly or SendRecv that supports RTX. The probe can be sent + // without first sending media packets in which case Rtp padding packets are + // used. + bool allow_probe_without_media = false; +}; + +} // namespace webrtc +#endif // API_TRANSPORT_BANDWIDTH_ESTIMATION_SETTINGS_H_ diff --git a/call/BUILD.gn b/call/BUILD.gn index 8af3eac754..613b2b94d2 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -117,6 +117,7 @@ rtc_library("rtp_interfaces") { "../api/crypto:options", "../api/environment", "../api/rtc_event_log", + "../api/transport:bandwidth_estimation_settings", "../api/transport:bitrate_settings", "../api/transport:network_control", "../api/units:time_delta", diff --git a/call/rtp_transport_config.h b/call/rtp_transport_config.h index 412ff78e08..cce5214fc8 100644 --- a/call/rtp_transport_config.h +++ b/call/rtp_transport_config.h @@ -38,10 +38,6 @@ struct RtpTransportConfig { // The burst interval of the pacer, see TaskQueuePacedSender constructor. absl::optional pacer_burst_interval; - - // A bandwith estimation probe may be sent on a writable Rtp stream that have - // RTX configured. It can be sent without first sending media packets. - bool allow_bandwidth_estimation_probe_without_media = false; }; } // namespace webrtc diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc index d439a2f898..32c4addfb9 100644 --- a/call/rtp_transport_controller_send.cc +++ b/call/rtp_transport_controller_send.cc @@ -70,8 +70,6 @@ bool IsRelayed(const rtc::NetworkRoute& route) { RtpTransportControllerSend::RtpTransportControllerSend( const RtpTransportConfig& config) : env_(config.env), - allow_bandwidth_estimation_probe_without_media_( - config.allow_bandwidth_estimation_probe_without_media), task_queue_(TaskQueueBase::Current()), bitrate_configurator_(config.bitrate_config), pacer_started_(false), @@ -168,7 +166,7 @@ void RtpTransportControllerSend::RegisterSendingRtpStream( packet_router_.AddSendRtpModule(&rtp_module, /*remb_candidate=*/true); pacer_.SetAllowProbeWithoutMediaPacket( - allow_bandwidth_estimation_probe_without_media_ && + bwe_settings_.allow_probe_without_media && packet_router_.SupportsRtxPayloadPadding()); } @@ -188,7 +186,7 @@ void RtpTransportControllerSend::DeRegisterSendingRtpStream( pacer_.RemovePacketsForSsrc(*rtp_module.FlexfecSsrc()); } pacer_.SetAllowProbeWithoutMediaPacket( - allow_bandwidth_estimation_probe_without_media_ && + bwe_settings_.allow_probe_without_media && packet_router_.SupportsRtxPayloadPadding()); } @@ -257,6 +255,29 @@ RtpTransportControllerSend::GetStreamFeedbackProvider() { return &feedback_demuxer_; } +void RtpTransportControllerSend::ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) { + RTC_DCHECK_RUN_ON(&sequence_checker_); + bwe_settings_ = settings; + + if (controller_) { + // Recreate the controller and handler. + control_handler_ = nullptr; + controller_ = nullptr; + // The BWE controller is created when/if the network is available. + MaybeCreateControllers(); + if (controller_) { + BitrateConstraints constraints = bitrate_configurator_.GetConfig(); + UpdateBitrateConstraints(constraints); + UpdateStreamsConfig(); + UpdateNetworkAvailability(); + } + } + pacer_.SetAllowProbeWithoutMediaPacket( + bwe_settings_.allow_probe_without_media && + packet_router_.SupportsRtxPayloadPadding()); +} + void RtpTransportControllerSend::RegisterTargetTransferRateObserver( TargetTransferRateObserver* observer) { RTC_DCHECK_RUN_ON(&sequence_checker_); @@ -358,9 +379,6 @@ void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) { RTC_DCHECK_RUN_ON(&sequence_checker_); RTC_LOG(LS_VERBOSE) << "SignalNetworkState " << (network_available ? "Up" : "Down"); - NetworkAvailability msg; - msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds()); - msg.network_available = network_available; network_available_ = network_available; if (network_available) { pacer_.Resume(); @@ -373,11 +391,7 @@ void RtpTransportControllerSend::OnNetworkAvailability(bool network_available) { if (!controller_) { MaybeCreateControllers(); } - if (controller_) { - control_handler_->SetNetworkAvailability(network_available); - PostUpdates(controller_->OnNetworkAvailability(msg)); - UpdateControlState(); - } + UpdateNetworkAvailability(); for (auto& rtp_sender : video_rtp_senders_) { rtp_sender->OnNetworkAvailability(network_available); } @@ -620,6 +634,18 @@ void RtpTransportControllerSend::MaybeCreateControllers() { StartProcessPeriodicTasks(); } +void RtpTransportControllerSend::UpdateNetworkAvailability() { + if (!controller_) { + return; + } + NetworkAvailability msg; + msg.at_time = Timestamp::Millis(env_.clock().TimeInMilliseconds()); + msg.network_available = network_available_; + control_handler_->SetNetworkAvailability(network_available_); + PostUpdates(controller_->OnNetworkAvailability(msg)); + UpdateControlState(); +} + void RtpTransportControllerSend::UpdateInitialConstraints( TargetRateConstraints new_contraints) { if (!new_contraints.starting_rate) diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h index 3c84beb65f..4428336672 100644 --- a/call/rtp_transport_controller_send.h +++ b/call/rtp_transport_controller_send.h @@ -84,6 +84,8 @@ class RtpTransportControllerSend final RtpPacketSender* packet_sender() override; void SetAllocatedSendBitrateLimits(BitrateAllocationLimits limits) override; + void ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) override; void SetPacingFactor(float pacing_factor) override; void SetQueueTimeLimit(int limit_ms) override; @@ -127,6 +129,7 @@ class RtpTransportControllerSend final private: void MaybeCreateControllers() RTC_RUN_ON(sequence_checker_); + void UpdateNetworkAvailability() RTC_RUN_ON(sequence_checker_); void UpdateInitialConstraints(TargetRateConstraints new_contraints) RTC_RUN_ON(sequence_checker_); @@ -150,7 +153,6 @@ class RtpTransportControllerSend final const Environment env_; SequenceChecker sequence_checker_; - const bool allow_bandwidth_estimation_probe_without_media_; TaskQueueBase* task_queue_; PacketRouter packet_router_; std::vector> video_rtp_senders_ @@ -158,6 +160,7 @@ class RtpTransportControllerSend final RtpBitrateConfigurator bitrate_configurator_; std::map network_routes_ RTC_GUARDED_BY(sequence_checker_); + BandwidthEstimationSettings bwe_settings_ RTC_GUARDED_BY(sequence_checker_); bool pacer_started_ RTC_GUARDED_BY(sequence_checker_); TaskQueuePacedSender pacer_; diff --git a/call/rtp_transport_controller_send_interface.h b/call/rtp_transport_controller_send_interface.h index 1938d86c57..c4b1536bad 100644 --- a/call/rtp_transport_controller_send_interface.h +++ b/call/rtp_transport_controller_send_interface.h @@ -24,6 +24,7 @@ #include "api/fec_controller.h" #include "api/frame_transformer_interface.h" #include "api/rtc_event_log/rtc_event_log.h" +#include "api/transport/bandwidth_estimation_settings.h" #include "api/transport/bitrate_settings.h" #include "api/units/timestamp.h" #include "call/rtp_config.h" @@ -125,6 +126,9 @@ class RtpTransportControllerSendInterface { virtual void SetAllocatedSendBitrateLimits( BitrateAllocationLimits limits) = 0; + virtual void ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) = 0; + virtual void SetPacingFactor(float pacing_factor) = 0; virtual void SetQueueTimeLimit(int limit_ms) = 0; diff --git a/call/test/mock_rtp_transport_controller_send.h b/call/test/mock_rtp_transport_controller_send.h index 2a0bc233ff..63f686eb3c 100644 --- a/call/test/mock_rtp_transport_controller_send.h +++ b/call/test/mock_rtp_transport_controller_send.h @@ -69,6 +69,10 @@ class MockRtpTransportControllerSend SetAllocatedSendBitrateLimits, (BitrateAllocationLimits), (override)); + MOCK_METHOD(void, + ReconfigureBandwidthEstimation, + (const BandwidthEstimationSettings&), + (override)); MOCK_METHOD(void, SetPacingFactor, (float), (override)); MOCK_METHOD(void, SetQueueTimeLimit, (int), (override)); MOCK_METHOD(StreamFeedbackProvider*, diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 1734ab551c..14971b8af1 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -426,6 +426,7 @@ rtc_source_set("peer_connection_proxy") { deps = [ ":proxy", "../api:libjingle_peerconnection_api", + "../api/transport:bandwidth_estimation_settings", ] } diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 3ab2c52130..e90d1e83f9 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -1681,6 +1681,15 @@ RTCError PeerConnection::SetBitrate(const BitrateSettings& bitrate) { return RTCError::OK(); } +void PeerConnection::ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) { + worker_thread()->PostTask(SafeTask(worker_thread_safety_, [this, settings]() { + RTC_DCHECK_RUN_ON(worker_thread()); + call_->GetTransportControllerSend()->ReconfigureBandwidthEstimation( + settings); + })); +} + void PeerConnection::SetAudioPlayout(bool playout) { if (!worker_thread()->IsCurrent()) { worker_thread()->BlockingCall( diff --git a/pc/peer_connection.h b/pc/peer_connection.h index 406bc1cef2..3c923139dc 100644 --- a/pc/peer_connection.h +++ b/pc/peer_connection.h @@ -236,6 +236,8 @@ class PeerConnection : public PeerConnectionInternal, const std::vector& candidates) override; RTCError SetBitrate(const BitrateSettings& bitrate) override; + void ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) override; void SetAudioPlayout(bool playout) override; void SetAudioRecording(bool recording) override; diff --git a/pc/peer_connection_proxy.h b/pc/peer_connection_proxy.h index 6db27f2dd5..aaccfe45d0 100644 --- a/pc/peer_connection_proxy.h +++ b/pc/peer_connection_proxy.h @@ -16,6 +16,7 @@ #include #include "api/peer_connection_interface.h" +#include "api/transport/bandwidth_estimation_settings.h" #include "pc/proxy.h" namespace webrtc { @@ -137,6 +138,9 @@ PROXY_METHOD2(void, std::function) PROXY_METHOD1(bool, RemoveIceCandidates, const std::vector&) PROXY_METHOD1(RTCError, SetBitrate, const BitrateSettings&) +PROXY_METHOD1(void, + ReconfigureBandwidthEstimation, + const BandwidthEstimationSettings&) PROXY_METHOD1(void, SetAudioPlayout, bool) PROXY_METHOD1(void, SetAudioRecording, bool) // This method will be invoked on the network thread. See diff --git a/pc/test/fake_peer_connection_base.h b/pc/test/fake_peer_connection_base.h index 1615088e99..9e4ed6d175 100644 --- a/pc/test/fake_peer_connection_base.h +++ b/pc/test/fake_peer_connection_base.h @@ -197,6 +197,9 @@ class FakePeerConnectionBase : public PeerConnectionInternal { return RTCError(RTCErrorType::UNSUPPORTED_OPERATION, "Not implemented"); } + void ReconfigureBandwidthEstimation( + const BandwidthEstimationSettings& settings) override {} + void SetAudioPlayout(bool playout) override {} void SetAudioRecording(bool recording) override {} diff --git a/pc/test/mock_peer_connection_internal.h b/pc/test/mock_peer_connection_internal.h index 5fd7a50b4f..b5f47cc46a 100644 --- a/pc/test/mock_peer_connection_internal.h +++ b/pc/test/mock_peer_connection_internal.h @@ -170,6 +170,10 @@ class MockPeerConnectionInternal : public PeerConnectionInternal { (const std::vector&), (override)); MOCK_METHOD(RTCError, SetBitrate, (const BitrateSettings&), (override)); + MOCK_METHOD(void, + ReconfigureBandwidthEstimation, + (const BandwidthEstimationSettings&), + (override)); MOCK_METHOD(void, SetAudioPlayout, (bool), (override)); MOCK_METHOD(void, SetAudioRecording, (bool), (override)); MOCK_METHOD(rtc::scoped_refptr, From aaa123debbd106669fc849425b92607edbd5d26f Mon Sep 17 00:00:00 2001 From: Tomas Lundqvist Date: Wed, 7 Feb 2024 15:17:39 +0000 Subject: [PATCH 092/170] Reland "Remove post-decode VAD" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a reland of commit 89cf26f1e0532130745f648cf16b1fb8af2f6b4f Original change's description: > Remove post-decode VAD > > Bug: webrtc:15806 > Change-Id: I6acf8734a70703085cfc1ccf82a79ee0931f59a4 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336460 > Reviewed-by: Sam Zackrisson > Commit-Queue: Tomas Lundqvist > Reviewed-by: Jakob Ivarsson‎ > Cr-Commit-Position: refs/heads/main@{#41653} Bug: webrtc:15806 Change-Id: I1c2c0ce568c3c1817ff5c65bee91b9f961d46559 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337442 Reviewed-by: Jakob Ivarsson‎ Commit-Queue: Tomas Lundqvist Reviewed-by: Sam Zackrisson Cr-Commit-Position: refs/heads/main@{#41688} --- api/neteq/neteq.cc | 3 +- api/neteq/neteq.h | 31 +++---- modules/audio_coding/BUILD.gn | 3 - modules/audio_coding/acm2/acm_receiver.cc | 6 +- .../acm2/acm_receiver_unittest.cc | 59 ------------ .../audio_coding/neteq/background_noise.cc | 29 +++--- modules/audio_coding/neteq/background_noise.h | 4 +- modules/audio_coding/neteq/neteq_impl.cc | 71 ++------------- modules/audio_coding/neteq/neteq_impl.h | 11 --- modules/audio_coding/neteq/post_decode_vad.cc | 90 ------------------- modules/audio_coding/neteq/post_decode_vad.h | 71 --------------- .../neteq/post_decode_vad_unittest.cc | 25 ------ test/fuzzers/neteq_signal_fuzzer.cc | 1 - 13 files changed, 34 insertions(+), 370 deletions(-) delete mode 100644 modules/audio_coding/neteq/post_decode_vad.cc delete mode 100644 modules/audio_coding/neteq/post_decode_vad.h delete mode 100644 modules/audio_coding/neteq/post_decode_vad_unittest.cc diff --git a/api/neteq/neteq.cc b/api/neteq/neteq.cc index 155ddf2cf3..d237def23a 100644 --- a/api/neteq/neteq.cc +++ b/api/neteq/neteq.cc @@ -24,8 +24,7 @@ NetEq::Config& NetEq::Config::operator=(Config&&) = default; std::string NetEq::Config::ToString() const { char buf[1024]; rtc::SimpleStringBuilder ss(buf); - ss << "sample_rate_hz=" << sample_rate_hz << ", enable_post_decode_vad=" - << (enable_post_decode_vad ? "true" : "false") + ss << "sample_rate_hz=" << sample_rate_hz << ", max_packets_in_buffer=" << max_packets_in_buffer << ", min_delay_ms=" << min_delay_ms << ", enable_fast_accelerate=" << (enable_fast_accelerate ? "true" : "false") diff --git a/api/neteq/neteq.h b/api/neteq/neteq.h index c8185bc1ce..3dfe662741 100644 --- a/api/neteq/neteq.h +++ b/api/neteq/neteq.h @@ -130,7 +130,6 @@ class NetEq { std::string ToString() const; int sample_rate_hz = 48000; // Initial value. Will change with input data. - bool enable_post_decode_vad = false; size_t max_packets_in_buffer = 200; int max_delay_ms = 0; int min_delay_ms = 0; @@ -197,18 +196,17 @@ class NetEq { // Instructs NetEq to deliver 10 ms of audio data. The data is written to // `audio_frame`. All data in `audio_frame` is wiped; `data_`, `speech_type_`, - // `num_channels_`, `sample_rate_hz_`, `samples_per_channel_`, and - // `vad_activity_` are updated upon success. If an error is returned, some - // fields may not have been updated, or may contain inconsistent values. - // If muted state is enabled (through Config::enable_muted_state), `muted` - // may be set to true after a prolonged expand period. When this happens, the - // `data_` in `audio_frame` is not written, but should be interpreted as being - // all zeros. For testing purposes, an override can be supplied in the - // `action_override` argument, which will cause NetEq to take this action - // next, instead of the action it would normally choose. An optional output - // argument for fetching the current sample rate can be provided, which - // will return the same value as last_output_sample_rate_hz() but will avoid - // additional synchronization. + // `num_channels_`, `sample_rate_hz_` and `samples_per_channel_` are updated + // upon success. If an error is returned, some fields may not have been + // updated, or may contain inconsistent values. If muted state is enabled + // (through Config::enable_muted_state), `muted` may be set to true after a + // prolonged expand period. When this happens, the `data_` in `audio_frame` + // is not written, but should be interpreted as being all zeros. For testing + // purposes, an override can be supplied in the `action_override` argument, + // which will cause NetEq to take this action next, instead of the action it + // would normally choose. An optional output argument for fetching the current + // sample rate can be provided, which will return the same value as + // last_output_sample_rate_hz() but will avoid additional synchronization. // Returns kOK on success, or kFail in case of an error. virtual int GetAudio( AudioFrame* audio_frame, @@ -278,13 +276,6 @@ class NetEq { // statistics are never reset. virtual NetEqOperationsAndState GetOperationsAndState() const = 0; - // Enables post-decode VAD. When enabled, GetAudio() will return - // kOutputVADPassive when the signal contains no speech. - virtual void EnableVad() {} - - // Disables post-decode VAD. - virtual void DisableVad() {} - // Returns the RTP timestamp for the last sample delivered by GetAudio(). // The return value will be empty if no valid timestamp is available. virtual absl::optional GetPlayoutTimestamp() const = 0; diff --git a/modules/audio_coding/BUILD.gn b/modules/audio_coding/BUILD.gn index 5de99efa45..8b23955d5b 100644 --- a/modules/audio_coding/BUILD.gn +++ b/modules/audio_coding/BUILD.gn @@ -689,8 +689,6 @@ rtc_library("neteq") { "neteq/packet_arrival_history.h", "neteq/packet_buffer.cc", "neteq/packet_buffer.h", - "neteq/post_decode_vad.cc", - "neteq/post_decode_vad.h", "neteq/preemptive_expand.cc", "neteq/preemptive_expand.h", "neteq/random_vector.cc", @@ -1655,7 +1653,6 @@ if (rtc_include_tests) { "neteq/normal_unittest.cc", "neteq/packet_arrival_history_unittest.cc", "neteq/packet_buffer_unittest.cc", - "neteq/post_decode_vad_unittest.cc", "neteq/random_vector_unittest.cc", "neteq/red_payload_splitter_unittest.cc", "neteq/reorder_optimizer_unittest.cc", diff --git a/modules/audio_coding/acm2/acm_receiver.cc b/modules/audio_coding/acm2/acm_receiver.cc index a77e472ec1..24a49024c8 100644 --- a/modules/audio_coding/acm2/acm_receiver.cc +++ b/modules/audio_coding/acm2/acm_receiver.cc @@ -50,11 +50,7 @@ std::unique_ptr CreateNetEq( AcmReceiver::Config::Config( rtc::scoped_refptr decoder_factory) - : clock(*Clock::GetRealTimeClock()), decoder_factory(decoder_factory) { - // Post-decode VAD is disabled by default in NetEq, however, Audio - // Conference Mixer relies on VAD decisions and fails without them. - neteq_config.enable_post_decode_vad = true; -} + : clock(*Clock::GetRealTimeClock()), decoder_factory(decoder_factory) {} AcmReceiver::Config::Config(const Config&) = default; AcmReceiver::Config::~Config() = default; diff --git a/modules/audio_coding/acm2/acm_receiver_unittest.cc b/modules/audio_coding/acm2/acm_receiver_unittest.cc index cda6688157..8b35f4a621 100644 --- a/modules/audio_coding/acm2/acm_receiver_unittest.cc +++ b/modules/audio_coding/acm2/acm_receiver_unittest.cc @@ -190,9 +190,6 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { const size_t output_channels = info.num_channels; const size_t samples_per_ms = rtc::checked_cast( rtc::CheckedDivExact(output_sample_rate_hz, 1000)); - const AudioFrame::VADActivity expected_vad_activity = - output_sample_rate_hz > 16000 ? AudioFrame::kVadActive - : AudioFrame::kVadPassive; // Expect the first output timestamp to be 5*fs/8000 samples before the // first inserted timestamp (because of NetEq's look-ahead). (This value is @@ -217,7 +214,6 @@ class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi { EXPECT_EQ(output_sample_rate_hz, frame.sample_rate_hz_); EXPECT_EQ(output_channels, frame.num_channels_); EXPECT_EQ(AudioFrame::kNormalSpeech, frame.speech_type_); - EXPECT_EQ(expected_vad_activity, frame.vad_activity_); EXPECT_FALSE(muted); } } @@ -242,61 +238,6 @@ TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) { RunVerifyAudioFrame({"opus", 48000, 2}); } -#if defined(WEBRTC_ANDROID) -#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad -#else -#define MAYBE_PostdecodingVad PostdecodingVad -#endif -TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) { - EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad); - constexpr int payload_type = 34; - const SdpAudioFormat codec = {"L16", 16000, 1}; - const AudioCodecInfo info = SetEncoder(payload_type, codec); - receiver_->SetCodecs({{payload_type, codec}}); - constexpr int kNumPackets = 5; - AudioFrame frame; - for (int n = 0; n < kNumPackets; ++n) { - const int num_10ms_frames = InsertOnePacketOfSilence(info); - for (int k = 0; k < num_10ms_frames; ++k) { - bool muted; - ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); - } - } - EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_); -} - -class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi { - protected: - AcmReceiverTestPostDecodeVadPassiveOldApi() { - config_.neteq_config.enable_post_decode_vad = false; - } -}; - -#if defined(WEBRTC_ANDROID) -#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad -#else -#define MAYBE_PostdecodingVad PostdecodingVad -#endif -TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) { - EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad); - constexpr int payload_type = 34; - const SdpAudioFormat codec = {"L16", 16000, 1}; - const AudioCodecInfo info = SetEncoder(payload_type, codec); - auto const value = encoder_factory_->QueryAudioEncoder(codec); - ASSERT_TRUE(value.has_value()); - receiver_->SetCodecs({{payload_type, codec}}); - const int kNumPackets = 5; - AudioFrame frame; - for (int n = 0; n < kNumPackets; ++n) { - const int num_10ms_frames = InsertOnePacketOfSilence(info); - for (int k = 0; k < num_10ms_frames; ++k) { - bool muted; - ASSERT_EQ(0, receiver_->GetAudio(info.sample_rate_hz, &frame, &muted)); - } - } - EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_); -} - #if defined(WEBRTC_ANDROID) #define MAYBE_LastAudioCodec DISABLED_LastAudioCodec #else diff --git a/modules/audio_coding/neteq/background_noise.cc b/modules/audio_coding/neteq/background_noise.cc index 2c95d3b390..0c33dba47a 100644 --- a/modules/audio_coding/neteq/background_noise.cc +++ b/modules/audio_coding/neteq/background_noise.cc @@ -17,7 +17,6 @@ #include "common_audio/signal_processing/include/signal_processing_library.h" #include "modules/audio_coding/neteq/audio_multi_vector.h" #include "modules/audio_coding/neteq/cross_correlation.h" -#include "modules/audio_coding/neteq/post_decode_vad.h" namespace webrtc { namespace { @@ -44,17 +43,11 @@ void BackgroundNoise::Reset() { } } -bool BackgroundNoise::Update(const AudioMultiVector& input, - const PostDecodeVad& vad) { +bool BackgroundNoise::Update(const AudioMultiVector& sync_buffer) { bool filter_params_saved = false; - if (vad.running() && vad.active_speech()) { - // Do not update the background noise parameters if we know that the signal - // is active speech. - return filter_params_saved; - } int32_t auto_correlation[kMaxLpcOrder + 1]; - int16_t fiter_output[kMaxLpcOrder + kResidualLength]; + int16_t filter_output[kMaxLpcOrder + kResidualLength]; int16_t reflection_coefficients[kMaxLpcOrder]; int16_t lpc_coefficients[kMaxLpcOrder + 1]; @@ -62,14 +55,13 @@ bool BackgroundNoise::Update(const AudioMultiVector& input, ChannelParameters& parameters = channel_parameters_[channel_ix]; int16_t temp_signal_array[kVecLen + kMaxLpcOrder] = {0}; int16_t* temp_signal = &temp_signal_array[kMaxLpcOrder]; - RTC_DCHECK_GE(input.Size(), kVecLen); - input[channel_ix].CopyTo(kVecLen, input.Size() - kVecLen, temp_signal); + RTC_DCHECK_GE(sync_buffer.Size(), kVecLen); + sync_buffer[channel_ix].CopyTo(kVecLen, sync_buffer.Size() - kVecLen, + temp_signal); int32_t sample_energy = CalculateAutoCorrelation(temp_signal, kVecLen, auto_correlation); - if ((!vad.running() && - sample_energy < parameters.energy_update_threshold) || - (vad.running() && !vad.active_speech())) { + if (sample_energy < parameters.energy_update_threshold) { // Generate LPC coefficients. if (auto_correlation[0] <= 0) { // Center value in auto-correlation is not positive. Do not update. @@ -95,10 +87,10 @@ bool BackgroundNoise::Update(const AudioMultiVector& input, // Generate the CNG gain factor by looking at the energy of the residual. WebRtcSpl_FilterMAFastQ12(temp_signal + kVecLen - kResidualLength, - fiter_output, lpc_coefficients, + filter_output, lpc_coefficients, kMaxLpcOrder + 1, kResidualLength); int32_t residual_energy = WebRtcSpl_DotProductWithScale( - fiter_output, fiter_output, kResidualLength, 0); + filter_output, filter_output, kResidualLength, 0); // Check spectral flatness. // Comparing the residual variance with the input signal variance tells @@ -117,9 +109,8 @@ bool BackgroundNoise::Update(const AudioMultiVector& input, filter_params_saved = true; } } else { - // Will only happen if post-decode VAD is disabled and `sample_energy` is - // not low enough. Increase the threshold for update so that it increases - // by a factor 4 in 4 seconds. + // Will only happen if `sample_energy` is not low enough. Increase the + // threshold for update so that it increases by a factor 4 in 4 seconds. IncrementEnergyThreshold(channel_ix, sample_energy); } } diff --git a/modules/audio_coding/neteq/background_noise.h b/modules/audio_coding/neteq/background_noise.h index 8e6d5890a0..9ef0131c92 100644 --- a/modules/audio_coding/neteq/background_noise.h +++ b/modules/audio_coding/neteq/background_noise.h @@ -39,9 +39,9 @@ class BackgroundNoise { void Reset(); // Updates the parameter estimates based on the signal currently in the - // `sync_buffer`, and on the latest decision in `vad` if it is running. + // `sync_buffer`. // Returns true if the filter parameters are updated. - bool Update(const AudioMultiVector& sync_buffer, const PostDecodeVad& vad); + bool Update(const AudioMultiVector& sync_buffer); // Generates background noise given a random vector and writes the output to // `buffer`. diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc index 144893b6d3..6a76096b49 100644 --- a/modules/audio_coding/neteq/neteq_impl.cc +++ b/modules/audio_coding/neteq/neteq_impl.cc @@ -37,7 +37,6 @@ #include "modules/audio_coding/neteq/normal.h" #include "modules/audio_coding/neteq/packet.h" #include "modules/audio_coding/neteq/packet_buffer.h" -#include "modules/audio_coding/neteq/post_decode_vad.h" #include "modules/audio_coding/neteq/preemptive_expand.h" #include "modules/audio_coding/neteq/red_payload_splitter.h" #include "modules/audio_coding/neteq/statistics_calculator.h" @@ -72,49 +71,26 @@ std::unique_ptr CreateNetEqController( return controller_factory.CreateNetEqController(config); } -void SetAudioFrameActivityAndType(bool vad_enabled, - NetEqImpl::OutputType type, - AudioFrame::VADActivity last_vad_activity, - AudioFrame* audio_frame) { +AudioFrame::SpeechType ToSpeechType(NetEqImpl::OutputType type) { switch (type) { case NetEqImpl::OutputType::kNormalSpeech: { - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - audio_frame->vad_activity_ = AudioFrame::kVadActive; - break; - } - case NetEqImpl::OutputType::kVadPassive: { - // This should only be reached if the VAD is enabled. - RTC_DCHECK(vad_enabled); - audio_frame->speech_type_ = AudioFrame::kNormalSpeech; - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - break; + return AudioFrame::kNormalSpeech; } case NetEqImpl::OutputType::kCNG: { - audio_frame->speech_type_ = AudioFrame::kCNG; - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - break; + return AudioFrame::kCNG; } case NetEqImpl::OutputType::kPLC: { - audio_frame->speech_type_ = AudioFrame::kPLC; - audio_frame->vad_activity_ = last_vad_activity; - break; + return AudioFrame::kPLC; } case NetEqImpl::OutputType::kPLCCNG: { - audio_frame->speech_type_ = AudioFrame::kPLCCNG; - audio_frame->vad_activity_ = AudioFrame::kVadPassive; - break; + return AudioFrame::kPLCCNG; } case NetEqImpl::OutputType::kCodecPLC: { - audio_frame->speech_type_ = AudioFrame::kCodecPLC; - audio_frame->vad_activity_ = last_vad_activity; - break; + return AudioFrame::kCodecPLC; } default: RTC_DCHECK_NOTREACHED(); - } - if (!vad_enabled) { - // Always set kVadUnknown when receive VAD is inactive. - audio_frame->vad_activity_ = AudioFrame::kVadUnknown; + return AudioFrame::kUndefined; } } @@ -171,7 +147,6 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, packet_buffer_(std::move(deps.packet_buffer)), red_payload_splitter_(std::move(deps.red_payload_splitter)), timestamp_scaler_(std::move(deps.timestamp_scaler)), - vad_(new PostDecodeVad()), expand_factory_(std::move(deps.expand_factory)), accelerate_factory_(std::move(deps.accelerate_factory)), preemptive_expand_factory_(std::move(deps.preemptive_expand_factory)), @@ -215,10 +190,6 @@ NetEqImpl::NetEqImpl(const NetEq::Config& config, if (create_components) { SetSampleRateAndChannels(fs, 1); // Default is 1 channel. } - RTC_DCHECK(!vad_->enabled()); - if (config.enable_post_decode_vad) { - vad_->Enable(); - } } NetEqImpl::~NetEqImpl() = default; @@ -256,9 +227,7 @@ int NetEqImpl::GetAudio(AudioFrame* audio_frame, audio_frame->sample_rate_hz_, rtc::dchecked_cast(audio_frame->samples_per_channel_ * 100)); RTC_DCHECK_EQ(*muted, audio_frame->muted()); - SetAudioFrameActivityAndType(vad_->enabled(), LastOutputType(), - last_vad_activity_, audio_frame); - last_vad_activity_ = audio_frame->vad_activity_; + audio_frame->speech_type_ = ToSpeechType(LastOutputType()); last_output_sample_rate_hz_ = audio_frame->sample_rate_hz_; RTC_DCHECK(last_output_sample_rate_hz_ == 8000 || last_output_sample_rate_hz_ == 16000 || @@ -402,18 +371,6 @@ NetEqOperationsAndState NetEqImpl::GetOperationsAndState() const { return result; } -void NetEqImpl::EnableVad() { - MutexLock lock(&mutex_); - RTC_DCHECK(vad_.get()); - vad_->Enable(); -} - -void NetEqImpl::DisableVad() { - MutexLock lock(&mutex_); - RTC_DCHECK(vad_.get()); - vad_->Disable(); -} - absl::optional NetEqImpl::GetPlayoutTimestamp() const { MutexLock lock(&mutex_); if (first_packet_ || last_mode_ == Mode::kRfc3389Cng || @@ -874,11 +831,8 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, last_decoded_type_ = speech_type; } - RTC_DCHECK(vad_.get()); bool sid_frame_available = (operation == Operation::kRfc3389Cng && !packet_list.empty()); - vad_->Update(decoded_buffer_.get(), static_cast(length), speech_type, - sid_frame_available, fs_hz_); // This is the criterion that we did decode some data through the speech // decoder, and the operation resulted in comfort noise. @@ -1028,7 +982,7 @@ int NetEqImpl::GetAudioInternal(AudioFrame* audio_frame, (last_mode_ == Mode::kPreemptiveExpandFail) || (last_mode_ == Mode::kRfc3389Cng) || (last_mode_ == Mode::kCodecInternalCng)) { - background_noise_->Update(*sync_buffer_, *vad_.get()); + background_noise_->Update(*sync_buffer_); } if (operation == Operation::kDtmf) { @@ -2104,10 +2058,6 @@ void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) { if (cng_decoder) cng_decoder->Reset(); - // Reinit post-decode VAD with new sample rate. - RTC_DCHECK(vad_.get()); // Cannot be NULL here. - vad_->Init(); - // Delete algorithm buffer and create a new one. algorithm_buffer_.reset(new AudioMultiVector(channels)); @@ -2148,7 +2098,6 @@ void NetEqImpl::SetSampleRateAndChannels(int fs_hz, size_t channels) { } NetEqImpl::OutputType NetEqImpl::LastOutputType() { - RTC_DCHECK(vad_.get()); RTC_DCHECK(expand_.get()); if (last_mode_ == Mode::kCodecInternalCng || last_mode_ == Mode::kRfc3389Cng) { @@ -2158,8 +2107,6 @@ NetEqImpl::OutputType NetEqImpl::LastOutputType() { return OutputType::kPLCCNG; } else if (last_mode_ == Mode::kExpand) { return OutputType::kPLC; - } else if (vad_->running() && !vad_->active_speech()) { - return OutputType::kVadPassive; } else if (last_mode_ == Mode::kCodecPlc) { return OutputType::kCodecPLC; } else { diff --git a/modules/audio_coding/neteq/neteq_impl.h b/modules/audio_coding/neteq/neteq_impl.h index f164238b09..eed7645e7d 100644 --- a/modules/audio_coding/neteq/neteq_impl.h +++ b/modules/audio_coding/neteq/neteq_impl.h @@ -48,7 +48,6 @@ class Merge; class NackTracker; class Normal; class RedPayloadSplitter; -class PostDecodeVad; class PreemptiveExpand; class RandomVector; class SyncBuffer; @@ -171,13 +170,6 @@ class NetEqImpl : public webrtc::NetEq { NetEqOperationsAndState GetOperationsAndState() const override; - // Enables post-decode VAD. When enabled, GetAudio() will return - // kOutputVADPassive when the signal contains no speech. - void EnableVad() override; - - // Disables post-decode VAD. - void DisableVad() override; - absl::optional GetPlayoutTimestamp() const override; int last_output_sample_rate_hz() const override; @@ -359,7 +351,6 @@ class NetEqImpl : public webrtc::NetEq { RTC_GUARDED_BY(mutex_); const std::unique_ptr timestamp_scaler_ RTC_GUARDED_BY(mutex_); - const std::unique_ptr vad_ RTC_GUARDED_BY(mutex_); const std::unique_ptr expand_factory_ RTC_GUARDED_BY(mutex_); const std::unique_ptr accelerate_factory_ RTC_GUARDED_BY(mutex_); @@ -401,8 +392,6 @@ class NetEqImpl : public webrtc::NetEq { std::unique_ptr nack_ RTC_GUARDED_BY(mutex_); bool nack_enabled_ RTC_GUARDED_BY(mutex_); const bool enable_muted_state_ RTC_GUARDED_BY(mutex_); - AudioFrame::VADActivity last_vad_activity_ RTC_GUARDED_BY(mutex_) = - AudioFrame::kVadPassive; std::unique_ptr generated_noise_stopwatch_ RTC_GUARDED_BY(mutex_); std::vector last_decoded_packet_infos_ RTC_GUARDED_BY(mutex_); diff --git a/modules/audio_coding/neteq/post_decode_vad.cc b/modules/audio_coding/neteq/post_decode_vad.cc deleted file mode 100644 index 9999d6764b..0000000000 --- a/modules/audio_coding/neteq/post_decode_vad.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013 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 "modules/audio_coding/neteq/post_decode_vad.h" - -namespace webrtc { - -PostDecodeVad::~PostDecodeVad() { - if (vad_instance_) - WebRtcVad_Free(vad_instance_); -} - -void PostDecodeVad::Enable() { - if (!vad_instance_) { - // Create the instance. - vad_instance_ = WebRtcVad_Create(); - if (vad_instance_ == nullptr) { - // Failed to create instance. - Disable(); - return; - } - } - Init(); - enabled_ = true; -} - -void PostDecodeVad::Disable() { - enabled_ = false; - running_ = false; -} - -void PostDecodeVad::Init() { - running_ = false; - if (vad_instance_) { - WebRtcVad_Init(vad_instance_); - WebRtcVad_set_mode(vad_instance_, kVadMode); - running_ = true; - } -} - -void PostDecodeVad::Update(int16_t* signal, - size_t length, - AudioDecoder::SpeechType speech_type, - bool sid_frame, - int fs_hz) { - if (!vad_instance_ || !enabled_) { - return; - } - - if (speech_type == AudioDecoder::kComfortNoise || sid_frame || - fs_hz > 16000) { - // TODO(hlundin): Remove restriction on fs_hz. - running_ = false; - active_speech_ = true; - sid_interval_counter_ = 0; - } else if (!running_) { - ++sid_interval_counter_; - } - - if (sid_interval_counter_ >= kVadAutoEnable) { - Init(); - } - - if (length > 0 && running_) { - size_t vad_sample_index = 0; - active_speech_ = false; - // Loop through frame sizes 30, 20, and 10 ms. - for (int vad_frame_size_ms = 30; vad_frame_size_ms >= 10; - vad_frame_size_ms -= 10) { - size_t vad_frame_size_samples = - static_cast(vad_frame_size_ms * fs_hz / 1000); - while (length - vad_sample_index >= vad_frame_size_samples) { - int vad_return = - WebRtcVad_Process(vad_instance_, fs_hz, &signal[vad_sample_index], - vad_frame_size_samples); - active_speech_ |= (vad_return == 1); - vad_sample_index += vad_frame_size_samples; - } - } - } -} - -} // namespace webrtc diff --git a/modules/audio_coding/neteq/post_decode_vad.h b/modules/audio_coding/neteq/post_decode_vad.h deleted file mode 100644 index 3bd91b9edb..0000000000 --- a/modules/audio_coding/neteq/post_decode_vad.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013 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 MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ -#define MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ - -#include -#include - -#include "api/audio_codecs/audio_decoder.h" -#include "common_audio/vad/include/webrtc_vad.h" - -namespace webrtc { - -class PostDecodeVad { - public: - PostDecodeVad() - : enabled_(false), - running_(false), - active_speech_(true), - sid_interval_counter_(0), - vad_instance_(NULL) {} - - virtual ~PostDecodeVad(); - - PostDecodeVad(const PostDecodeVad&) = delete; - PostDecodeVad& operator=(const PostDecodeVad&) = delete; - - // Enables post-decode VAD. - void Enable(); - - // Disables post-decode VAD. - void Disable(); - - // Initializes post-decode VAD. - void Init(); - - // Updates post-decode VAD with the audio data in `signal` having `length` - // samples. The data is of type `speech_type`, at the sample rate `fs_hz`. - void Update(int16_t* signal, - size_t length, - AudioDecoder::SpeechType speech_type, - bool sid_frame, - int fs_hz); - - // Accessors. - bool enabled() const { return enabled_; } - bool running() const { return running_; } - bool active_speech() const { return active_speech_; } - - private: - static const int kVadMode = 0; // Sets aggressiveness to "Normal". - // Number of Update() calls without CNG/SID before re-enabling VAD. - static const int kVadAutoEnable = 3000; - - bool enabled_; - bool running_; - bool active_speech_; - int sid_interval_counter_; - ::VadInst* vad_instance_; -}; - -} // namespace webrtc -#endif // MODULES_AUDIO_CODING_NETEQ_POST_DECODE_VAD_H_ diff --git a/modules/audio_coding/neteq/post_decode_vad_unittest.cc b/modules/audio_coding/neteq/post_decode_vad_unittest.cc deleted file mode 100644 index da3e4e864e..0000000000 --- a/modules/audio_coding/neteq/post_decode_vad_unittest.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -// Unit tests for PostDecodeVad class. - -#include "modules/audio_coding/neteq/post_decode_vad.h" - -#include "test/gtest.h" - -namespace webrtc { - -TEST(PostDecodeVad, CreateAndDestroy) { - PostDecodeVad vad; -} - -// TODO(hlundin): Write more tests. - -} // namespace webrtc diff --git a/test/fuzzers/neteq_signal_fuzzer.cc b/test/fuzzers/neteq_signal_fuzzer.cc index 485c38085e..3b1f70cdb4 100644 --- a/test/fuzzers/neteq_signal_fuzzer.cc +++ b/test/fuzzers/neteq_signal_fuzzer.cc @@ -179,7 +179,6 @@ void FuzzOneInputTest(const uint8_t* data, size_t size) { // Configure NetEq and the NetEqTest object. NetEqTest::Callbacks callbacks; NetEq::Config config; - config.enable_post_decode_vad = true; config.enable_fast_accelerate = true; auto codecs = NetEqTest::StandardDecoderMap(); // rate_types contains the payload types that will be used for encoding. From dc769ae509198577ef8351a0da8a2d564676a9e4 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Wed, 7 Feb 2024 10:02:18 -0800 Subject: [PATCH 093/170] Roll chromium_revision ed8169cbb0..1b5fb86a99 (1257259:1257437) Change log: https://chromium.googlesource.com/chromium/src/+log/ed8169cbb0..1b5fb86a99 Full diff: https://chromium.googlesource.com/chromium/src/+/ed8169cbb0..1b5fb86a99 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/81ad254d3c..a80392267c * src/build: https://chromium.googlesource.com/chromium/src/build/+log/afc7f0f08a..37009039d9 * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/262e0f6f64..f0bd4d6d94 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/386f1b2ae9..3b662c3afa * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/d0f1ef3ee0..acb795da6a * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/18c651389f..f7718e49b8 * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/a8f0954411..9305434c21 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/450c05cd3b..7cf1c2d0f4 * src/third_party/r8: Wpuxcm9gcq_RziIlCD0O_dgjRUr75g61LfP2iXo4FTsC..c2PL3_z2rOvwF74DJ36SLbH9iry7D6V-KG7NU_njKJwC * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/ceb5eb8417..a67d34022c DEPS diff: https://chromium.googlesource.com/chromium/src/+/ed8169cbb0..1b5fb86a99/DEPS Clang version changed llvmorg-18-init-17730-gf670112a:llvmorg-19-init-817-g3f5fcb59 Details: https://chromium.googlesource.com/chromium/src/+/ed8169cbb0..1b5fb86a99/tools/clang/scripts/update.py BUG=None Change-Id: I0bf32c5adeeb6da8489dbe5f4697d9a934449f0e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338208 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41689} --- DEPS | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/DEPS b/DEPS index ebc13d622b..f917b0f0f8 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'ed8169cbb00c3d73ba0f9b60da641e55d4d062f2', + 'chromium_revision': '1b5fb86a995bf16dfe1156b4953605484f430280', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@81ad254d3cf38a2ccd5ce32a2ec9907b5a84acca', + 'https://chromium.googlesource.com/chromium/src/base@a80392267ce83c1bcc5d6cb9ee6e6f28d8ab9de7', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@afc7f0f08a77d1ff83c327617afd6fe2cb0b3431', + 'https://chromium.googlesource.com/chromium/src/build@37009039d9cbd4e138d6eabcb3a1b1a707be865d', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@262e0f6f649a83f5ac98f3bac6eefff66fb90133', + 'https://chromium.googlesource.com/chromium/src/buildtools@f0bd4d6d94dd0e0b383d03f0d8d11d817e6e382b', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@386f1b2ae92f3005617b8d7d9d6c42b3892255d0', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@3b662c3afa5a46de4205d24ab13c74dfad1f0fb5', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@d0f1ef3ee07d54d407f8e17c0761fc76c50b6dfd', + 'https://chromium.googlesource.com/chromium/src/testing@acb795da6a74466093fd44504d6c386224b8a001', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@18c651389fbdc155e3271dccb908edf2ebc6f652', + 'https://chromium.googlesource.com/chromium/src/third_party@f7718e49b8b2ee0b1beccd2a7dfb7ab3e0c5c16b', 'src/buildtools/linux64': { 'packages': [ @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@a8f095441135fc2a95b5d45c9f66b242906ddfc1', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@9305434c21feace5efde065e50151596484b7bc5', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@450c05cd3bd3e596f4757cca3217182d764b9ba9', + 'https://android.googlesource.com/platform/external/perfetto.git@7cf1c2d0f40780828dae7a1590484cfc3055b48c', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -331,7 +331,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'Wpuxcm9gcq_RziIlCD0O_dgjRUr75g61LfP2iXo4FTsC', + 'version': 'c2PL3_z2rOvwF74DJ36SLbH9iry7D6V-KG7NU_njKJwC', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@ceb5eb8417e3c47c8392056eba19488713027198', + 'https://chromium.googlesource.com/chromium/src/tools@a67d34022ce539302a8aecc00d96ac3f7a840e64', 'src/third_party/accessibility_test_framework': { 'packages': [ From fe6178ef7d7f4f25ce93253bdda0b7daae0769a6 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Wed, 7 Feb 2024 16:01:33 -0800 Subject: [PATCH 094/170] Roll chromium_revision 1b5fb86a99..bae41acd7c (1257437:1257677) Change log: https://chromium.googlesource.com/chromium/src/+log/1b5fb86a99..bae41acd7c Full diff: https://chromium.googlesource.com/chromium/src/+/1b5fb86a99..bae41acd7c Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/a80392267c..086cbbd648 * src/build: https://chromium.googlesource.com/chromium/src/build/+log/37009039d9..4a9d301719 * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/f0bd4d6d94..c89450da2b * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/3b662c3afa..1c4f73a43e * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/acb795da6a..c2dccaca29 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/f7718e49b8..8660aacd5e * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/6d39c23fce..27e029f529 * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/9305434c21..784db7a5f0 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/7cf1c2d0f4..74cdba3b28 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/a67d34022c..0882d37654 DEPS diff: https://chromium.googlesource.com/chromium/src/+/1b5fb86a99..bae41acd7c/DEPS Clang version changed llvmorg-19-init-817-g3f5fcb59:llvmorg-18-init-17730-gf670112a Details: https://chromium.googlesource.com/chromium/src/+/1b5fb86a99..bae41acd7c/tools/clang/scripts/update.py BUG=None Change-Id: I34151f2689a3ad04edce07811e6f93f02ba155bd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338520 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41690} --- DEPS | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/DEPS b/DEPS index f917b0f0f8..130b7bae63 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '1b5fb86a995bf16dfe1156b4953605484f430280', + 'chromium_revision': 'bae41acd7c06d59eba25d68a1fa028f7af5ddb99', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@a80392267ce83c1bcc5d6cb9ee6e6f28d8ab9de7', + 'https://chromium.googlesource.com/chromium/src/base@086cbbd648f19c105a95a92ed4a22282ef344b1d', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@37009039d9cbd4e138d6eabcb3a1b1a707be865d', + 'https://chromium.googlesource.com/chromium/src/build@4a9d3017197359d313e2be6a0bdf3a97a44aae66', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@f0bd4d6d94dd0e0b383d03f0d8d11d817e6e382b', + 'https://chromium.googlesource.com/chromium/src/buildtools@c89450da2b5b8a97d9fc2e3c746bb12295778faf', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@3b662c3afa5a46de4205d24ab13c74dfad1f0fb5', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@1c4f73a43e214c39f5b5f28fd31981e207335383', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@acb795da6a74466093fd44504d6c386224b8a001', + 'https://chromium.googlesource.com/chromium/src/testing@c2dccaca29adbb3c17b786b8cef9c09e9d375ea0', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@f7718e49b8b2ee0b1beccd2a7dfb7ab3e0c5c16b', + 'https://chromium.googlesource.com/chromium/src/third_party@8660aacd5e96a4949b10a8616a39c943ff86f466', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@6d39c23fce9fdf9e5ce7c5730de4bc14556ec159', + 'https://chromium.googlesource.com/catapult.git@27e029f52955bf8ac9e35a1dacf4f56bb39d3eb8', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@9305434c21feace5efde065e50151596484b7bc5', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@784db7a5f04f5093941b6c2228e40b9a10d553b2', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@7cf1c2d0f40780828dae7a1590484cfc3055b48c', + 'https://android.googlesource.com/platform/external/perfetto.git@74cdba3b28c2a48bb3c5b5cae32812eb6c76a8da', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@a67d34022ce539302a8aecc00d96ac3f7a840e64', + 'https://chromium.googlesource.com/chromium/src/tools@0882d37654d1bf50ab8b0fedbcff4ab341d470d4', 'src/third_party/accessibility_test_framework': { 'packages': [ From 76817070d34848fb3dc643b2acfec66e20344687 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Wed, 7 Feb 2024 20:02:06 -0800 Subject: [PATCH 095/170] Update WebRTC code version (2024-02-08T04:02:04). Bug: None Change-Id: I76e138fbb76020fbe769a57750c9938246baf005 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338212 Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41691} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index c07f1262c4..5a4a798c73 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-07T04:02:17"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-08T04:02:04"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 5e04753e7aeabcccb7a34fde5bb9cd092a3aebde Mon Sep 17 00:00:00 2001 From: Tommi Date: Thu, 1 Feb 2024 14:04:19 +0100 Subject: [PATCH 096/170] Remove deprecated IceCandidateType values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: none Change-Id: I13ebcc6fd38aa25fee8afd92bda06a0f3483cda1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337120 Reviewed-by: Björn Terelius Commit-Queue: Björn Terelius Auto-Submit: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41692} --- .../rtc_event_log/events/rtc_event_ice_candidate_pair_config.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h index c8623a3010..14984b324f 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h @@ -38,9 +38,6 @@ enum class IceCandidateType { kSrflx, kPrflx, kRelay, - // TODO(tommi): Legacy names. Remove. - kLocal [[deprecated("Use kHost instead")]] = kHost, - kStun [[deprecated("Use kSrflx instead ")]] = kSrflx }; enum class IceCandidatePairProtocol { From 74e7ac59b05e0941d0d86709747ce404b15a6da9 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Thu, 8 Feb 2024 00:14:43 -0800 Subject: [PATCH 097/170] Roll chromium_revision bae41acd7c..59df7a60eb (1257677:1257821) Change log: https://chromium.googlesource.com/chromium/src/+log/bae41acd7c..59df7a60eb Full diff: https://chromium.googlesource.com/chromium/src/+/bae41acd7c..59df7a60eb Changed dependencies * fuchsia_version: version:18.20240127.1.1..version:18.20240207.3.1 * src/base: https://chromium.googlesource.com/chromium/src/base/+log/086cbbd648..8f11a314eb * src/build: https://chromium.googlesource.com/chromium/src/build/+log/4a9d301719..c3b35d6b4c * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/c89450da2b..6e5b3a31f2 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/1c4f73a43e..9b810c7888 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/c2dccaca29..fb5d53661a * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/8660aacd5e..ce97b0e3f1 * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/27e029f529..ca502d307f * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/784db7a5f0..74a6ca92bb * src/third_party/libc++/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git/+log/9d119c1f4a..c51c9efb6c * src/third_party/libunwind/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git/+log/fc505746f0..8bad7bd6ec * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/74cdba3b28..6821c955bd * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/0882d37654..e9eee6e818 DEPS diff: https://chromium.googlesource.com/chromium/src/+/bae41acd7c..59df7a60eb/DEPS No update to Clang. BUG=None Change-Id: Icffbb9ee3d7e1708234e78835161b5210745b774 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338601 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41693} --- DEPS | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/DEPS b/DEPS index 130b7bae63..2adbdb4cbc 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'bae41acd7c06d59eba25d68a1fa028f7af5ddb99', + 'chromium_revision': '59df7a60ebe13178b3d085397d13486db906e49a', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -25,7 +25,7 @@ vars = { # By default, download the fuchsia sdk from the public sdk directory. 'fuchsia_sdk_cipd_prefix': 'fuchsia/sdk/core/', - 'fuchsia_version': 'version:18.20240127.1.1', + 'fuchsia_version': 'version:18.20240207.3.1', # By default, download the fuchsia images from the fuchsia GCS bucket. 'fuchsia_images_bucket': 'fuchsia', 'checkout_fuchsia': False, @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@086cbbd648f19c105a95a92ed4a22282ef344b1d', + 'https://chromium.googlesource.com/chromium/src/base@8f11a314ebca4c9aafe89b51736b96d8976f493a', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@4a9d3017197359d313e2be6a0bdf3a97a44aae66', + 'https://chromium.googlesource.com/chromium/src/build@c3b35d6b4cff8d6a2c616427726b15e187c57293', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@c89450da2b5b8a97d9fc2e3c746bb12295778faf', + 'https://chromium.googlesource.com/chromium/src/buildtools@6e5b3a31f22a0271a450318fcdeb80cdd2a57374', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@1c4f73a43e214c39f5b5f28fd31981e207335383', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@9b810c7888872552ebab3a437c6e5503a179444d', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@c2dccaca29adbb3c17b786b8cef9c09e9d375ea0', + 'https://chromium.googlesource.com/chromium/src/testing@fb5d53661ab9db51668b32785bdf847437bc20b4', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@8660aacd5e96a4949b10a8616a39c943ff86f466', + 'https://chromium.googlesource.com/chromium/src/third_party@ce97b0e3f12a32be4d978a2e25d1eb7cd2c6f8ec', 'src/buildtools/linux64': { 'packages': [ @@ -115,11 +115,11 @@ deps = { 'src/third_party/clang-format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@e5337933f2951cacd3aeacd238ce4578163ca0b9', 'src/third_party/libc++/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@9d119c1f4a097b7d27210874f4eba3fc91a83a4e', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@c51c9efb6c5a83e0e25c1e30864449d2beadd7a8', 'src/third_party/libc++abi/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@a7b3d968a3a923886fea64b424bd770e69dc4ea4', 'src/third_party/libunwind/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@fc505746f02c927d792bdeb328307e0e87500342', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git@8bad7bd6ec30f94bce82f7cb5b58ecbd6ce02996', 'src/third_party/ninja': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@27e029f52955bf8ac9e35a1dacf4f56bb39d3eb8', + 'https://chromium.googlesource.com/catapult.git@ca502d307f30e7ac2de76211d8d590ff31e5080f', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@784db7a5f04f5093941b6c2228e40b9a10d553b2', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@74a6ca92bba677fc87328637bf573deb5944ac91', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@74cdba3b28c2a48bb3c5b5cae32812eb6c76a8da', + 'https://android.googlesource.com/platform/external/perfetto.git@6821c955bdf682556ec4828a174a9cd916d0a02a', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@0882d37654d1bf50ab8b0fedbcff4ab341d470d4', + 'https://chromium.googlesource.com/chromium/src/tools@e9eee6e8184854da240ea5210043027715f205f0', 'src/third_party/accessibility_test_framework': { 'packages': [ From 68831d28c7be9d88d207999e52cc33f174e30a27 Mon Sep 17 00:00:00 2001 From: Joachim Reiersen Date: Wed, 7 Feb 2024 11:14:47 -0800 Subject: [PATCH 098/170] Remove extraneous partial re-initialization of NetEq in the ChannelReceive ctor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These function calls break RAII and are redundant since NetEq and voe::AudioLevel have just been constructed. Remove them to fix an issue where NetEq ignores the min/max delay passed to its constructor. This will not change default behavior since the defaults in NetEq::Config for max_delay_ms and min_delay_ms are both 0. Bug: webrtc:15835 Change-Id: I27d4745ac85d6c6948796fe1d6286a0b79429474 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338209 Reviewed-by: Jakob Ivarsson‎ Commit-Queue: Jakob Ivarsson‎ Cr-Commit-Position: refs/heads/main@{#41694} --- audio/channel_receive.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/audio/channel_receive.cc b/audio/channel_receive.cc index 8367b00113..17cf859ed8 100644 --- a/audio/channel_receive.cc +++ b/audio/channel_receive.cc @@ -569,13 +569,6 @@ ChannelReceive::ChannelReceive( network_thread_checker_.Detach(); - acm_receiver_.ResetInitialDelay(); - acm_receiver_.SetMinimumDelay(0); - acm_receiver_.SetMaximumDelay(0); - acm_receiver_.FlushBuffers(); - - _outputAudioLevel.ResetLevelFullRange(); - rtp_receive_statistics_->EnableRetransmitDetection(remote_ssrc_, true); RtpRtcpInterface::Configuration configuration; configuration.clock = clock; From 3e613c2590b2f76e3dd4cc13f76fb49aee05032b Mon Sep 17 00:00:00 2001 From: Dor Hen Date: Mon, 5 Feb 2024 07:58:10 -0800 Subject: [PATCH 099/170] Change `vector` with `const vector` As described in the issue. This won't compile under most compilers, at least that what godbolt indicated. So instead, using const vector to prevent the compilation errors. Keep in mind this is a bit more restrictive as it also implies constness on the vector itself and not only its members, meaning we cannot push/pop. Bug: webrtc:15829 Change-Id: I19c1223f0a3c56082da75b39c2afe152ae43a3a7 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337960 Reviewed-by: Harald Alvestrand Commit-Queue: Guido Urdaneta Reviewed-by: Guido Urdaneta Reviewed-by: Gustaf Ullberg Cr-Commit-Position: refs/heads/main@{#41695} --- audio/channel_send_frame_transformer_delegate_unittest.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/audio/channel_send_frame_transformer_delegate_unittest.cc b/audio/channel_send_frame_transformer_delegate_unittest.cc index 428235efc9..5c025bb345 100644 --- a/audio/channel_send_frame_transformer_delegate_unittest.cc +++ b/audio/channel_send_frame_transformer_delegate_unittest.cc @@ -59,7 +59,7 @@ class MockChannelSend { }; std::unique_ptr CreateMockReceiverFrame( - std::vector csrcs) { + const std::vector& csrcs) { std::unique_ptr mock_frame = std::make_unique>(); rtc::ArrayView payload(mock_data); @@ -168,7 +168,7 @@ TEST(ChannelSendFrameTransformerDelegateTest, delegate->Init(); ASSERT_TRUE(callback); - std::vector csrcs = {123, 234, 345, 456}; + const std::vector csrcs = {123, 234, 345, 456}; EXPECT_CALL(mock_channel, SendFrame).Times(0); EXPECT_CALL(mock_channel, SendFrame(_, 0, 0, ElementsAreArray(mock_data), _, ElementsAreArray(csrcs))); From cea1c0b9a91be940ec801ab84a7ca3b52e9fc930 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Wed, 7 Feb 2024 18:01:39 +0100 Subject: [PATCH 100/170] Dynamically assign ids to header extensions not enabled by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit by creating an id collision and letting UsedIds resolve it. Also avoid id=15 which is forbidden by https://www.rfc-editor.org/rfc/rfc8285#section-4.2 so might cause interop issues in offers to implementations not supporting two-byte extensions. BUG=webrtc:15378 Change-Id: I27926f065f8e396257294da7acf2be9802169805 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/319280 Reviewed-by: Harald Alvestrand Reviewed-by: Henrik Boström Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41696} --- media/engine/webrtc_video_engine.cc | 13 +++++++------ media/engine/webrtc_voice_engine.cc | 4 +++- pc/used_ids.h | 11 ++++++----- pc/used_ids_unittest.cc | 9 +++++---- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index 902b5365d1..a313407f2d 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -811,6 +811,8 @@ std::vector WebRtcVideoEngine::recv_codecs(bool include_rtx) const { std::vector WebRtcVideoEngine::GetRtpHeaderExtensions() const { std::vector result; + // id is *not* incremented for non-default extensions, UsedIds needs to + // resolve conflicts. int id = 1; for (const auto& uri : {webrtc::RtpExtension::kTimestampOffsetUri, @@ -825,27 +827,26 @@ WebRtcVideoEngine::GetRtpHeaderExtensions() const { result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv); } for (const auto& uri : {webrtc::RtpExtension::kAbsoluteCaptureTimeUri}) { - result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kStopped); + result.emplace_back(uri, id, webrtc::RtpTransceiverDirection::kStopped); } - result.emplace_back(webrtc::RtpExtension::kGenericFrameDescriptorUri00, id++, + result.emplace_back(webrtc::RtpExtension::kGenericFrameDescriptorUri00, id, IsEnabled(trials_, "WebRTC-GenericDescriptorAdvertised") ? webrtc::RtpTransceiverDirection::kSendRecv : webrtc::RtpTransceiverDirection::kStopped); result.emplace_back( - webrtc::RtpExtension::kDependencyDescriptorUri, id++, + webrtc::RtpExtension::kDependencyDescriptorUri, id, IsEnabled(trials_, "WebRTC-DependencyDescriptorAdvertised") ? webrtc::RtpTransceiverDirection::kSendRecv : webrtc::RtpTransceiverDirection::kStopped); - result.emplace_back( - webrtc::RtpExtension::kVideoLayersAllocationUri, id++, + webrtc::RtpExtension::kVideoLayersAllocationUri, id, IsEnabled(trials_, "WebRTC-VideoLayersAllocationAdvertised") ? webrtc::RtpTransceiverDirection::kSendRecv : webrtc::RtpTransceiverDirection::kStopped); // VideoFrameTrackingId is a test-only extension. if (IsEnabled(trials_, "WebRTC-VideoFrameTrackingIdAdvertised")) { - result.emplace_back(webrtc::RtpExtension::kVideoFrameTrackingIdUri, id++, + result.emplace_back(webrtc::RtpExtension::kVideoFrameTrackingIdUri, id, webrtc::RtpTransceiverDirection::kSendRecv); } return result; diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index fcc2703f98..23a1b1927c 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -643,6 +643,8 @@ std::vector WebRtcVoiceEngine::GetRtpHeaderExtensions() const { RTC_DCHECK(signal_thread_checker_.IsCurrent()); std::vector result; + // id is *not* incremented for non-default extensions, UsedIds needs to + // resolve conflicts. int id = 1; for (const auto& uri : {webrtc::RtpExtension::kAudioLevelUri, webrtc::RtpExtension::kAbsSendTimeUri, @@ -651,7 +653,7 @@ WebRtcVoiceEngine::GetRtpHeaderExtensions() const { result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kSendRecv); } for (const auto& uri : {webrtc::RtpExtension::kAbsoluteCaptureTimeUri}) { - result.emplace_back(uri, id++, webrtc::RtpTransceiverDirection::kStopped); + result.emplace_back(uri, id, webrtc::RtpTransceiverDirection::kStopped); } return result; } diff --git a/pc/used_ids.h b/pc/used_ids.h index 6b342cbea8..42ef00a7c0 100644 --- a/pc/used_ids.h +++ b/pc/used_ids.h @@ -147,15 +147,15 @@ class UsedRtpHeaderExtensionIds : public UsedIds { private: // Returns the first unused id in reverse order from the max id of one byte - // header extensions. This hopefully reduce the risk of more collisions. We + // header extensions. This hopefully reduces the risk of more collisions. We // want to change the default ids as little as possible. If no unused id is // found and two byte header extensions are enabled (i.e., - // `extmap_allow_mixed_` is true), search for unused ids from 15 to 255. + // `extmap_allow_mixed_` is true), search for unused ids from 16 to 255. int FindUnusedId() override { if (next_extension_id_ <= webrtc::RtpExtension::kOneByteHeaderExtensionMaxId) { // First search in reverse order from the max id of one byte header - // extensions. + // extensions (14). while (IsIdUsed(next_extension_id_) && next_extension_id_ >= min_allowed_id_) { --next_extension_id_; @@ -165,9 +165,10 @@ class UsedRtpHeaderExtensionIds : public UsedIds { if (id_domain_ == IdDomain::kTwoByteAllowed) { if (next_extension_id_ < min_allowed_id_) { // We have searched among all one-byte IDs without finding an unused ID, - // continue at the first two-byte ID. + // continue at the first two-byte ID (16; avoid 15 since it is somewhat + // special per https://www.rfc-editor.org/rfc/rfc8285#section-4.2 next_extension_id_ = - webrtc::RtpExtension::kOneByteHeaderExtensionMaxId + 1; + webrtc::RtpExtension::kOneByteHeaderExtensionMaxId + 2; } if (next_extension_id_ > diff --git a/pc/used_ids_unittest.cc b/pc/used_ids_unittest.cc index 6362f2773a..df3790b52c 100644 --- a/pc/used_ids_unittest.cc +++ b/pc/used_ids_unittest.cc @@ -119,7 +119,8 @@ TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) { UsedRtpHeaderExtensionIds::IdDomain::kTwoByteAllowed); // Fill all one byte IDs. - for (int i = 1; i < 15; ++i) { + for (int i = 1; i <= webrtc::RtpExtension::kOneByteHeaderExtensionMaxId; + ++i) { webrtc::RtpExtension id("", i); used_ids.FindAndSetIdUsed(&id); } @@ -131,11 +132,11 @@ TEST_F(UsedRtpHeaderExtensionIdsTest, TwoByteIdsAllowed) { // Expect to reassign to two-byte header extension IDs. used_ids.FindAndSetIdUsed(&id1_collision); - EXPECT_EQ(id1_collision.id, 15); + EXPECT_EQ(id1_collision.id, 16); used_ids.FindAndSetIdUsed(&id2_collision); - EXPECT_EQ(id2_collision.id, 16); + EXPECT_EQ(id2_collision.id, 17); used_ids.FindAndSetIdUsed(&id3_collision); - EXPECT_EQ(id3_collision.id, 17); + EXPECT_EQ(id3_collision.id, 18); } // Death tests. From 974044efca4fc3aa8bea9664aeb5934e0e2303aa Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Thu, 8 Feb 2024 13:15:51 +0000 Subject: [PATCH 101/170] Remove code for supporting SDES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework transport_description_factory to only have non-DTLS mode for testing, and rewrite tests accordingly. Bug: webrtc:11066, chromium:804275 Change-Id: Ie7d477c4331c975e4e0a3034fbbb749ed9009446 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336880 Commit-Queue: Harald Alvestrand Reviewed-by: Henrik Boström Cr-Commit-Position: refs/heads/main@{#41697} --- api/BUILD.gn | 1 - api/crypto_params.h | 43 -- p2p/base/transport_description.h | 11 - p2p/base/transport_description_factory.cc | 92 ++-- p2p/base/transport_description_factory.h | 15 +- .../transport_description_factory_unittest.cc | 112 ++--- pc/BUILD.gn | 26 - pc/dtls_srtp_transport.h | 1 - pc/jsep_transport.cc | 75 +-- pc/jsep_transport.h | 10 - pc/jsep_transport_controller.cc | 14 +- pc/jsep_transport_unittest.cc | 171 +------ pc/media_session.cc | 387 +------------- pc/media_session.h | 5 - pc/media_session_unittest.cc | 426 ++-------------- pc/peer_connection.cc | 4 +- pc/peer_connection_crypto_unittest.cc | 35 +- pc/peer_connection_interface_unittest.cc | 47 +- pc/sdp_offer_answer.cc | 16 +- pc/session_description.h | 9 - pc/srtp_filter.cc | 280 ----------- pc/srtp_filter.h | 147 ------ pc/srtp_filter_unittest.cc | 472 ------------------ pc/srtp_transport.h | 3 - pc/webrtc_sdp.cc | 53 -- pc/webrtc_sdp_unittest.cc | 21 - pc/webrtc_session_description_factory.cc | 67 ++- pc/webrtc_session_description_factory.h | 7 +- .../tests/unsignaled_stream_test.cc | 1 - 29 files changed, 231 insertions(+), 2320 deletions(-) delete mode 100644 api/crypto_params.h delete mode 100644 pc/srtp_filter.cc delete mode 100644 pc/srtp_filter.h delete mode 100644 pc/srtp_filter_unittest.cc diff --git a/api/BUILD.gn b/api/BUILD.gn index 61c000d3f0..e8d03f0e3e 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -274,7 +274,6 @@ rtc_library("libjingle_peerconnection_api") { visibility = [ "*" ] cflags = [] sources = [ - "crypto_params.h", "data_channel_interface.cc", "data_channel_interface.h", "jsep.cc", diff --git a/api/crypto_params.h b/api/crypto_params.h deleted file mode 100644 index 34906ea0ef..0000000000 --- a/api/crypto_params.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2004 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_CRYPTO_PARAMS_H_ -#define API_CRYPTO_PARAMS_H_ - -#include - -#include "absl/strings/string_view.h" - -namespace cricket { - -// Parameters for SRTP negotiation, as described in RFC 4568. -// TODO(benwright) - Rename to SrtpCryptoParams as these only apply to SRTP and -// not generic crypto parameters for WebRTC. -struct CryptoParams { - CryptoParams() : tag(0) {} - CryptoParams(int t, - absl::string_view cs, - absl::string_view kp, - absl::string_view sp) - : tag(t), crypto_suite(cs), key_params(kp), session_params(sp) {} - - bool Matches(const CryptoParams& params) const { - return (tag == params.tag && crypto_suite == params.crypto_suite); - } - - int tag; - std::string crypto_suite; - std::string key_params; - std::string session_params; -}; - -} // namespace cricket - -#endif // API_CRYPTO_PARAMS_H_ diff --git a/p2p/base/transport_description.h b/p2p/base/transport_description.h index 7d28ad52e9..53a1804933 100644 --- a/p2p/base/transport_description.h +++ b/p2p/base/transport_description.h @@ -25,17 +25,6 @@ namespace cricket { -// SEC_ENABLED and SEC_REQUIRED should only be used if the session -// was negotiated over TLS, to protect the inline crypto material -// exchange. -// SEC_DISABLED: No crypto in outgoing offer, ignore any supplied crypto. -// SEC_ENABLED: Crypto in outgoing offer and answer (if supplied in offer). -// SEC_REQUIRED: Crypto in outgoing offer and answer. Fail any offer with absent -// or unsupported crypto. -// TODO(deadbeef): Remove this or rename it to something more appropriate, like -// SdesPolicy. -enum SecurePolicy { SEC_DISABLED, SEC_ENABLED, SEC_REQUIRED }; - // Whether our side of the call is driving the negotiation, or the other side. enum IceRole { ICEROLE_CONTROLLING = 0, ICEROLE_CONTROLLED, ICEROLE_UNKNOWN }; diff --git a/p2p/base/transport_description_factory.cc b/p2p/base/transport_description_factory.cc index 7eb21da166..6e3af94384 100644 --- a/p2p/base/transport_description_factory.cc +++ b/p2p/base/transport_description_factory.cc @@ -23,7 +23,7 @@ namespace cricket { TransportDescriptionFactory::TransportDescriptionFactory( const webrtc::FieldTrialsView& field_trials) - : secure_(SEC_DISABLED), field_trials_(field_trials) {} + : field_trials_(field_trials) {} TransportDescriptionFactory::~TransportDescriptionFactory() = default; @@ -47,13 +47,15 @@ std::unique_ptr TransportDescriptionFactory::CreateOffer( desc->AddOption(ICE_OPTION_RENOMINATION); } - // If we are trying to establish a secure transport, add a fingerprint. - if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) { - // Fail if we can't create the fingerprint. - // If we are the initiator set role to "actpass". - if (!SetSecurityInfo(desc.get(), CONNECTIONROLE_ACTPASS)) { - return NULL; - } + // If we are not trying to establish a secure transport, don't add a + // fingerprint. + if (insecure_ && !certificate_) { + return desc; + } + // Fail if we can't create the fingerprint. + // If we are the initiator set role to "actpass". + if (!SetSecurityInfo(desc.get(), CONNECTIONROLE_ACTPASS)) { + return NULL; } return desc; @@ -87,43 +89,49 @@ std::unique_ptr TransportDescriptionFactory::CreateAnswer( if (options.enable_ice_renomination) { desc->AddOption(ICE_OPTION_RENOMINATION); } - - // Negotiate security params. - if (offer && offer->identity_fingerprint.get()) { - // The offer supports DTLS, so answer with DTLS, as long as we support it. - if (secure_ == SEC_ENABLED || secure_ == SEC_REQUIRED) { - ConnectionRole role = CONNECTIONROLE_NONE; - // If the offer does not constrain the role, go with preference. - if (offer->connection_role == CONNECTIONROLE_ACTPASS) { - role = (options.prefer_passive_role) ? CONNECTIONROLE_PASSIVE - : CONNECTIONROLE_ACTIVE; - } else if (offer->connection_role == CONNECTIONROLE_ACTIVE) { - role = CONNECTIONROLE_PASSIVE; - } else if (offer->connection_role == CONNECTIONROLE_PASSIVE) { - role = CONNECTIONROLE_ACTIVE; - } else if (offer->connection_role == CONNECTIONROLE_NONE) { - // This case may be reached if a=setup is not present in the SDP. - RTC_LOG(LS_WARNING) << "Remote offer connection role is NONE, which is " - "a protocol violation"; - role = (options.prefer_passive_role) ? CONNECTIONROLE_PASSIVE - : CONNECTIONROLE_ACTIVE; - } else { - RTC_LOG(LS_ERROR) << "Remote offer connection role is " << role - << " which is a protocol violation"; - RTC_DCHECK_NOTREACHED(); - } - - if (!SetSecurityInfo(desc.get(), role)) { - return NULL; - } + // Special affordance for testing: Answer without DTLS params + // if we are insecure without a certificate, or if we are + // insecure with a non-DTLS offer. + if ((!certificate_ || !offer->identity_fingerprint.get()) && insecure()) { + return desc; + } + if (!offer->identity_fingerprint.get()) { + if (require_transport_attributes) { + // We require DTLS, but the other side didn't offer it. Fail. + RTC_LOG(LS_WARNING) << "Failed to create TransportDescription answer " + "because of incompatible security settings"; + return NULL; } - } else if (require_transport_attributes && secure_ == SEC_REQUIRED) { - // We require DTLS, but the other side didn't offer it. Fail. - RTC_LOG(LS_WARNING) << "Failed to create TransportDescription answer " - "because of incompatible security settings"; + // This may be a bundled section, fingerprint may legitimately be missing. + return desc; + } + // Negotiate security params. + // The offer supports DTLS, so answer with DTLS. + RTC_CHECK(certificate_); + ConnectionRole role = CONNECTIONROLE_NONE; + // If the offer does not constrain the role, go with preference. + if (offer->connection_role == CONNECTIONROLE_ACTPASS) { + role = (options.prefer_passive_role) ? CONNECTIONROLE_PASSIVE + : CONNECTIONROLE_ACTIVE; + } else if (offer->connection_role == CONNECTIONROLE_ACTIVE) { + role = CONNECTIONROLE_PASSIVE; + } else if (offer->connection_role == CONNECTIONROLE_PASSIVE) { + role = CONNECTIONROLE_ACTIVE; + } else if (offer->connection_role == CONNECTIONROLE_NONE) { + // This case may be reached if a=setup is not present in the SDP. + RTC_LOG(LS_WARNING) << "Remote offer connection role is NONE, which is " + "a protocol violation"; + role = (options.prefer_passive_role) ? CONNECTIONROLE_PASSIVE + : CONNECTIONROLE_ACTIVE; + } else { + RTC_LOG(LS_ERROR) << "Remote offer connection role is " << role + << " which is a protocol violation"; + RTC_DCHECK_NOTREACHED(); + return NULL; + } + if (!SetSecurityInfo(desc.get(), role)) { return NULL; } - return desc; } diff --git a/p2p/base/transport_description_factory.h b/p2p/base/transport_description_factory.h index 11352f88b4..bd0cb9078e 100644 --- a/p2p/base/transport_description_factory.h +++ b/p2p/base/transport_description_factory.h @@ -43,15 +43,12 @@ class TransportDescriptionFactory { const webrtc::FieldTrialsView& field_trials); ~TransportDescriptionFactory(); - SecurePolicy secure() const { return secure_; } // The certificate to use when setting up DTLS. const rtc::scoped_refptr& certificate() const { return certificate_; } - // Specifies the transport security policy to use. - void set_secure(SecurePolicy s) { secure_ = s; } - // Specifies the certificate to use (only used when secure != SEC_DISABLED). + // Specifies the certificate to use void set_certificate(rtc::scoped_refptr certificate) { certificate_ = std::move(certificate); } @@ -76,12 +73,18 @@ class TransportDescriptionFactory { IceCredentialsIterator* ice_credentials) const; const webrtc::FieldTrialsView& trials() const { return field_trials_; } + // Functions for disabling encryption - test only! + // In insecure mode, the connection will accept a description without + // fingerprint, and will generate SDP even if certificate is not set. + // If certificate is set, it will accept a description both with and + // without fingerprint, but will generate a description with fingerprint. + bool insecure() const { return insecure_; } + void SetInsecureForTesting() { insecure_ = true; } private: bool SetSecurityInfo(TransportDescription* description, ConnectionRole role) const; - - SecurePolicy secure_; + bool insecure_ = false; rtc::scoped_refptr certificate_; const webrtc::FieldTrialsView& field_trials_; }; diff --git a/p2p/base/transport_description_factory_unittest.cc b/p2p/base/transport_description_factory_unittest.cc index 0da5b7c294..0d38ac6d7b 100644 --- a/p2p/base/transport_description_factory_unittest.cc +++ b/p2p/base/transport_description_factory_unittest.cc @@ -33,6 +33,7 @@ using cricket::TransportDescriptionFactory; using cricket::TransportOptions; using ::testing::Contains; using ::testing::Not; +using ::testing::NotNull; class TransportDescriptionFactoryTest : public ::testing::Test { public: @@ -43,7 +44,11 @@ class TransportDescriptionFactoryTest : public ::testing::Test { cert1_(rtc::RTCCertificate::Create(std::unique_ptr( new rtc::FakeSSLIdentity("User1")))), cert2_(rtc::RTCCertificate::Create(std::unique_ptr( - new rtc::FakeSSLIdentity("User2")))) {} + new rtc::FakeSSLIdentity("User2")))) { + // By default, certificates are supplied. + f1_.set_certificate(cert1_); + f2_.set_certificate(cert2_); + } void CheckDesc(const TransportDescription* desc, absl::string_view opt, @@ -75,7 +80,12 @@ class TransportDescriptionFactoryTest : public ::testing::Test { // in the offer and answer is changed. // If `dtls` is true, the test verifies that the finger print is not changed. void TestIceRestart(bool dtls) { - SetDtls(dtls); + if (dtls) { + f1_.set_certificate(cert1_); + f2_.set_certificate(cert2_); + } else { + SetInsecure(); + } cricket::TransportOptions options; // The initial offer / answer exchange. std::unique_ptr offer = @@ -102,6 +112,8 @@ class TransportDescriptionFactoryTest : public ::testing::Test { void VerifyUfragAndPasswordChanged(bool dtls, const TransportDescription* org_desc, const TransportDescription* restart_desc) { + ASSERT_THAT(org_desc, NotNull()); + ASSERT_THAT(restart_desc, NotNull()); EXPECT_NE(org_desc->ice_pwd, restart_desc->ice_pwd); EXPECT_NE(org_desc->ice_ufrag, restart_desc->ice_ufrag); EXPECT_EQ(static_cast(cricket::ICE_UFRAG_LENGTH), @@ -118,7 +130,9 @@ class TransportDescriptionFactoryTest : public ::testing::Test { } void TestIceRenomination(bool dtls) { - SetDtls(dtls); + if (!dtls) { + SetInsecureNoDtls(); + } cricket::TransportOptions options; // The initial offer / answer exchange. @@ -148,16 +162,16 @@ class TransportDescriptionFactoryTest : public ::testing::Test { } protected: - void SetDtls(bool dtls) { - if (dtls) { - f1_.set_secure(cricket::SEC_ENABLED); - f2_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); - f2_.set_certificate(cert2_); - } else { - f1_.set_secure(cricket::SEC_DISABLED); - f2_.set_secure(cricket::SEC_DISABLED); - } + // This will enable responding to non-DTLS requests. + void SetInsecure() { + f1_.SetInsecureForTesting(); + f2_.SetInsecureForTesting(); + } + // This will disable the ability to respond to DTLS requests. + void SetInsecureNoDtls() { + SetInsecure(); + f1_.set_certificate(nullptr); + f2_.set_certificate(nullptr); } webrtc::test::ScopedKeyValueConfig field_trials_; @@ -169,30 +183,18 @@ class TransportDescriptionFactoryTest : public ::testing::Test { rtc::scoped_refptr cert2_; }; -TEST_F(TransportDescriptionFactoryTest, TestOfferDefault) { - std::unique_ptr desc = - f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); - CheckDesc(desc.get(), "", "", "", ""); -} - TEST_F(TransportDescriptionFactoryTest, TestOfferDtls) { - f1_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); std::string digest_alg; ASSERT_TRUE( cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg)); std::unique_ptr desc = f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); CheckDesc(desc.get(), "", "", "", digest_alg); - // Ensure it also works with SEC_REQUIRED. - f1_.set_secure(cricket::SEC_REQUIRED); - desc = f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); - CheckDesc(desc.get(), "", "", "", digest_alg); } // Test generating an offer with DTLS fails with no identity. TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsWithNoIdentity) { - f1_.set_secure(cricket::SEC_ENABLED); + f1_.set_certificate(nullptr); std::unique_ptr desc = f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); ASSERT_TRUE(desc.get() == NULL); @@ -201,8 +203,6 @@ TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsWithNoIdentity) { // Test updating an offer with DTLS to pick ICE. // The ICE credentials should stay the same in the new offer. TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsReofferDtls) { - f1_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); std::string digest_alg; ASSERT_TRUE( cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg)); @@ -215,19 +215,25 @@ TEST_F(TransportDescriptionFactoryTest, TestOfferDtlsReofferDtls) { } TEST_F(TransportDescriptionFactoryTest, TestAnswerDefault) { + std::string digest_alg; + ASSERT_TRUE( + cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg)); std::unique_ptr offer = f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); ASSERT_TRUE(offer.get() != NULL); std::unique_ptr desc = f2_.CreateAnswer( offer.get(), TransportOptions(), true, NULL, &ice_credentials_); - CheckDesc(desc.get(), "", "", "", ""); + CheckDesc(desc.get(), "", "", "", digest_alg); desc = f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL, &ice_credentials_); - CheckDesc(desc.get(), "", "", "", ""); + CheckDesc(desc.get(), "", "", "", digest_alg); } // Test that we can update an answer properly; ICE credentials shouldn't change. TEST_F(TransportDescriptionFactoryTest, TestReanswer) { + std::string digest_alg; + ASSERT_TRUE( + cert1_->GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg)); std::unique_ptr offer = f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); ASSERT_TRUE(offer.get() != NULL); @@ -237,13 +243,13 @@ TEST_F(TransportDescriptionFactoryTest, TestReanswer) { std::unique_ptr desc = f2_.CreateAnswer( offer.get(), TransportOptions(), true, old_desc.get(), &ice_credentials_); ASSERT_TRUE(desc.get() != NULL); - CheckDesc(desc.get(), "", old_desc->ice_ufrag, old_desc->ice_pwd, ""); + CheckDesc(desc.get(), "", old_desc->ice_ufrag, old_desc->ice_pwd, digest_alg); } // Test that we handle answering an offer with DTLS with no DTLS. TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToNoDtls) { - f1_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); + f2_.SetInsecureForTesting(); + f2_.set_certificate(nullptr); std::unique_ptr offer = f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); ASSERT_TRUE(offer.get() != NULL); @@ -255,28 +261,25 @@ TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToNoDtls) { // Test that we handle answering an offer without DTLS if we have DTLS enabled, // but fail if we require DTLS. TEST_F(TransportDescriptionFactoryTest, TestAnswerNoDtlsToDtls) { - f2_.set_secure(cricket::SEC_ENABLED); - f2_.set_certificate(cert2_); + f1_.SetInsecureForTesting(); + f1_.set_certificate(nullptr); std::unique_ptr offer = f1_.CreateOffer(TransportOptions(), NULL, &ice_credentials_); ASSERT_TRUE(offer.get() != NULL); + // Normal case. std::unique_ptr desc = f2_.CreateAnswer( offer.get(), TransportOptions(), true, NULL, &ice_credentials_); - CheckDesc(desc.get(), "", "", "", ""); - f2_.set_secure(cricket::SEC_REQUIRED); + ASSERT_TRUE(desc.get() == NULL); + // Insecure case. + f2_.SetInsecureForTesting(); desc = f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL, &ice_credentials_); - ASSERT_TRUE(desc.get() == NULL); + CheckDesc(desc.get(), "", "", "", ""); } -// Test that we handle answering an DTLS offer with DTLS, both if we have -// DTLS enabled and required. +// Test that we handle answering an DTLS offer with DTLS, +// even if we don't require DTLS. TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToDtls) { - f1_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); - - f2_.set_secure(cricket::SEC_ENABLED); - f2_.set_certificate(cert2_); // f2_ produces the answer that is being checked in this test, so the // answer must contain fingerprint lines with cert2_'s digest algorithm. std::string digest_alg2; @@ -289,7 +292,8 @@ TEST_F(TransportDescriptionFactoryTest, TestAnswerDtlsToDtls) { std::unique_ptr desc = f2_.CreateAnswer( offer.get(), TransportOptions(), true, NULL, &ice_credentials_); CheckDesc(desc.get(), "", "", "", digest_alg2); - f2_.set_secure(cricket::SEC_REQUIRED); + + f2_.SetInsecureForTesting(); desc = f2_.CreateAnswer(offer.get(), TransportOptions(), true, NULL, &ice_credentials_); CheckDesc(desc.get(), "", "", "", digest_alg2); @@ -325,6 +329,7 @@ TEST_F(TransportDescriptionFactoryTest, AddsTrickleIceOption) { cricket::TransportOptions options; std::unique_ptr offer = f1_.CreateOffer(options, nullptr, &ice_credentials_); + ASSERT_THAT(offer, NotNull()); EXPECT_TRUE(offer->HasOption("trickle")); std::unique_ptr answer = f2_.CreateAnswer(offer.get(), options, true, nullptr, &ice_credentials_); @@ -359,11 +364,6 @@ TEST_F(TransportDescriptionFactoryTest, CreateAnswerIceCredentialsIterator) { } TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsActpassOffer) { - f1_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); - - f2_.set_secure(cricket::SEC_ENABLED); - f2_.set_certificate(cert2_); cricket::TransportOptions options; std::unique_ptr offer = f1_.CreateOffer(options, nullptr, &ice_credentials_); @@ -374,11 +374,6 @@ TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsActpassOffer) { } TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsActiveOffer) { - f1_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); - - f2_.set_secure(cricket::SEC_ENABLED); - f2_.set_certificate(cert2_); cricket::TransportOptions options; std::unique_ptr offer = f1_.CreateOffer(options, nullptr, &ice_credentials_); @@ -390,11 +385,6 @@ TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsActiveOffer) { } TEST_F(TransportDescriptionFactoryTest, CreateAnswerToDtlsPassiveOffer) { - f1_.set_secure(cricket::SEC_ENABLED); - f1_.set_certificate(cert1_); - - f2_.set_secure(cricket::SEC_ENABLED); - f2_.set_certificate(cert2_); cricket::TransportOptions options; std::unique_ptr offer = f1_.CreateOffer(options, nullptr, &ice_credentials_); diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 14971b8af1..6f21d00bc9 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -218,7 +218,6 @@ rtc_source_set("jsep_transport") { ":rtp_transport_internal", ":sctp_transport", ":session_description", - ":srtp_filter", ":srtp_transport", ":transport_stats", "../api:array_view", @@ -573,29 +572,6 @@ rtc_source_set("sctp_utils") { ] absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] } -rtc_source_set("srtp_filter") { - visibility = [ ":*" ] - sources = [ - "srtp_filter.cc", - "srtp_filter.h", - ] - deps = [ - ":session_description", - "../api:array_view", - "../api:libjingle_peerconnection_api", - "../api:sequence_checker", - "../rtc_base:buffer", - "../rtc_base:logging", - "../rtc_base:ssl", - "../rtc_base:zero_memory", - "../rtc_base/third_party/base64", - ] - absl_deps = [ - "//third_party/abseil-cpp/absl/strings", - "//third_party/abseil-cpp/absl/types:optional", - ] -} - rtc_source_set("srtp_session") { visibility = [ ":*" ] sources = [ @@ -2048,7 +2024,6 @@ if (rtc_include_tests && !build_with_chromium) { "rtp_transport_unittest.cc", "sctp_transport_unittest.cc", "session_description_unittest.cc", - "srtp_filter_unittest.cc", "srtp_session_unittest.cc", "srtp_transport_unittest.cc", "test/rtp_transport_test_util.h", @@ -2083,7 +2058,6 @@ if (rtc_include_tests && !build_with_chromium) { ":rtp_transport_internal", ":sctp_transport", ":session_description", - ":srtp_filter", ":srtp_session", ":srtp_transport", ":used_ids", diff --git a/pc/dtls_srtp_transport.h b/pc/dtls_srtp_transport.h index 995809ed4b..654eb2f628 100644 --- a/pc/dtls_srtp_transport.h +++ b/pc/dtls_srtp_transport.h @@ -16,7 +16,6 @@ #include #include "absl/types/optional.h" -#include "api/crypto_params.h" #include "api/dtls_transport_interface.h" #include "api/rtc_error.h" #include "p2p/base/dtls_transport_internal.h" diff --git a/pc/jsep_transport.cc b/pc/jsep_transport.cc index 2398a0ad2d..faff4e8cf4 100644 --- a/pc/jsep_transport.cc +++ b/pc/jsep_transport.cc @@ -36,12 +36,10 @@ JsepTransportDescription::JsepTransportDescription() {} JsepTransportDescription::JsepTransportDescription( bool rtcp_mux_enabled, - const std::vector& cryptos, const std::vector& encrypted_header_extension_ids, int rtp_abs_sendtime_extn_id, const TransportDescription& transport_desc) : rtcp_mux_enabled(rtcp_mux_enabled), - cryptos(cryptos), encrypted_header_extension_ids(encrypted_header_extension_ids), rtp_abs_sendtime_extn_id(rtp_abs_sendtime_extn_id), transport_desc(transport_desc) {} @@ -49,7 +47,6 @@ JsepTransportDescription::JsepTransportDescription( JsepTransportDescription::JsepTransportDescription( const JsepTransportDescription& from) : rtcp_mux_enabled(from.rtcp_mux_enabled), - cryptos(from.cryptos), encrypted_header_extension_ids(from.encrypted_header_extension_ids), rtp_abs_sendtime_extn_id(from.rtp_abs_sendtime_extn_id), transport_desc(from.transport_desc) {} @@ -62,7 +59,6 @@ JsepTransportDescription& JsepTransportDescription::operator=( return *this; } rtcp_mux_enabled = from.rtcp_mux_enabled; - cryptos = from.cryptos; encrypted_header_extension_ids = from.encrypted_header_extension_ids; rtp_abs_sendtime_extn_id = from.rtp_abs_sendtime_extn_id; transport_desc = from.transport_desc; @@ -167,17 +163,7 @@ webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription( "Failed to setup RTCP mux."); } - // If doing SDES, setup the SDES crypto parameters. - if (sdes_transport_) { - RTC_DCHECK(!unencrypted_rtp_transport_); - RTC_DCHECK(!dtls_srtp_transport_); - if (!SetSdes(jsep_description.cryptos, - jsep_description.encrypted_header_extension_ids, type, - ContentSource::CS_LOCAL)) { - return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, - "Failed to setup SDES crypto parameters."); - } - } else if (dtls_srtp_transport_) { + if (dtls_srtp_transport_) { RTC_DCHECK(!unencrypted_rtp_transport_); RTC_DCHECK(!sdes_transport_); dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds( @@ -254,19 +240,7 @@ webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription( "Failed to setup RTCP mux."); } - // If doing SDES, setup the SDES crypto parameters. - if (sdes_transport_) { - RTC_DCHECK(!unencrypted_rtp_transport_); - RTC_DCHECK(!dtls_srtp_transport_); - if (!SetSdes(jsep_description.cryptos, - jsep_description.encrypted_header_extension_ids, type, - ContentSource::CS_REMOTE)) { - return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER, - "Failed to setup SDES crypto parameters."); - } - sdes_transport_->CacheRtpAbsSendTimeHeaderExtension( - jsep_description.rtp_abs_sendtime_extn_id); - } else if (dtls_srtp_transport_) { + if (dtls_srtp_transport_) { RTC_DCHECK(!unencrypted_rtp_transport_); RTC_DCHECK(!sdes_transport_); dtls_srtp_transport_->UpdateSendEncryptedHeaderExtensionIds( @@ -474,51 +448,6 @@ void JsepTransport::ActivateRtcpMux() { rtcp_mux_active_callback_(); } -bool JsepTransport::SetSdes(const std::vector& cryptos, - const std::vector& encrypted_extension_ids, - webrtc::SdpType type, - ContentSource source) { - RTC_DCHECK_RUN_ON(network_thread_); - bool ret = false; - ret = sdes_negotiator_.Process(cryptos, type, source); - if (!ret) { - return ret; - } - - if (source == ContentSource::CS_LOCAL) { - recv_extension_ids_ = encrypted_extension_ids; - } else { - send_extension_ids_ = encrypted_extension_ids; - } - - // If setting an SDES answer succeeded, apply the negotiated parameters - // to the SRTP transport. - if ((type == SdpType::kPrAnswer || type == SdpType::kAnswer) && ret) { - if (sdes_negotiator_.send_crypto_suite() && - sdes_negotiator_.recv_crypto_suite()) { - RTC_DCHECK(send_extension_ids_); - RTC_DCHECK(recv_extension_ids_); - ret = sdes_transport_->SetRtpParams( - *(sdes_negotiator_.send_crypto_suite()), - sdes_negotiator_.send_key().data(), - static_cast(sdes_negotiator_.send_key().size()), - *(send_extension_ids_), *(sdes_negotiator_.recv_crypto_suite()), - sdes_negotiator_.recv_key().data(), - static_cast(sdes_negotiator_.recv_key().size()), - *(recv_extension_ids_)); - } else { - RTC_LOG(LS_INFO) << "No crypto keys are provided for SDES."; - if (type == SdpType::kAnswer) { - // Explicitly reset the `sdes_transport_` if no crypto param is - // provided in the answer. No need to call `ResetParams()` for - // `sdes_negotiator_` because it resets the params inside `SetAnswer`. - sdes_transport_->ResetParams(); - } - } - } - return ret; -} - webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters( SdpType local_description_type) { RTC_DCHECK_RUN_ON(network_thread_); diff --git a/pc/jsep_transport.h b/pc/jsep_transport.h index f2643070a1..af0c797fc8 100644 --- a/pc/jsep_transport.h +++ b/pc/jsep_transport.h @@ -19,7 +19,6 @@ #include "absl/types/optional.h" #include "api/candidate.h" -#include "api/crypto_params.h" #include "api/ice_transport_interface.h" #include "api/jsep.h" #include "api/rtc_error.h" @@ -40,7 +39,6 @@ #include "pc/rtp_transport_internal.h" #include "pc/sctp_transport.h" #include "pc/session_description.h" -#include "pc/srtp_filter.h" #include "pc/srtp_transport.h" #include "pc/transport_stats.h" #include "rtc_base/checks.h" @@ -59,7 +57,6 @@ struct JsepTransportDescription { JsepTransportDescription(); JsepTransportDescription( bool rtcp_mux_enabled, - const std::vector& cryptos, const std::vector& encrypted_header_extension_ids, int rtp_abs_sendtime_extn_id, const TransportDescription& transport_description); @@ -69,7 +66,6 @@ struct JsepTransportDescription { JsepTransportDescription& operator=(const JsepTransportDescription& from); bool rtcp_mux_enabled = true; - std::vector cryptos; std::vector encrypted_header_extension_ids; int rtp_abs_sendtime_extn_id = -1; // TODO(zhihuang): Add the ICE and DTLS related variables and methods from @@ -243,11 +239,6 @@ class JsepTransport { void ActivateRtcpMux() RTC_RUN_ON(network_thread_); - bool SetSdes(const std::vector& cryptos, - const std::vector& encrypted_extension_ids, - webrtc::SdpType type, - ContentSource source); - // Negotiates and sets the DTLS parameters based on the current local and // remote transport description, such as the DTLS role to use, and whether // DTLS should be activated. @@ -310,7 +301,6 @@ class JsepTransport { const rtc::scoped_refptr sctp_transport_; - SrtpFilter sdes_negotiator_ RTC_GUARDED_BY(network_thread_); RtcpMuxFilter rtcp_mux_negotiator_ RTC_GUARDED_BY(network_thread_); // Cache the encrypted header extension IDs for SDES negoitation. diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index ff0abc0c57..9473d962ef 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -951,8 +951,8 @@ JsepTransportController::CreateJsepTransportDescription( : content_desc->rtcp_mux(); return cricket::JsepTransportDescription( - rtcp_mux_enabled, content_desc->cryptos(), encrypted_extension_ids, - rtp_abs_sendtime_extn_id, transport_info.description); + rtcp_mux_enabled, encrypted_extension_ids, rtp_abs_sendtime_extn_id, + transport_info.description); } std::vector JsepTransportController::GetEncryptedHeaderExtensionIds( @@ -1058,12 +1058,6 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( if (transport) { return RTCError::OK(); } - const cricket::MediaContentDescription* content_desc = - content_info.media_description(); - if (certificate_ && !content_desc->cryptos().empty()) { - return RTCError(RTCErrorType::INVALID_PARAMETER, - "SDES and DTLS-SRTP cannot be enabled at the same time."); - } rtc::scoped_refptr ice = CreateIceTransport(content_info.name, /*rtcp=*/false); @@ -1090,10 +1084,6 @@ RTCError JsepTransportController::MaybeCreateJsepTransport( << "Creating UnencryptedRtpTransport, becayse encryption is disabled."; unencrypted_rtp_transport = CreateUnencryptedRtpTransport( content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get()); - } else if (!content_desc->cryptos().empty()) { - sdes_transport = CreateSdesTransport( - content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get()); - RTC_LOG(LS_INFO) << "Creating SdesTransport."; } else { RTC_LOG(LS_INFO) << "Creating DtlsSrtpTransport."; dtls_srtp_transport = CreateDtlsSrtpTransport( diff --git a/pc/jsep_transport_unittest.cc b/pc/jsep_transport_unittest.cc index f057d37a0d..18dd2d8896 100644 --- a/pc/jsep_transport_unittest.cc +++ b/pc/jsep_transport_unittest.cc @@ -48,11 +48,6 @@ static const char kIceUfrag2[] = "U002"; static const char kIcePwd2[] = "TESTIEPWD00000000000002"; static const char kTransportName[] = "Test Transport"; -enum class SrtpMode { - kSdes, - kDtlsSrtp, -}; - struct NegotiateRoleParams { ConnectionRole local_role; ConnectionRole remote_role; @@ -110,8 +105,7 @@ class JsepTransport2Test : public ::testing::Test, public sigslot::has_slots<> { // Create a new JsepTransport with a FakeDtlsTransport and a // FakeIceTransport. - std::unique_ptr CreateJsepTransport2(bool rtcp_mux_enabled, - SrtpMode srtp_mode) { + std::unique_ptr CreateJsepTransport2(bool rtcp_mux_enabled) { auto ice_internal = std::make_unique( kTransportName, ICE_CANDIDATE_COMPONENT_RTP); auto rtp_dtls_transport = @@ -131,19 +125,8 @@ class JsepTransport2Test : public ::testing::Test, public sigslot::has_slots<> { std::unique_ptr unencrypted_rtp_transport; std::unique_ptr sdes_transport; std::unique_ptr dtls_srtp_transport; - switch (srtp_mode) { - case SrtpMode::kSdes: - sdes_transport = CreateSdesTransport(rtp_dtls_transport.get(), - rtcp_dtls_transport.get()); - sdes_transport_ = sdes_transport.get(); - break; - case SrtpMode::kDtlsSrtp: dtls_srtp_transport = CreateDtlsSrtpTransport( rtp_dtls_transport.get(), rtcp_dtls_transport.get()); - break; - default: - RTC_DCHECK_NOTREACHED(); - } auto jsep_transport = std::make_unique( kTransportName, /*local_certificate=*/nullptr, std::move(ice), @@ -205,7 +188,7 @@ class JsepTransport2WithRtcpMux : public JsepTransport2Test, // This test verifies the ICE parameters are properly applied to the transports. TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); JsepTransportDescription jsep_description; jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1); @@ -251,7 +234,7 @@ TEST_P(JsepTransport2WithRtcpMux, SetIceParameters) { // Similarly, test DTLS parameters are properly applied to the transports. TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); // Create certificates. rtc::scoped_refptr local_cert = @@ -302,7 +285,7 @@ TEST_P(JsepTransport2WithRtcpMux, SetDtlsParameters) { // CONNECTIONROLE_PASSIVE, expecting SSL_CLIENT role. TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); // Create certificates. rtc::scoped_refptr local_cert = @@ -354,7 +337,7 @@ TEST_P(JsepTransport2WithRtcpMux, SetDtlsParametersWithPassiveAnswer) { // only starts returning "false" once an ICE restart has been initiated. TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); // Use the same JsepTransportDescription for both offer and answer. JsepTransportDescription description; @@ -399,7 +382,7 @@ TEST_P(JsepTransport2WithRtcpMux, NeedsIceRestart) { TEST_P(JsepTransport2WithRtcpMux, GetStats) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); size_t expected_stats_size = rtcp_mux_enabled ? 1u : 2u; TransportStats stats; @@ -415,7 +398,7 @@ TEST_P(JsepTransport2WithRtcpMux, GetStats) { // certificate matches the fingerprint. TEST_P(JsepTransport2WithRtcpMux, VerifyCertificateFingerprint) { bool rtcp_mux_enabled = GetParam(); - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); EXPECT_FALSE( jsep_transport_->VerifyCertificateFingerprint(nullptr, nullptr).ok()); @@ -489,8 +472,7 @@ TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) { }; for (auto& param : valid_client_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -535,8 +517,7 @@ TEST_P(JsepTransport2WithRtcpMux, ValidDtlsRoleNegotiation) { }; for (auto& param : valid_server_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -607,8 +588,7 @@ TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) { SdpType::kPrAnswer}}; for (auto& param : duplicate_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -658,8 +638,7 @@ TEST_P(JsepTransport2WithRtcpMux, InvalidDtlsRoleNegotiation) { SdpType::kPrAnswer}}; for (auto& param : offerer_without_actpass_params) { - jsep_transport_ = - CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); local_description.transport_desc.connection_role = param.local_role; @@ -705,7 +684,7 @@ TEST_F(JsepTransport2Test, ValidDtlsReofferFromAnswerer) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription local_offer = @@ -752,7 +731,7 @@ TEST_F(JsepTransport2Test, InvalidDtlsReofferFromAnswerer) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription local_offer = @@ -798,7 +777,7 @@ TEST_F(JsepTransport2Test, RemoteOfferWithCurrentNegotiatedDtlsRole) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -843,7 +822,7 @@ TEST_F(JsepTransport2Test, RemoteOfferThatChangesNegotiatedDtlsRole) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -890,7 +869,7 @@ TEST_F(JsepTransport2Test, RemoteOfferThatChangesFingerprintAndDtlsRole) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing2", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -943,7 +922,7 @@ TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) { rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("testing", rtc::KT_ECDSA)); bool rtcp_mux_enabled = true; - jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(rtcp_mux_enabled); jsep_transport_->SetLocalCertificate(certificate); JsepTransportDescription remote_desc = @@ -975,8 +954,7 @@ TEST_F(JsepTransport2Test, DtlsSetupWithLegacyAsAnswerer) { // Tests that when the RTCP mux is successfully negotiated, the RTCP transport // will be destroyed and the SignalRtpMuxActive will be fired. TEST_F(JsepTransport2Test, RtcpMuxNegotiation) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/false); JsepTransportDescription local_desc; local_desc.rtcp_mux_enabled = true; ASSERT_NE(nullptr, jsep_transport_->rtcp_dtls_transport()); @@ -998,8 +976,7 @@ TEST_F(JsepTransport2Test, RtcpMuxNegotiation) { EXPECT_TRUE(signal_rtcp_mux_active_received_); // The remote side doesn't support RTCP-mux. - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/false, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/false); signal_rtcp_mux_active_received_ = false; remote_desc.rtcp_mux_enabled = false; ASSERT_TRUE( @@ -1015,87 +992,10 @@ TEST_F(JsepTransport2Test, RtcpMuxNegotiation) { EXPECT_FALSE(signal_rtcp_mux_active_received_); } -TEST_F(JsepTransport2Test, SdesNegotiation) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes); - ASSERT_TRUE(sdes_transport_); - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); - - JsepTransportDescription offer_desc; - offer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) - .ok()); - - JsepTransportDescription answer_desc; - answer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) - .ok()); - EXPECT_TRUE(sdes_transport_->IsSrtpActive()); -} - -TEST_F(JsepTransport2Test, SdesNegotiationWithEmptyCryptosInAnswer) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes); - ASSERT_TRUE(sdes_transport_); - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); - - JsepTransportDescription offer_desc; - offer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) - .ok()); - - JsepTransportDescription answer_desc; - ASSERT_TRUE( - jsep_transport_ - ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) - .ok()); - // SRTP is not active because the crypto parameter is answer is empty. - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); -} - -TEST_F(JsepTransport2Test, SdesNegotiationWithMismatchedCryptos) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kSdes); - ASSERT_TRUE(sdes_transport_); - EXPECT_FALSE(sdes_transport_->IsSrtpActive()); - - JsepTransportDescription offer_desc; - offer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_32, "inline:" + rtc::CreateRandomString(40), - std::string())); - ASSERT_TRUE( - jsep_transport_ - ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) - .ok()); - - JsepTransportDescription answer_desc; - answer_desc.cryptos.push_back(cricket::CryptoParams( - 1, rtc::kCsAesCm128HmacSha1_80, "inline:" + rtc::CreateRandomString(40), - std::string())); - // Expected to fail because the crypto parameters don't match. - ASSERT_FALSE( - jsep_transport_ - ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) - .ok()); -} - // Tests that the remote candidates can be added to the transports after both // local and remote descriptions are set. TEST_F(JsepTransport2Test, AddRemoteCandidates) { - jsep_transport_ = - CreateJsepTransport2(/*rtcp_mux_enabled=*/true, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true); auto fake_ice_transport = static_cast( jsep_transport_->rtp_dtls_transport()->ice_transport()); @@ -1119,7 +1019,6 @@ TEST_F(JsepTransport2Test, AddRemoteCandidates) { } enum class Scenario { - kSdes, kDtlsBeforeCallerSendOffer, kDtlsBeforeCallerSetAnswer, kDtlsAfterCallerSetAnswer, @@ -1131,9 +1030,9 @@ class JsepTransport2HeaderExtensionTest protected: JsepTransport2HeaderExtensionTest() {} - void CreateJsepTransportPair(SrtpMode mode) { - jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode); - jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true, mode); + void CreateJsepTransportPair() { + jsep_transport1_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true); + jsep_transport2_ = CreateJsepTransport2(/*rtcp_mux_enabled=*/true); auto fake_dtls1 = static_cast(jsep_transport1_->rtp_dtls_transport()); @@ -1145,14 +1044,12 @@ class JsepTransport2HeaderExtensionTest fake_dtls2->fake_ice_transport()->SignalReadPacket.connect( this, &JsepTransport2HeaderExtensionTest::OnReadPacket2); - if (mode == SrtpMode::kDtlsSrtp) { auto cert1 = rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT)); jsep_transport1_->rtp_dtls_transport()->SetLocalCertificate(cert1); auto cert2 = rtc::RTCCertificate::Create( rtc::SSLIdentity::Create("session1", rtc::KT_DEFAULT)); jsep_transport2_->rtp_dtls_transport()->SetLocalCertificate(cert2); - } } void OnReadPacket1(rtc::PacketTransportInternal* transport, @@ -1239,17 +1136,10 @@ class JsepTransport2HeaderExtensionTest TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { Scenario scenario = std::get<0>(GetParam()); bool use_gcm = std::get<1>(GetParam()); - SrtpMode mode = SrtpMode ::kDtlsSrtp; - if (scenario == Scenario::kSdes) { - mode = SrtpMode::kSdes; - } - CreateJsepTransportPair(mode); + CreateJsepTransportPair(); recv_encrypted_headers1_.push_back(kHeaderExtensionIDs[0]); recv_encrypted_headers2_.push_back(kHeaderExtensionIDs[1]); - cricket::CryptoParams sdes_param(1, rtc::kCsAesCm128HmacSha1_80, - "inline:" + rtc::CreateRandomString(40), - std::string()); if (use_gcm) { auto fake_dtls1 = static_cast(jsep_transport1_->rtp_dtls_transport()); @@ -1266,9 +1156,6 @@ TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { JsepTransportDescription offer_desc; offer_desc.encrypted_header_extension_ids = recv_encrypted_headers1_; - if (scenario == Scenario::kSdes) { - offer_desc.cryptos.push_back(sdes_param); - } ASSERT_TRUE( jsep_transport1_ ->SetLocalJsepTransportDescription(offer_desc, SdpType::kOffer) @@ -1280,9 +1167,6 @@ TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { JsepTransportDescription answer_desc; answer_desc.encrypted_header_extension_ids = recv_encrypted_headers2_; - if (scenario == Scenario::kSdes) { - answer_desc.cryptos.push_back(sdes_param); - } ASSERT_TRUE( jsep_transport2_ ->SetLocalJsepTransportDescription(answer_desc, SdpType::kAnswer) @@ -1301,8 +1185,7 @@ TEST_P(JsepTransport2HeaderExtensionTest, EncryptedHeaderExtensionNegotiation) { ->SetRemoteJsepTransportDescription(answer_desc, SdpType::kAnswer) .ok()); - if (scenario == Scenario::kDtlsAfterCallerSetAnswer || - scenario == Scenario::kSdes) { + if (scenario == Scenario::kDtlsAfterCallerSetAnswer) { ConnectTransport(); } EXPECT_TRUE(jsep_transport1_->rtp_transport()->IsSrtpActive()); @@ -1341,7 +1224,6 @@ INSTANTIATE_TEST_SUITE_P( JsepTransport2Test, JsepTransport2HeaderExtensionTest, ::testing::Values( - std::make_tuple(Scenario::kSdes, false), std::make_tuple(Scenario::kDtlsBeforeCallerSendOffer, true), std::make_tuple(Scenario::kDtlsBeforeCallerSetAnswer, true), std::make_tuple(Scenario::kDtlsAfterCallerSetAnswer, true), @@ -1351,8 +1233,7 @@ INSTANTIATE_TEST_SUITE_P( // This test verifies the ICE parameters are properly applied to the transports. TEST_F(JsepTransport2Test, SetIceParametersWithRenomination) { - jsep_transport_ = - CreateJsepTransport2(/* rtcp_mux_enabled= */ true, SrtpMode::kDtlsSrtp); + jsep_transport_ = CreateJsepTransport2(/* rtcp_mux_enabled= */ true); JsepTransportDescription jsep_description; jsep_description.transport_desc = TransportDescription(kIceUfrag1, kIcePwd1); diff --git a/pc/media_session.cc b/pc/media_session.cc index f146562b37..4f63f3088f 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -22,7 +22,6 @@ #include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" -#include "api/crypto_params.h" #include "media/base/codec.h" #include "media/base/media_constants.h" #include "media/base/media_engine.h" @@ -47,19 +46,6 @@ using webrtc::RTCError; using webrtc::RTCErrorType; using webrtc::RtpTransceiverDirection; -const char kInline[] = "inline:"; - -void GetSupportedSdesCryptoSuiteNames( - void (*func)(const webrtc::CryptoOptions&, std::vector*), - const webrtc::CryptoOptions& crypto_options, - std::vector* names) { - std::vector crypto_suites; - func(crypto_options, &crypto_suites); - for (const auto crypto : crypto_suites) { - names->push_back(rtc::SrtpCryptoSuiteToName(crypto)); - } -} - webrtc::RtpExtension RtpExtensionFromCapability( const webrtc::RtpHeaderExtensionCapability& capability) { return webrtc::RtpExtension(capability.uri, @@ -167,140 +153,6 @@ bool IsMediaContentOfType(const ContentInfo* content, MediaType media_type) { return content->media_description()->type() == media_type; } -bool CreateCryptoParams(int tag, - const std::string& cipher, - CryptoParams* crypto_out) { - int key_len; - int salt_len; - if (!rtc::GetSrtpKeyAndSaltLengths(rtc::SrtpCryptoSuiteFromName(cipher), - &key_len, &salt_len)) { - return false; - } - - int master_key_len = key_len + salt_len; - std::string master_key; - if (!rtc::CreateRandomData(master_key_len, &master_key)) { - return false; - } - - RTC_CHECK_EQ(master_key_len, master_key.size()); - std::string key = rtc::Base64::Encode(master_key); - - crypto_out->tag = tag; - crypto_out->crypto_suite = cipher; - crypto_out->key_params = kInline; - crypto_out->key_params += key; - return true; -} - -bool AddCryptoParams(const std::string& crypto_suite, - CryptoParamsVec* cryptos_out) { - int size = static_cast(cryptos_out->size()); - - cryptos_out->resize(size + 1); - return CreateCryptoParams(size, crypto_suite, &cryptos_out->at(size)); -} - -void AddMediaCryptos(const CryptoParamsVec& cryptos, - MediaContentDescription* media) { - for (const CryptoParams& crypto : cryptos) { - media->AddCrypto(crypto); - } -} - -bool CreateMediaCryptos(const std::vector& crypto_suites, - MediaContentDescription* media) { - CryptoParamsVec cryptos; - for (const std::string& crypto_suite : crypto_suites) { - if (!AddCryptoParams(crypto_suite, &cryptos)) { - return false; - } - } - AddMediaCryptos(cryptos, media); - return true; -} - -const CryptoParamsVec* GetCryptos(const ContentInfo* content) { - if (!content || !content->media_description()) { - return nullptr; - } - return &content->media_description()->cryptos(); -} - -bool FindMatchingCrypto(const CryptoParamsVec& cryptos, - const CryptoParams& crypto, - CryptoParams* crypto_out) { - auto it = absl::c_find_if( - cryptos, [&crypto](const CryptoParams& c) { return crypto.Matches(c); }); - if (it == cryptos.end()) { - return false; - } - *crypto_out = *it; - return true; -} - -// For audio, HMAC 32 (if enabled) is prefered over HMAC 80 because of the -// low overhead. -void GetSupportedAudioSdesCryptoSuites( - const webrtc::CryptoOptions& crypto_options, - std::vector* crypto_suites) { - if (crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher) { - crypto_suites->push_back(rtc::kSrtpAes128CmSha1_32); - } - crypto_suites->push_back(rtc::kSrtpAes128CmSha1_80); - if (crypto_options.srtp.enable_gcm_crypto_suites) { - crypto_suites->push_back(rtc::kSrtpAeadAes256Gcm); - crypto_suites->push_back(rtc::kSrtpAeadAes128Gcm); - } -} - -void GetSupportedAudioSdesCryptoSuiteNames( - const webrtc::CryptoOptions& crypto_options, - std::vector* crypto_suite_names) { - GetSupportedSdesCryptoSuiteNames(GetSupportedAudioSdesCryptoSuites, - crypto_options, crypto_suite_names); -} - -void GetSupportedVideoSdesCryptoSuites( - const webrtc::CryptoOptions& crypto_options, - std::vector* crypto_suites) { - crypto_suites->push_back(rtc::kSrtpAes128CmSha1_80); - if (crypto_options.srtp.enable_gcm_crypto_suites) { - crypto_suites->push_back(rtc::kSrtpAeadAes256Gcm); - crypto_suites->push_back(rtc::kSrtpAeadAes128Gcm); - } -} - -void GetSupportedVideoSdesCryptoSuiteNames( - const webrtc::CryptoOptions& crypto_options, - std::vector* crypto_suite_names) { - GetSupportedSdesCryptoSuiteNames(GetSupportedVideoSdesCryptoSuites, - crypto_options, crypto_suite_names); -} - -// Support any GCM cipher (if enabled through options). For video support only -// 80-bit SHA1 HMAC. For audio 32-bit HMAC is tolerated (if enabled) unless -// bundle is enabled because it is low overhead. -// Pick the crypto in the list that is supported. -bool SelectCrypto(const MediaContentDescription* offer, - bool bundle, - const webrtc::CryptoOptions& crypto_options, - CryptoParams* crypto_out) { - bool audio = offer->type() == MEDIA_TYPE_AUDIO; - const CryptoParamsVec& cryptos = offer->cryptos(); - - for (const CryptoParams& crypto : cryptos) { - if ((crypto_options.srtp.enable_gcm_crypto_suites && - rtc::IsGcmCryptoSuiteName(crypto.crypto_suite)) || - rtc::kCsAesCm128HmacSha1_80 == crypto.crypto_suite || - (rtc::kCsAesCm128HmacSha1_32 == crypto.crypto_suite && audio && - !bundle && crypto_options.srtp.enable_aes128_sha1_32_crypto_cipher)) { - return CreateCryptoParams(crypto.tag, crypto.crypto_suite, crypto_out); - } - } - return false; -} - // Finds all StreamParams of all media types and attach them to stream_params. StreamParamsVec GetCurrentStreamParams( const std::vector& active_local_contents) { @@ -496,118 +348,6 @@ bool UpdateTransportInfoForBundle(const ContentGroup& bundle_group, return true; } -// Gets the CryptoParamsVec of the given `content_name` from `sdesc`, and -// sets it to `cryptos`. -bool GetCryptosByName(const SessionDescription* sdesc, - const std::string& content_name, - CryptoParamsVec* cryptos) { - if (!sdesc || !cryptos) { - return false; - } - const ContentInfo* content = sdesc->GetContentByName(content_name); - if (!content || !content->media_description()) { - return false; - } - *cryptos = content->media_description()->cryptos(); - return true; -} - -// Prunes the `target_cryptos` by removing the crypto params (crypto_suite) -// which are not available in `filter`. -void PruneCryptos(const CryptoParamsVec& filter, - CryptoParamsVec* target_cryptos) { - if (!target_cryptos) { - return; - } - - target_cryptos->erase( - std::remove_if(target_cryptos->begin(), target_cryptos->end(), - // Returns true if the `crypto`'s crypto_suite is not - // found in `filter`. - [&filter](const CryptoParams& crypto) { - for (const CryptoParams& entry : filter) { - if (entry.crypto_suite == crypto.crypto_suite) - return false; - } - return true; - }), - target_cryptos->end()); -} - -bool IsRtpContent(SessionDescription* sdesc, const std::string& content_name) { - bool is_rtp = false; - ContentInfo* content = sdesc->GetContentByName(content_name); - if (content && content->media_description()) { - is_rtp = IsRtpProtocol(content->media_description()->protocol()); - } - return is_rtp; -} - -// Updates the crypto parameters of the `sdesc` according to the given -// `bundle_group`. The crypto parameters of all the contents within the -// `bundle_group` should be updated to use the common subset of the -// available cryptos. -bool UpdateCryptoParamsForBundle(const ContentGroup& bundle_group, - SessionDescription* sdesc) { - // The bundle should not be empty. - if (!sdesc || !bundle_group.FirstContentName()) { - return false; - } - - bool common_cryptos_needed = false; - // Get the common cryptos. - const ContentNames& content_names = bundle_group.content_names(); - CryptoParamsVec common_cryptos; - bool first = true; - for (const std::string& content_name : content_names) { - if (!IsRtpContent(sdesc, content_name)) { - continue; - } - // The common cryptos are needed if any of the content does not have DTLS - // enabled. - if (!sdesc->GetTransportInfoByName(content_name)->description.secure()) { - common_cryptos_needed = true; - } - if (first) { - first = false; - // Initial the common_cryptos with the first content in the bundle group. - if (!GetCryptosByName(sdesc, content_name, &common_cryptos)) { - return false; - } - if (common_cryptos.empty()) { - // If there's no crypto params, we should just return. - return true; - } - } else { - CryptoParamsVec cryptos; - if (!GetCryptosByName(sdesc, content_name, &cryptos)) { - return false; - } - PruneCryptos(cryptos, &common_cryptos); - } - } - - if (common_cryptos.empty() && common_cryptos_needed) { - return false; - } - - // Update to use the common cryptos. - for (const std::string& content_name : content_names) { - if (!IsRtpContent(sdesc, content_name)) { - continue; - } - ContentInfo* content = sdesc->GetContentByName(content_name); - if (IsMediaContent(content)) { - MediaContentDescription* media_desc = content->media_description(); - if (!media_desc) { - return false; - } - media_desc->set_cryptos(common_cryptos); - } - } - return true; -} - std::vector GetActiveContents( const SessionDescription& description, const MediaSessionOptions& session_options) { @@ -634,9 +374,6 @@ std::vector GetActiveContents( RTCError CreateContentOffer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, - const SecurePolicy& secure_policy, - const CryptoParamsVec* current_cryptos, - const std::vector& crypto_suites, const RtpHeaderExtensions& rtp_extensions, UniqueRandomIdGenerator* ssrc_generator, StreamParamsVec* current_streams, @@ -665,22 +402,6 @@ RTCError CreateContentOffer( AddSimulcastToMediaDescription(media_description_options, offer); - if (secure_policy != SEC_DISABLED) { - if (current_cryptos) { - AddMediaCryptos(*current_cryptos, offer); - } - if (offer->cryptos().empty()) { - if (!CreateMediaCryptos(crypto_suites, offer)) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create crypto parameters"); - } - } - } - - if (secure_policy == SEC_REQUIRED && offer->cryptos().empty()) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create crypto parameters"); - } return RTCError::OK(); } @@ -688,9 +409,6 @@ RTCError CreateMediaContentOffer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, const std::vector& codecs, - const SecurePolicy& secure_policy, - const CryptoParamsVec* current_cryptos, - const std::vector& crypto_suites, const RtpHeaderExtensions& rtp_extensions, UniqueRandomIdGenerator* ssrc_generator, StreamParamsVec* current_streams, @@ -705,7 +423,6 @@ RTCError CreateMediaContentOffer( } return CreateContentOffer(media_description_options, session_options, - secure_policy, current_cryptos, crypto_suites, rtp_extensions, ssrc_generator, current_streams, offer); } @@ -1343,8 +1060,6 @@ bool CreateMediaContentAnswer( const MediaContentDescription* offer, const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, - const SecurePolicy& sdes_policy, - const CryptoParamsVec* current_cryptos, const RtpHeaderExtensions& local_rtp_extensions, UniqueRandomIdGenerator* ssrc_generator, bool enable_encrypted_rtp_header_extensions, @@ -1385,21 +1100,6 @@ bool CreateMediaContentAnswer( answer->set_remote_estimate(offer->remote_estimate()); - if (sdes_policy != SEC_DISABLED) { - CryptoParams crypto; - if (SelectCrypto(offer, bundle_enabled, session_options.crypto_options, - &crypto)) { - if (current_cryptos) { - FindMatchingCrypto(*current_cryptos, crypto, &crypto); - } - answer->AddCrypto(crypto); - } - } - - if (answer->cryptos().empty() && sdes_policy == SEC_REQUIRED) { - return false; - } - AddSimulcastToMediaDescription(media_description_options, answer); answer->set_direction(NegotiateRtpTransceiverDirection( @@ -1438,9 +1138,7 @@ bool IsMediaProtocolSupported(MediaType type, } void SetMediaProtocol(bool secure_transport, MediaContentDescription* desc) { - if (!desc->cryptos().empty()) - desc->set_protocol(kMediaProtocolSavpf); - else if (secure_transport) + if (secure_transport) desc->set_protocol(kMediaProtocolDtlsSavpf); else desc->set_protocol(kMediaProtocolAvpf); @@ -1462,23 +1160,6 @@ const TransportDescription* GetTransportDescription( return desc; } -// Gets the current DTLS state from the transport description. -bool IsDtlsActive(const ContentInfo* content, - const SessionDescription* current_description) { - if (!content) { - return false; - } - - size_t msection_index = content - ¤t_description->contents()[0]; - - if (current_description->transport_infos().size() <= msection_index) { - return false; - } - - return current_description->transport_infos()[msection_index] - .description.secure(); -} - webrtc::RTCErrorOr GetNegotiatedCodecsForOffer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, @@ -1843,11 +1524,6 @@ MediaSessionDescriptionFactory::CreateOfferOrError( RTCErrorType::INTERNAL_ERROR, "CreateOffer failed to UpdateTransportInfoForBundle"); } - if (!UpdateCryptoParamsForBundle(offer_bundle, offer.get())) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INTERNAL_ERROR, - "CreateOffer failed to UpdateCryptoParamsForBundle."); - } } } @@ -2021,12 +1697,6 @@ MediaSessionDescriptionFactory::CreateAnswerOrError( RTCErrorType::INTERNAL_ERROR, "CreateAnswer failed to UpdateTransportInfoForBundle."); } - - if (!UpdateCryptoParamsForBundle(answer_bundle, answer.get())) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INTERNAL_ERROR, - "CreateAnswer failed to UpdateCryptoParamsForBundle."); - } } } } @@ -2378,19 +2048,6 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer( return error_or_filtered_codecs.MoveError(); } - cricket::SecurePolicy sdes_policy = - IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED - : secure(); - - std::vector crypto_suites; - if (media_description_options.type == MEDIA_TYPE_AUDIO) { - GetSupportedAudioSdesCryptoSuiteNames(session_options.crypto_options, - &crypto_suites); - } else { - GetSupportedVideoSdesCryptoSuiteNames(session_options.crypto_options, - &crypto_suites); - } - std::unique_ptr content_description; if (media_description_options.type == MEDIA_TYPE_AUDIO) { content_description = std::make_unique(); @@ -2400,15 +2057,15 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer( auto error = CreateMediaContentOffer( media_description_options, session_options, - error_or_filtered_codecs.MoveValue(), sdes_policy, - GetCryptos(current_content), crypto_suites, header_extensions, - ssrc_generator(), current_streams, content_description.get(), + error_or_filtered_codecs.MoveValue(), header_extensions, ssrc_generator(), + current_streams, content_description.get(), transport_desc_factory_->trials()); if (!error.ok()) { return error; } - bool secure_transport = transport_desc_factory_->secure() != SEC_DISABLED; + // Insecure transport should only occur in testing. + bool secure_transport = !(transport_desc_factory_->insecure()); SetMediaProtocol(secure_transport, content_description.get()); content_description->set_direction(media_description_options.direction); @@ -2432,15 +2089,9 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForOffer( IceCredentialsIterator* ice_credentials) const { auto data = std::make_unique(); - bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED); + bool secure_transport = true; - cricket::SecurePolicy sdes_policy = - IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED - : secure(); std::vector crypto_suites; - // SDES doesn't make sense for SCTP, so we disable it, and we only - // get SDES crypto suites for RTP-based data channels. - sdes_policy = cricket::SEC_DISABLED; // Unlike SetMediaProtocol below, we need to set the protocol // before we call CreateMediaContentOffer. Otherwise, // CreateMediaContentOffer won't know this is SCTP and will @@ -2450,10 +2101,9 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForOffer( data->set_use_sctpmap(session_options.use_obsolete_sctp_sdp); data->set_max_message_size(kSctpSendBufferSize); - auto error = CreateContentOffer( - media_description_options, session_options, sdes_policy, - GetCryptos(current_content), crypto_suites, RtpHeaderExtensions(), - ssrc_generator(), current_streams, data.get()); + auto error = CreateContentOffer(media_description_options, session_options, + RtpHeaderExtensions(), ssrc_generator(), + current_streams, data.get()); if (!error.ok()) { return error; } @@ -2522,10 +2172,14 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( } else { offer_content_description = offer_content->media_description()->as_video(); } + // If this section is part of a bundle, bundle_transport is non-null. + // Then require_transport_attributes is false - we can handle sections + // without the DTLS parameters. Otherwise, transport attributes MUST + // be present. std::unique_ptr transport = CreateTransportAnswer( media_description_options.mid, offer_description, media_description_options.transport_options, current_description, - bundle_transport != nullptr, ice_credentials); + bundle_transport == nullptr, ice_credentials); if (!transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, @@ -2566,9 +2220,6 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( } else { answer_content = std::make_unique(); } - // Do not require or create SDES cryptos if DTLS is used. - cricket::SecurePolicy sdes_policy = - transport->secure() ? cricket::SEC_DISABLED : secure(); if (!SetCodecsInAnswer( offer_content_description, filtered_codecs, media_description_options, session_options, ssrc_generator(), current_streams, @@ -2578,7 +2229,6 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( } if (!CreateMediaContentAnswer( offer_content_description, media_description_options, session_options, - sdes_policy, GetCryptos(current_content), filtered_rtp_header_extensions(header_extensions), ssrc_generator(), enable_encrypted_rtp_header_extensions_, current_streams, bundle_enabled, answer_content.get())) { @@ -2629,9 +2279,6 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForAnswer( "Failed to create transport answer, data transport is missing"); } - // Do not require or create SDES cryptos if DTLS is used. - cricket::SecurePolicy sdes_policy = - data_transport->secure() ? cricket::SEC_DISABLED : secure(); bool bundle_enabled = offer_description->HasGroup(GROUP_TYPE_BUNDLE) && session_options.bundle_enabled; RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_DATA)); @@ -2656,9 +2303,9 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForAnswer( } if (!CreateMediaContentAnswer( offer_data_description, media_description_options, session_options, - sdes_policy, GetCryptos(current_content), RtpHeaderExtensions(), - ssrc_generator(), enable_encrypted_rtp_header_extensions_, - current_streams, bundle_enabled, data_answer.get())) { + RtpHeaderExtensions(), ssrc_generator(), + enable_encrypted_rtp_header_extensions_, current_streams, + bundle_enabled, data_answer.get())) { LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, "Failed to create answer"); } diff --git a/pc/media_session.h b/pc/media_session.h index 0b3cb67c35..c9fbc4ba63 100644 --- a/pc/media_session.h +++ b/pc/media_session.h @@ -160,8 +160,6 @@ class MediaSessionDescriptionFactory { const VideoCodecs& recv_codecs); RtpHeaderExtensions filtered_rtp_header_extensions( RtpHeaderExtensions extensions) const; - SecurePolicy secure() const { return secure_; } - void set_secure(SecurePolicy s) { secure_ = s; } void set_enable_encrypted_rtp_header_extensions(bool enable) { enable_encrypted_rtp_header_extensions_ = enable; @@ -320,9 +318,6 @@ class MediaSessionDescriptionFactory { webrtc::AlwaysValidPointer const ssrc_generator_; bool enable_encrypted_rtp_header_extensions_ = false; - // TODO(zhihuang): Rename secure_ to sdec_policy_; rename the related getter - // and setter. - SecurePolicy secure_ = SEC_DISABLED; const TransportDescriptionFactory* transport_desc_factory_; }; diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc index ecfb4397bb..d00ad1c90e 100644 --- a/pc/media_session_unittest.cc +++ b/pc/media_session_unittest.cc @@ -25,7 +25,6 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/candidate.h" -#include "api/crypto_params.h" #include "api/rtp_parameters.h" #include "media/base/codec.h" #include "media/base/media_constants.h" @@ -50,10 +49,6 @@ #include "test/gtest.h" #include "test/scoped_key_value_config.h" -#define ASSERT_CRYPTO(cd, s, cs) \ - ASSERT_EQ(s, cd->cryptos().size()); \ - ASSERT_EQ(cs, cd->cryptos()[0].crypto_suite) - namespace cricket { namespace { @@ -254,12 +249,6 @@ const char* kMediaProtocols[] = {"RTP/AVP", "RTP/SAVP", "RTP/AVPF", const char* kMediaProtocolsDtls[] = {"TCP/TLS/RTP/SAVPF", "TCP/TLS/RTP/SAVP", "UDP/TLS/RTP/SAVPF", "UDP/TLS/RTP/SAVP"}; -// SRTP cipher name negotiated by the tests. This must be updated if the -// default changes. -const char* kDefaultSrtpCryptoSuite = kCsAesCm128HmacSha1_80; -const char* kDefaultSrtpCryptoSuiteGcm = kCsAeadAes256Gcm; -const uint8_t kDefaultCryptoSuiteSize = 3U; - // These constants are used to make the code using "AddMediaDescriptionOptions" // more readable. constexpr bool kStopped = true; @@ -388,17 +377,6 @@ MediaSessionOptions CreateAudioMediaSession() { return session_options; } -// prefers GCM SDES crypto suites by removing non-GCM defaults. -void PreferGcmCryptoParameters(CryptoParamsVec* cryptos) { - cryptos->erase( - std::remove_if(cryptos->begin(), cryptos->end(), - [](const CryptoParams& crypto) { - return crypto.crypto_suite != kCsAeadAes256Gcm && - crypto.crypto_suite != kCsAeadAes128Gcm; - }), - cryptos->end()); -} - // TODO(zhihuang): Most of these tests were written while MediaSessionOptions // was designed for Plan B SDP, where only one audio "m=" section and one video // "m=" section could be generated, and ordering couldn't be controlled. Many of @@ -451,18 +429,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { return video_streams; } - bool CompareCryptoParams(const CryptoParamsVec& c1, - const CryptoParamsVec& c2) { - if (c1.size() != c2.size()) - return false; - for (size_t i = 0; i < c1.size(); ++i) - if (c1[i].tag != c2[i].tag || c1[i].crypto_suite != c2[i].crypto_suite || - c1[i].key_params != c2[i].key_params || - c1[i].session_params != c2[i].session_params) - return false; - return true; - } - // Returns true if the transport info contains "renomination" as an // ICE option. bool GetIceRenomination(const TransportInfo* transport_info) { @@ -566,50 +532,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { } } - void TestCryptoWithBundle(bool offer) { - f1_.set_secure(SEC_ENABLED); - MediaSessionOptions options; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &options); - std::unique_ptr ref_desc; - std::unique_ptr desc; - if (offer) { - options.bundle_enabled = false; - ref_desc = f1_.CreateOfferOrError(options, nullptr).MoveValue(); - options.bundle_enabled = true; - desc = f1_.CreateOfferOrError(options, ref_desc.get()).MoveValue(); - } else { - options.bundle_enabled = true; - ref_desc = f1_.CreateOfferOrError(options, nullptr).MoveValue(); - desc = - f1_.CreateAnswerOrError(ref_desc.get(), options, nullptr).MoveValue(); - } - ASSERT_TRUE(desc); - const MediaContentDescription* audio_media_desc = - desc->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - const MediaContentDescription* video_media_desc = - desc->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_TRUE(CompareCryptoParams(audio_media_desc->cryptos(), - video_media_desc->cryptos())); - ASSERT_CRYPTO(audio_media_desc, offer ? kDefaultCryptoSuiteSize : 1U, - kDefaultSrtpCryptoSuite); - - // Verify the selected crypto is one from the reference audio - // media content. - const MediaContentDescription* ref_audio_media_desc = - ref_desc->GetContentDescriptionByName("audio"); - bool found = false; - for (size_t i = 0; i < ref_audio_media_desc->cryptos().size(); ++i) { - if (ref_audio_media_desc->cryptos()[i].Matches( - audio_media_desc->cryptos()[0])) { - found = true; - break; - } - } - EXPECT_TRUE(found); - } - // This test that the audio and video media direction is set to // `expected_direction_in_answer` in an answer if the offer direction is set // to `direction_in_offer` and the answer is willing to both send and receive. @@ -650,59 +572,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { return true; } - void TestVideoGcmCipher(bool gcm_offer, bool gcm_answer) { - MediaSessionOptions offer_opts; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &offer_opts); - offer_opts.crypto_options.srtp.enable_gcm_crypto_suites = gcm_offer; - - MediaSessionOptions answer_opts; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &answer_opts); - answer_opts.crypto_options.srtp.enable_gcm_crypto_suites = gcm_answer; - - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - std::unique_ptr offer = - f1_.CreateOfferOrError(offer_opts, nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - if (gcm_offer && gcm_answer) { - for (ContentInfo& content : offer->contents()) { - auto cryptos = content.media_description()->cryptos(); - PreferGcmCryptoParameters(&cryptos); - content.media_description()->set_cryptos(cryptos); - } - } - std::unique_ptr answer = - f2_.CreateAnswerOrError(offer.get(), answer_opts, nullptr).MoveValue(); - const ContentInfo* ac = answer->GetContentByName("audio"); - const ContentInfo* vc = answer->GetContentByName("video"); - ASSERT_TRUE(ac); - ASSERT_TRUE(vc); - EXPECT_EQ(MediaProtocolType::kRtp, ac->type); - EXPECT_EQ(MediaProtocolType::kRtp, vc->type); - const MediaContentDescription* acd = ac->media_description(); - const MediaContentDescription* vcd = vc->media_description(); - EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); - EXPECT_THAT(acd->codecs(), ElementsAreArray(kAudioCodecsAnswer)); - EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw - EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached - EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - if (gcm_offer && gcm_answer) { - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuiteGcm); - } else { - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - } - EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); - EXPECT_THAT(vcd->codecs(), ElementsAreArray(kVideoCodecsAnswer)); - EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached - EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux - if (gcm_offer && gcm_answer) { - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuiteGcm); - } else { - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); - } - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); - } - void TestTransportSequenceNumberNegotiation( const RtpHeaderExtensions& local, const RtpHeaderExtensions& offered, @@ -768,7 +637,6 @@ class MediaSessionDescriptionFactoryTest : public testing::Test { // Create a typical audio offer, and ensure it matches what we expect. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { - f1_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -783,14 +651,12 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOffer) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached. EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); } // Create an offer with just Opus and RED. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOfferWithJustOpusAndRed) { - f1_.set_secure(SEC_ENABLED); // First, prefer to only use opus and red. std::vector preferences; preferences.push_back( @@ -819,7 +685,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, // Create an offer with RED before Opus, which enables RED with Opus encoding. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOfferWithRedForOpus) { - f1_.set_secure(SEC_ENABLED); // First, prefer to only use opus and red. std::vector preferences; preferences.push_back( @@ -850,7 +715,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioOfferWithRedForOpus) { TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -867,15 +731,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoOffer) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); EXPECT_EQ(f1_.video_sendrecv_codecs(), vcd->codecs()); EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, vcd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(vcd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(vcd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, vcd->protocol()); } // Test creating an offer with bundle where the Codecs have the same dynamic @@ -906,8 +768,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestBundleOfferWithSameCodecPlType) { // after an audio only session has been negotiated. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateUpdatedVideoOfferWithBundle) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); MediaSessionOptions opts; AddMediaDescriptionOptions(MEDIA_TYPE_AUDIO, "audio", RtpTransceiverDirection::kRecvOnly, kActive, @@ -934,10 +794,8 @@ TEST_F(MediaSessionDescriptionFactoryTest, EXPECT_TRUE(vcd); EXPECT_TRUE(acd); - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, vcd->protocol()); } // Create an SCTP data offer with bundle without error. @@ -945,7 +803,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSctpDataOffer) { MediaSessionOptions opts; opts.bundle_enabled = true; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); EXPECT_TRUE(offer.get()); @@ -953,7 +810,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSctpDataOffer) { auto dcd = GetFirstSctpDataContentDescription(offer.get()); ASSERT_TRUE(dcd); // Since this transport is insecure, the protocol should be "SCTP". - EXPECT_EQ(kMediaProtocolSctp, dcd->protocol()); + EXPECT_EQ(kMediaProtocolUdpDtlsSctp, dcd->protocol()); } // Create an SCTP data offer with bundle without error. @@ -961,8 +818,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateSecureSctpDataOffer) { MediaSessionOptions opts; opts.bundle_enabled = true; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); - f1_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); EXPECT_TRUE(offer.get()); @@ -978,19 +833,18 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateImplicitSctpDataOffer) { MediaSessionOptions opts; opts.bundle_enabled = true; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr offer1( f1_.CreateOfferOrError(opts, nullptr).MoveValue()); ASSERT_TRUE(offer1.get()); const ContentInfo* data = offer1->GetContentByName("data"); ASSERT_TRUE(data); - ASSERT_EQ(kMediaProtocolSctp, data->media_description()->protocol()); + ASSERT_EQ(kMediaProtocolUdpDtlsSctp, data->media_description()->protocol()); std::unique_ptr offer2( f1_.CreateOfferOrError(opts, offer1.get()).MoveValue()); data = offer2->GetContentByName("data"); ASSERT_TRUE(data); - EXPECT_EQ(kMediaProtocolSctp, data->media_description()->protocol()); + EXPECT_EQ(kMediaProtocolUdpDtlsSctp, data->media_description()->protocol()); } // Test that if BUNDLE is enabled and all media sections are rejected then the @@ -1289,8 +1143,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateOfferContentOrder) { // Create a typical audio answer, and ensure it matches what we expect. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -1308,24 +1160,16 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswer) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); } // Create a typical audio answer with GCM ciphers enabled, and ensure it // matches what we expect. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); MediaSessionOptions opts = CreateAudioMediaSession(); std::unique_ptr offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); - for (ContentInfo& content : offer->contents()) { - auto cryptos = content.media_description()->cryptos(); - PreferGcmCryptoParameters(&cryptos); - content.media_description()->set_cryptos(cryptos); - } std::unique_ptr answer = f2_.CreateAnswerOrError(offer.get(), opts, nullptr).MoveValue(); const ContentInfo* ac = answer->GetContentByName("audio"); @@ -1339,8 +1183,7 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateAudioAnswerGcm) { EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuiteGcm); - EXPECT_EQ(kMediaProtocolSavpf, acd->protocol()); + EXPECT_EQ(kMediaProtocolDtlsSavpf, acd->protocol()); } // Create an audio answer with no common codecs, and ensure it is rejected. @@ -1369,8 +1212,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { MediaSessionOptions opts; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &opts); - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -1389,31 +1230,11 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswer) { EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // negotiated auto bw EXPECT_EQ(0U, acd->first_ssrc()); // no sender is attached EXPECT_TRUE(acd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); EXPECT_THAT(vcd->codecs(), ElementsAreArray(kVideoCodecsAnswer)); EXPECT_EQ(0U, vcd->first_ssrc()); // no sender is attached EXPECT_TRUE(vcd->rtcp_mux()); // negotiated rtcp-mux - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_EQ(kMediaProtocolSavpf, vcd->protocol()); -} - -// Create a typical video answer with GCM ciphers enabled, and ensure it -// matches what we expect. -TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcm) { - TestVideoGcmCipher(true, true); -} - -// Create a typical video answer with GCM ciphers enabled for the offer only, -// and ensure it matches what we expect. -TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmOffer) { - TestVideoGcmCipher(true, false); -} - -// Create a typical video answer with GCM ciphers enabled for the answer only, -// and ensure it matches what we expect. -TEST_F(MediaSessionDescriptionFactoryTest, TestCreateVideoAnswerGcmAnswer) { - TestVideoGcmCipher(false, true); + EXPECT_EQ(kMediaProtocolDtlsSavpf, vcd->protocol()); } // Create a video answer with no common codecs, and ensure it is rejected. @@ -1512,13 +1333,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerWithoutSctpmap) { // and "TCP/DTLS/SCTP" offers. TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerToDifferentOfferedProtos) { - // Need to enable DTLS offer/answer generation (disabled by default in this - // test). - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - MediaSessionOptions opts; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); std::unique_ptr offer = @@ -1547,13 +1361,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerToOfferWithDefinedMessageSize) { - // Need to enable DTLS offer/answer generation (disabled by default in this - // test). - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - MediaSessionOptions opts; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); std::unique_ptr offer = @@ -1577,13 +1384,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TEST_F(MediaSessionDescriptionFactoryTest, TestCreateDataAnswerToOfferWithZeroMessageSize) { - // Need to enable DTLS offer/answer generation (disabled by default in this - // test). - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - MediaSessionOptions opts; AddDataSection(RtpTransceiverDirection::kSendRecv, &opts); std::unique_ptr offer = @@ -1672,13 +1472,13 @@ TEST_F(MediaSessionDescriptionFactoryTest, CreateAnswerToInactiveOffer) { RtpTransceiverDirection::kInactive); } -// Test that the media protocol is RTP/AVPF if DTLS and SDES are disabled. +// Test that the media protocol is RTP/AVPF if DTLS is disabled. TEST_F(MediaSessionDescriptionFactoryTest, AudioOfferAnswerWithCryptoDisabled) { MediaSessionOptions opts = CreateAudioMediaSession(); - f1_.set_secure(SEC_DISABLED); - f2_.set_secure(SEC_DISABLED); - tdf1_.set_secure(SEC_DISABLED); - tdf2_.set_secure(SEC_DISABLED); + tdf1_.SetInsecureForTesting(); + tdf1_.set_certificate(nullptr); + tdf2_.SetInsecureForTesting(); + tdf2_.set_certificate(nullptr); std::unique_ptr offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); @@ -2510,7 +2310,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { AttachSenderToMediaDescriptionOptions("audio", MEDIA_TYPE_AUDIO, kAudioTrack2, {kMediaStream1}, 1, &opts); - f1_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(opts, nullptr).MoveValue(); @@ -2536,11 +2335,9 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { EXPECT_EQ(kAutoBandwidth, acd->bandwidth()); // default bandwidth (auto) EXPECT_TRUE(acd->rtcp_mux()); // rtcp-mux defaults on - ASSERT_CRYPTO(acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); EXPECT_EQ(MEDIA_TYPE_VIDEO, vcd->type()); EXPECT_EQ(f1_.video_sendrecv_codecs(), vcd->codecs()); - ASSERT_CRYPTO(vcd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); const StreamParamsVec& video_streams = vcd->streams(); ASSERT_EQ(1U, video_streams.size()); @@ -2571,10 +2368,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoOffer) { EXPECT_EQ(acd->codecs(), updated_acd->codecs()); EXPECT_EQ(vcd->type(), updated_vcd->type()); EXPECT_EQ(vcd->codecs(), updated_vcd->codecs()); - ASSERT_CRYPTO(updated_acd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos())); - ASSERT_CRYPTO(updated_vcd, kDefaultCryptoSuiteSize, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos())); const StreamParamsVec& updated_audio_streams = updated_acd->streams(); ASSERT_EQ(2U, updated_audio_streams.size()); @@ -2795,8 +2588,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video", RtpTransceiverDirection::kRecvOnly, kActive, &offer_opts); - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); std::unique_ptr offer = f1_.CreateOfferOrError(offer_opts, nullptr).MoveValue(); @@ -2824,8 +2615,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { ASSERT_TRUE(vc); const MediaContentDescription* acd = ac->media_description(); const MediaContentDescription* vcd = vc->media_description(); - ASSERT_CRYPTO(acd, 1U, kDefaultSrtpCryptoSuite); - ASSERT_CRYPTO(vcd, 1U, kDefaultSrtpCryptoSuite); EXPECT_EQ(MEDIA_TYPE_AUDIO, acd->type()); EXPECT_THAT(acd->codecs(), ElementsAreArray(kAudioCodecsAnswer)); @@ -2870,11 +2659,6 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestCreateMultiStreamVideoAnswer) { const MediaContentDescription* updated_acd = ac->media_description(); const MediaContentDescription* updated_vcd = vc->media_description(); - ASSERT_CRYPTO(updated_acd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(acd->cryptos(), updated_acd->cryptos())); - ASSERT_CRYPTO(updated_vcd, 1U, kDefaultSrtpCryptoSuite); - EXPECT_TRUE(CompareCryptoParams(vcd->cryptos(), updated_vcd->cryptos())); - EXPECT_EQ(acd->type(), updated_acd->type()); EXPECT_EQ(acd->codecs(), updated_acd->codecs()); EXPECT_EQ(vcd->type(), updated_vcd->type()); @@ -3816,54 +3600,9 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestTransportInfo(false, options, true); } -// Create an offer with bundle enabled and verify the crypto parameters are -// the common set of the available cryptos. -TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoWithOfferBundle) { - TestCryptoWithBundle(true); -} - -// Create an answer with bundle enabled and verify the crypto parameters are -// the common set of the available cryptos. -TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoWithAnswerBundle) { - TestCryptoWithBundle(false); -} - -// Verifies that creating answer fails if the offer has UDP/TLS/RTP/SAVPF but -// DTLS is not enabled locally. -TEST_F(MediaSessionDescriptionFactoryTest, - TestOfferDtlsSavpfWithoutDtlsFailed) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_DISABLED); - tdf2_.set_secure(SEC_DISABLED); - - std::unique_ptr offer = - f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - ContentInfo* offer_content = offer->GetContentByName("audio"); - ASSERT_TRUE(offer_content); - MediaContentDescription* offer_audio_desc = - offer_content->media_description(); - offer_audio_desc->set_protocol(kMediaProtocolDtlsSavpf); - - std::unique_ptr answer = - f2_.CreateAnswerOrError(offer.get(), CreateAudioMediaSession(), nullptr) - .MoveValue(); - ASSERT_TRUE(answer); - ContentInfo* answer_content = answer->GetContentByName("audio"); - ASSERT_TRUE(answer_content); - - ASSERT_TRUE(answer_content->rejected); -} - // Offers UDP/TLS/RTP/SAVPF and verifies the answer can be created and contains // UDP/TLS/RTP/SAVPF. TEST_F(MediaSessionDescriptionFactoryTest, TestOfferDtlsSavpfCreateAnswer) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); - std::unique_ptr offer = f1_.CreateOfferOrError(CreateAudioMediaSession(), nullptr).MoveValue(); ASSERT_TRUE(offer.get()); @@ -3887,136 +3626,24 @@ TEST_F(MediaSessionDescriptionFactoryTest, TestOfferDtlsSavpfCreateAnswer) { EXPECT_EQ(kMediaProtocolDtlsSavpf, answer_audio_desc->protocol()); } -// Test that we include both SDES and DTLS in the offer, but only include SDES -// in the answer if DTLS isn't negotiated. -TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoDtls) { - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_DISABLED); - MediaSessionOptions options; - AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &options); - std::unique_ptr offer, answer; - const MediaContentDescription* audio_media_desc; - const MediaContentDescription* video_media_desc; - const TransportDescription* audio_trans_desc; - const TransportDescription* video_trans_desc; - - // Generate an offer with SDES and DTLS support. - offer = f1_.CreateOfferOrError(options, nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - - audio_media_desc = offer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = offer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_EQ(kDefaultCryptoSuiteSize, audio_media_desc->cryptos().size()); - EXPECT_EQ(kDefaultCryptoSuiteSize, video_media_desc->cryptos().size()); - - audio_trans_desc = offer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = offer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_TRUE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_TRUE(video_trans_desc->identity_fingerprint.get()); - - // Generate an answer with only SDES support, since tdf2 has crypto disabled. - answer = f2_.CreateAnswerOrError(offer.get(), options, nullptr).MoveValue(); - ASSERT_TRUE(answer.get()); - - audio_media_desc = answer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = answer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_EQ(1u, audio_media_desc->cryptos().size()); - EXPECT_EQ(1u, video_media_desc->cryptos().size()); - - audio_trans_desc = answer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = answer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_FALSE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_FALSE(video_trans_desc->identity_fingerprint.get()); - - // Enable DTLS; the answer should now only have DTLS support. - tdf2_.set_secure(SEC_ENABLED); - answer = f2_.CreateAnswerOrError(offer.get(), options, nullptr).MoveValue(); - ASSERT_TRUE(answer.get()); - - audio_media_desc = answer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = answer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_TRUE(audio_media_desc->cryptos().empty()); - EXPECT_TRUE(video_media_desc->cryptos().empty()); - EXPECT_EQ(kMediaProtocolSavpf, audio_media_desc->protocol()); - EXPECT_EQ(kMediaProtocolSavpf, video_media_desc->protocol()); - - audio_trans_desc = answer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = answer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_TRUE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_TRUE(video_trans_desc->identity_fingerprint.get()); - - // Try creating offer again. DTLS enabled now, crypto's should be empty - // in new offer. - offer = f1_.CreateOfferOrError(options, offer.get()).MoveValue(); - ASSERT_TRUE(offer.get()); - audio_media_desc = offer->GetContentDescriptionByName("audio"); - ASSERT_TRUE(audio_media_desc); - video_media_desc = offer->GetContentDescriptionByName("video"); - ASSERT_TRUE(video_media_desc); - EXPECT_TRUE(audio_media_desc->cryptos().empty()); - EXPECT_TRUE(video_media_desc->cryptos().empty()); - - audio_trans_desc = offer->GetTransportDescriptionByName("audio"); - ASSERT_TRUE(audio_trans_desc); - video_trans_desc = offer->GetTransportDescriptionByName("video"); - ASSERT_TRUE(video_trans_desc); - ASSERT_TRUE(audio_trans_desc->identity_fingerprint.get()); - ASSERT_TRUE(video_trans_desc->identity_fingerprint.get()); -} - -// Test that an answer can't be created if cryptos are required but the offer is -// unsecure. -TEST_F(MediaSessionDescriptionFactoryTest, TestSecureAnswerToUnsecureOffer) { - MediaSessionOptions options = CreateAudioMediaSession(); - f1_.set_secure(SEC_DISABLED); - tdf1_.set_secure(SEC_DISABLED); - f2_.set_secure(SEC_REQUIRED); - tdf1_.set_secure(SEC_ENABLED); - - std::unique_ptr offer = - f1_.CreateOfferOrError(options, nullptr).MoveValue(); - ASSERT_TRUE(offer.get()); - - auto error = f2_.CreateAnswerOrError(offer.get(), options, nullptr); - EXPECT_FALSE(error.ok()); -} // Test that we accept a DTLS offer without SDES and create an appropriate // answer. TEST_F(MediaSessionDescriptionFactoryTest, TestCryptoOfferDtlsButNotSdes) { + /* TODO(hta): Figure this one out. f1_.set_secure(SEC_DISABLED); f2_.set_secure(SEC_ENABLED); tdf1_.set_secure(SEC_ENABLED); tdf2_.set_secure(SEC_ENABLED); + */ MediaSessionOptions options; AddAudioVideoSections(RtpTransceiverDirection::kRecvOnly, &options); - // Generate an offer with DTLS but without SDES. + // Generate an offer with DTLS std::unique_ptr offer = f1_.CreateOfferOrError(options, nullptr).MoveValue(); ASSERT_TRUE(offer.get()); - const AudioContentDescription* audio_offer = - GetFirstAudioContentDescription(offer.get()); - ASSERT_TRUE(audio_offer->cryptos().empty()); - const VideoContentDescription* video_offer = - GetFirstVideoContentDescription(offer.get()); - ASSERT_TRUE(video_offer->cryptos().empty()); - const TransportDescription* audio_offer_trans_desc = offer->GetTransportDescriptionByName("audio"); ASSERT_TRUE(audio_offer_trans_desc->identity_fingerprint.get()); @@ -4698,14 +4325,10 @@ class MediaProtocolTest : public testing::TestWithParam { MAKE_VECTOR(kAudioCodecs2)); f2_.set_video_codecs(MAKE_VECTOR(kVideoCodecs2), MAKE_VECTOR(kVideoCodecs2)); - f1_.set_secure(SEC_ENABLED); - f2_.set_secure(SEC_ENABLED); tdf1_.set_certificate(rtc::RTCCertificate::Create( std::unique_ptr(new rtc::FakeSSLIdentity("id1")))); tdf2_.set_certificate(rtc::RTCCertificate::Create( std::unique_ptr(new rtc::FakeSSLIdentity("id2")))); - tdf1_.set_secure(SEC_ENABLED); - tdf2_.set_secure(SEC_ENABLED); } protected: @@ -4752,6 +4375,9 @@ INSTANTIATE_TEST_SUITE_P(MediaProtocolDtlsPatternTest, TEST_F(MediaSessionDescriptionFactoryTest, TestSetAudioCodecs) { webrtc::test::ScopedKeyValueConfig field_trials; TransportDescriptionFactory tdf(field_trials); + tdf.set_certificate(rtc::RTCCertificate::Create( + std::unique_ptr(new rtc::FakeSSLIdentity("id")))); + UniqueRandomIdGenerator ssrc_generator; MediaSessionDescriptionFactory sf(nullptr, false, &ssrc_generator, &tdf); std::vector send_codecs = MAKE_VECTOR(kAudioCodecs1); @@ -4821,6 +4447,9 @@ bool CodecsMatch(const std::vector& codecs1, void TestAudioCodecsOffer(RtpTransceiverDirection direction) { webrtc::test::ScopedKeyValueConfig field_trials; TransportDescriptionFactory tdf(field_trials); + tdf.set_certificate(rtc::RTCCertificate::Create( + std::unique_ptr(new rtc::FakeSSLIdentity("id")))); + UniqueRandomIdGenerator ssrc_generator; MediaSessionDescriptionFactory sf(nullptr, false, &ssrc_generator, &tdf); const std::vector send_codecs = MAKE_VECTOR(kAudioCodecs1); @@ -4921,6 +4550,11 @@ void TestAudioCodecsAnswer(RtpTransceiverDirection offer_direction, webrtc::test::ScopedKeyValueConfig field_trials; TransportDescriptionFactory offer_tdf(field_trials); TransportDescriptionFactory answer_tdf(field_trials); + offer_tdf.set_certificate(rtc::RTCCertificate::Create( + std::unique_ptr(new rtc::FakeSSLIdentity("offer_id")))); + answer_tdf.set_certificate( + rtc::RTCCertificate::Create(std::unique_ptr( + new rtc::FakeSSLIdentity("answer_id")))); UniqueRandomIdGenerator ssrc_generator1, ssrc_generator2; MediaSessionDescriptionFactory offer_factory(nullptr, false, &ssrc_generator1, &offer_tdf); diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index e90d1e83f9..76cf13aa18 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -2702,9 +2702,7 @@ void PeerConnection::ReportRemoteIceCandidateAdded( bool PeerConnection::SrtpRequired() const { RTC_DCHECK_RUN_ON(signaling_thread()); - return (dtls_enabled_ || - sdp_handler_->webrtc_session_desc_factory()->SdesPolicy() == - cricket::SEC_REQUIRED); + return dtls_enabled_; } void PeerConnection::OnTransportControllerGatheringState( diff --git a/pc/peer_connection_crypto_unittest.cc b/pc/peer_connection_crypto_unittest.cc index 4274e88b07..1d90e04714 100644 --- a/pc/peer_connection_crypto_unittest.cc +++ b/pc/peer_connection_crypto_unittest.cc @@ -24,7 +24,6 @@ #include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/create_peerconnection_factory.h" #include "api/crypto/crypto_options.h" -#include "api/crypto_params.h" #include "api/jsep.h" #include "api/peer_connection_interface.h" #include "api/scoped_refptr.h" @@ -178,13 +177,6 @@ SdpContentPredicate HaveDtlsFingerprint() { }; } -SdpContentPredicate HaveSdesCryptos() { - return [](const cricket::ContentInfo* content, - const cricket::TransportInfo* transport) { - return !content->media_description()->cryptos().empty(); - }; -} - SdpContentPredicate HaveProtocol(const std::string& protocol) { return [protocol](const cricket::ContentInfo* content, const cricket::TransportInfo* transport) { @@ -192,22 +184,6 @@ SdpContentPredicate HaveProtocol(const std::string& protocol) { }; } -SdpContentPredicate HaveSdesGcmCryptos(size_t num_crypto_suites) { - return [num_crypto_suites](const cricket::ContentInfo* content, - const cricket::TransportInfo* transport) { - const auto& cryptos = content->media_description()->cryptos(); - if (cryptos.size() != num_crypto_suites) { - return false; - } - for (size_t i = 0; i < cryptos.size(); ++i) { - if (cryptos[i].key_params.size() == 67U && - cryptos[i].crypto_suite == "AEAD_AES_256_GCM") - return true; - } - return false; - }; -} - class PeerConnectionCryptoTest : public PeerConnectionCryptoBaseTest, public ::testing::WithParamInterface { @@ -215,20 +191,13 @@ class PeerConnectionCryptoTest PeerConnectionCryptoTest() : PeerConnectionCryptoBaseTest(GetParam()) {} }; -SdpContentMutator RemoveSdesCryptos() { - return [](cricket::ContentInfo* content, cricket::TransportInfo* transport) { - content->media_description()->set_cryptos({}); - }; -} - SdpContentMutator RemoveDtlsFingerprint() { return [](cricket::ContentInfo* content, cricket::TransportInfo* transport) { transport->description.identity_fingerprint.reset(); }; } -// When DTLS is enabled, the SDP offer/answer should have a DTLS fingerprint and -// no SDES cryptos. +// When DTLS is enabled, the SDP offer/answer should have a DTLS fingerprint TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsEnabled) { RTCConfiguration config; auto caller = CreatePeerConnectionWithAudioVideo(config); @@ -238,7 +207,6 @@ TEST_P(PeerConnectionCryptoTest, CorrectCryptoInOfferWhenDtlsEnabled) { ASSERT_FALSE(offer->description()->contents().empty()); EXPECT_TRUE(SdpContentsAll(HaveDtlsFingerprint(), offer->description())); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), offer->description())); EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolDtlsSavpf), offer->description())); } @@ -253,7 +221,6 @@ TEST_P(PeerConnectionCryptoTest, CorrectCryptoInAnswerWhenDtlsEnabled) { ASSERT_FALSE(answer->description()->contents().empty()); EXPECT_TRUE(SdpContentsAll(HaveDtlsFingerprint(), answer->description())); - EXPECT_TRUE(SdpContentsNone(HaveSdesCryptos(), answer->description())); EXPECT_TRUE(SdpContentsAll(HaveProtocol(cricket::kMediaProtocolDtlsSavpf), answer->description())); } diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc index 61794bb0f9..08fb1632d6 100644 --- a/pc/peer_connection_interface_unittest.cc +++ b/pc/peer_connection_interface_unittest.cc @@ -420,29 +420,6 @@ static const char kSdpStringMs1Video1[] = "a=ssrc:4 cname:stream1\r\n" "a=ssrc:4 msid:stream1 videotrack1\r\n"; -static const char kDtlsSdesFallbackSdp[] = - "v=0\r\n" - "o=xxxxxx 7 2 IN IP4 0.0.0.0\r\n" - "s=-\r\n" - "c=IN IP4 0.0.0.0\r\n" - "t=0 0\r\n" - "a=group:BUNDLE audio\r\n" - "a=msid-semantic: WMS\r\n" - "m=audio 1 RTP/SAVPF 0\r\n" - "a=sendrecv\r\n" - "a=rtcp-mux\r\n" - "a=mid:audio\r\n" - "a=ssrc:1 cname:stream1\r\n" - "a=ice-ufrag:e5785931\r\n" - "a=ice-pwd:36fb7878390db89481c1d46daa4278d8\r\n" - "a=rtpmap:0 pcmu/8000\r\n" - "a=fingerprint:sha-1 " - "4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\r\n" - "a=setup:actpass\r\n" - "a=crypto:0 AES_CM_128_HMAC_SHA1_80 " - "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32 " - "dummy_session_params\r\n"; - class RtcEventLogOutputNull final : public RtcEventLogOutput { public: bool IsActive() const override { return true; } @@ -1662,7 +1639,7 @@ TEST_P(PeerConnectionInterfaceTest, AddTrackWithoutStream) { // Test that we can call GetStats() after AddTrack but before connecting // the PeerConnection to a peer. TEST_P(PeerConnectionInterfaceTest, AddTrackBeforeConnecting) { - CreatePeerConnectionWithoutDtls(); + CreatePeerConnection(); rtc::scoped_refptr audio_track( CreateAudioTrack("audio_track")); rtc::scoped_refptr video_track( @@ -1673,7 +1650,7 @@ TEST_P(PeerConnectionInterfaceTest, AddTrackBeforeConnecting) { } TEST_P(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) { - CreatePeerConnectionWithoutDtls(); + CreatePeerConnection(); rtc::scoped_refptr audio_track( CreateAudioTrack("audio_track")); rtc::scoped_refptr video_track( @@ -1695,7 +1672,7 @@ TEST_P(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) { // Don't run under Unified Plan since the stream API is not available. TEST_F(PeerConnectionInterfaceTestPlanB, AttachmentIdIsSetOnAddStream) { - CreatePeerConnectionWithoutDtls(); + CreatePeerConnection(); AddVideoStream(kStreamId1); auto senders = pc_->GetSenders(); ASSERT_EQ(1u, senders.size()); @@ -2130,24 +2107,6 @@ TEST_P(PeerConnectionInterfaceTest, ReceiveFireFoxOffer) { #endif } -// Test that fallback from DTLS to SDES is not supported. -// The fallback was previously supported but was removed to simplify the code -// and because it's non-standard. -TEST_P(PeerConnectionInterfaceTest, DtlsSdesFallbackNotSupported) { - RTCConfiguration rtc_config; - CreatePeerConnection(rtc_config); - // Wait for fake certificate to be generated. Previously, this is what caused - // the "a=crypto" lines to be rejected. - AddAudioTrack("audio_label"); - AddVideoTrack("video_label"); - ASSERT_NE(nullptr, fake_certificate_generator_); - EXPECT_EQ_WAIT(1, fake_certificate_generator_->generated_certificates(), - kTimeout); - std::unique_ptr desc( - CreateSessionDescription(SdpType::kOffer, kDtlsSdesFallbackSdp, nullptr)); - EXPECT_FALSE(DoSetSessionDescription(std::move(desc), /*local=*/false)); -} - // Test that we can create an audio only offer and receive an answer with a // limited set of audio codecs and receive an updated offer with more audio // codecs, where the added codecs are not supported. diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index 19cd9ba45c..d75606ab4e 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -99,7 +99,7 @@ const char kSdpWithoutIceUfragPwd[] = "Called with SDP without ice-ufrag and ice-pwd."; const char kSdpWithoutDtlsFingerprint[] = "Called with SDP without DTLS fingerprint."; -const char kSdpWithoutSdesCrypto[] = "Called with SDP without SDES crypto."; +const char kSdpWithoutCrypto[] = "Called with SDP without crypto setup."; const char kSessionError[] = "Session error code: "; const char kSessionErrorDesc[] = "Session error description: "; @@ -271,7 +271,7 @@ bool MediaSectionsHaveSameCount(const SessionDescription& desc1, const SessionDescription& desc2) { return desc1.contents().size() == desc2.contents().size(); } -// Checks that each non-rejected content has SDES crypto keys or a DTLS +// Checks that each non-rejected content has a DTLS // fingerprint, unless it's in a BUNDLE group, in which case only the // BUNDLE-tag section (first media section/description in the BUNDLE group) // needs a ufrag and pwd. Mismatches, such as replying with a DTLS fingerprint @@ -310,10 +310,7 @@ RTCError VerifyCrypto(const SessionDescription* desc, kSdpWithoutDtlsFingerprint); } } else { - if (media->cryptos().empty()) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, - kSdpWithoutSdesCrypto); - } + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, kSdpWithoutCrypto); } } return RTCError::OK(); @@ -1393,7 +1390,9 @@ void SdpOfferAnswerHandler::Initialize( pc_->trials()); if (pc_->options()->disable_encryption) { - webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED); + RTC_LOG(LS_INFO) + << "Disabling encryption. This should only be done in tests."; + webrtc_session_desc_factory_->SetInsecureForTesting(); } webrtc_session_desc_factory_->set_enable_encrypted_rtp_header_extensions( @@ -3551,8 +3550,7 @@ RTCError SdpOfferAnswerHandler::ValidateSessionDescription( // Verify crypto settings. std::string crypto_error; - if (webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED || - pc_->dtls_enabled()) { + if (pc_->dtls_enabled()) { RTCError crypto_error = VerifyCrypto( sdesc->description(), pc_->dtls_enabled(), bundle_groups_by_mid); if (!crypto_error.ok()) { diff --git a/pc/session_description.h b/pc/session_description.h index 6ef9c316e1..fe037a5786 100644 --- a/pc/session_description.h +++ b/pc/session_description.h @@ -23,7 +23,6 @@ #include "absl/memory/memory.h" #include "absl/strings/string_view.h" -#include "api/crypto_params.h" #include "api/media_types.h" #include "api/rtp_parameters.h" #include "api/rtp_transceiver_direction.h" @@ -43,7 +42,6 @@ namespace cricket { -using CryptoParamsVec = std::vector; using RtpHeaderExtensions = std::vector; // Options to control how session descriptions are generated. @@ -123,12 +121,6 @@ class MediaContentDescription { bandwidth_type_ = bandwidth_type; } - const std::vector& cryptos() const { return cryptos_; } - void AddCrypto(const CryptoParams& params) { cryptos_.push_back(params); } - void set_cryptos(const std::vector& cryptos) { - cryptos_ = cryptos; - } - // List of RTP header extensions. URIs are **NOT** guaranteed to be unique // as they can appear twice when both encrypted and non-encrypted extensions // are present. @@ -268,7 +260,6 @@ class MediaContentDescription { int bandwidth_ = kAutoBandwidth; std::string bandwidth_type_ = kApplicationSpecificBandwidth; - std::vector cryptos_; std::vector rtp_header_extensions_; bool rtp_header_extensions_set_ = false; StreamParamsVec send_streams_; diff --git a/pc/srtp_filter.cc b/pc/srtp_filter.cc deleted file mode 100644 index b8be63cd22..0000000000 --- a/pc/srtp_filter.cc +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2009 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 "pc/srtp_filter.h" - -#include - -#include - -#include "absl/strings/match.h" -#include "rtc_base/logging.h" -#include "rtc_base/ssl_stream_adapter.h" -#include "rtc_base/third_party/base64/base64.h" -#include "rtc_base/zero_memory.h" - -namespace cricket { - -SrtpFilter::SrtpFilter() {} - -SrtpFilter::~SrtpFilter() {} - -bool SrtpFilter::IsActive() const { - return state_ >= ST_ACTIVE; -} - -bool SrtpFilter::Process(const std::vector& cryptos, - webrtc::SdpType type, - ContentSource source) { - bool ret = false; - switch (type) { - case webrtc::SdpType::kOffer: - ret = SetOffer(cryptos, source); - break; - case webrtc::SdpType::kPrAnswer: - ret = SetProvisionalAnswer(cryptos, source); - break; - case webrtc::SdpType::kAnswer: - ret = SetAnswer(cryptos, source); - break; - default: - break; - } - - if (!ret) { - return false; - } - - return true; -} - -bool SrtpFilter::SetOffer(const std::vector& offer_params, - ContentSource source) { - if (!ExpectOffer(source)) { - RTC_LOG(LS_ERROR) << "Wrong state to update SRTP offer"; - return false; - } - return StoreParams(offer_params, source); -} - -bool SrtpFilter::SetAnswer(const std::vector& answer_params, - ContentSource source) { - return DoSetAnswer(answer_params, source, true); -} - -bool SrtpFilter::SetProvisionalAnswer( - const std::vector& answer_params, - ContentSource source) { - return DoSetAnswer(answer_params, source, false); -} - -bool SrtpFilter::ExpectOffer(ContentSource source) { - return ((state_ == ST_INIT) || (state_ == ST_ACTIVE) || - (state_ == ST_SENTOFFER && source == CS_LOCAL) || - (state_ == ST_SENTUPDATEDOFFER && source == CS_LOCAL) || - (state_ == ST_RECEIVEDOFFER && source == CS_REMOTE) || - (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_REMOTE)); -} - -bool SrtpFilter::StoreParams(const std::vector& params, - ContentSource source) { - offer_params_ = params; - if (state_ == ST_INIT) { - state_ = (source == CS_LOCAL) ? ST_SENTOFFER : ST_RECEIVEDOFFER; - } else if (state_ == ST_ACTIVE) { - state_ = - (source == CS_LOCAL) ? ST_SENTUPDATEDOFFER : ST_RECEIVEDUPDATEDOFFER; - } - return true; -} - -bool SrtpFilter::ExpectAnswer(ContentSource source) { - return ((state_ == ST_SENTOFFER && source == CS_REMOTE) || - (state_ == ST_RECEIVEDOFFER && source == CS_LOCAL) || - (state_ == ST_SENTUPDATEDOFFER && source == CS_REMOTE) || - (state_ == ST_RECEIVEDUPDATEDOFFER && source == CS_LOCAL) || - (state_ == ST_SENTPRANSWER_NO_CRYPTO && source == CS_LOCAL) || - (state_ == ST_SENTPRANSWER && source == CS_LOCAL) || - (state_ == ST_RECEIVEDPRANSWER_NO_CRYPTO && source == CS_REMOTE) || - (state_ == ST_RECEIVEDPRANSWER && source == CS_REMOTE)); -} - -bool SrtpFilter::DoSetAnswer(const std::vector& answer_params, - ContentSource source, - bool final) { - if (!ExpectAnswer(source)) { - RTC_LOG(LS_ERROR) << "Invalid state for SRTP answer"; - return false; - } - - // If the answer doesn't requests crypto complete the negotiation of an - // unencrypted session. - // Otherwise, finalize the parameters and apply them. - if (answer_params.empty()) { - if (final) { - return ResetParams(); - } else { - // Need to wait for the final answer to decide if - // we should go to Active state. - state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER_NO_CRYPTO - : ST_RECEIVEDPRANSWER_NO_CRYPTO; - return true; - } - } - CryptoParams selected_params; - if (!NegotiateParams(answer_params, &selected_params)) - return false; - - const CryptoParams& new_send_params = - (source == CS_REMOTE) ? selected_params : answer_params[0]; - const CryptoParams& new_recv_params = - (source == CS_REMOTE) ? answer_params[0] : selected_params; - if (!ApplySendParams(new_send_params) || !ApplyRecvParams(new_recv_params)) { - return false; - } - applied_send_params_ = new_send_params; - applied_recv_params_ = new_recv_params; - - if (final) { - offer_params_.clear(); - state_ = ST_ACTIVE; - } else { - state_ = (source == CS_LOCAL) ? ST_SENTPRANSWER : ST_RECEIVEDPRANSWER; - } - return true; -} - -bool SrtpFilter::NegotiateParams(const std::vector& answer_params, - CryptoParams* selected_params) { - // We're processing an accept. We should have exactly one set of params, - // unless the offer didn't mention crypto, in which case we shouldn't be here. - bool ret = (answer_params.size() == 1U && !offer_params_.empty()); - if (ret) { - // We should find a match between the answer params and the offered params. - std::vector::const_iterator it; - for (it = offer_params_.begin(); it != offer_params_.end(); ++it) { - if (answer_params[0].Matches(*it)) { - break; - } - } - - if (it != offer_params_.end()) { - *selected_params = *it; - } else { - ret = false; - } - } - - if (!ret) { - RTC_LOG(LS_WARNING) << "Invalid parameters in SRTP answer"; - } - return ret; -} - -bool SrtpFilter::ResetParams() { - offer_params_.clear(); - applied_send_params_ = CryptoParams(); - applied_recv_params_ = CryptoParams(); - send_crypto_suite_ = absl::nullopt; - recv_crypto_suite_ = absl::nullopt; - send_key_.Clear(); - recv_key_.Clear(); - state_ = ST_INIT; - return true; -} - -bool SrtpFilter::ApplySendParams(const CryptoParams& send_params) { - if (applied_send_params_.crypto_suite == send_params.crypto_suite && - applied_send_params_.key_params == send_params.key_params) { - RTC_LOG(LS_INFO) << "Applying the same SRTP send parameters again. No-op."; - - // We do not want to reset the ROC if the keys are the same. So just return. - return true; - } - - send_crypto_suite_ = rtc::SrtpCryptoSuiteFromName(send_params.crypto_suite); - if (send_crypto_suite_ == rtc::kSrtpInvalidCryptoSuite) { - RTC_LOG(LS_WARNING) << "Unknown crypto suite(s) received:" - " send crypto_suite " - << send_params.crypto_suite; - return false; - } - - int send_key_len, send_salt_len; - if (!rtc::GetSrtpKeyAndSaltLengths(*send_crypto_suite_, &send_key_len, - &send_salt_len)) { - RTC_LOG(LS_ERROR) << "Could not get lengths for crypto suite(s):" - " send crypto_suite " - << send_params.crypto_suite; - return false; - } - - send_key_ = rtc::ZeroOnFreeBuffer(send_key_len + send_salt_len); - return ParseKeyParams(send_params.key_params, send_key_.data(), - send_key_.size()); -} - -bool SrtpFilter::ApplyRecvParams(const CryptoParams& recv_params) { - if (applied_recv_params_.crypto_suite == recv_params.crypto_suite && - applied_recv_params_.key_params == recv_params.key_params) { - RTC_LOG(LS_INFO) << "Applying the same SRTP recv parameters again. No-op."; - - // We do not want to reset the ROC if the keys are the same. So just return. - return true; - } - - recv_crypto_suite_ = rtc::SrtpCryptoSuiteFromName(recv_params.crypto_suite); - if (recv_crypto_suite_ == rtc::kSrtpInvalidCryptoSuite) { - RTC_LOG(LS_WARNING) << "Unknown crypto suite(s) received:" - " recv crypto_suite " - << recv_params.crypto_suite; - return false; - } - - int recv_key_len, recv_salt_len; - if (!rtc::GetSrtpKeyAndSaltLengths(*recv_crypto_suite_, &recv_key_len, - &recv_salt_len)) { - RTC_LOG(LS_ERROR) << "Could not get lengths for crypto suite(s):" - " recv crypto_suite " - << recv_params.crypto_suite; - return false; - } - - recv_key_ = rtc::ZeroOnFreeBuffer(recv_key_len + recv_salt_len); - return ParseKeyParams(recv_params.key_params, recv_key_.data(), - recv_key_.size()); -} - -bool SrtpFilter::ParseKeyParams(const std::string& key_params, - uint8_t* key, - size_t len) { - // example key_params: "inline:YUJDZGVmZ2hpSktMbW9QUXJzVHVWd3l6MTIzNDU2" - - // Fail if key-method is wrong. - if (!absl::StartsWith(key_params, "inline:")) { - return false; - } - - // Fail if base64 decode fails, or the key is the wrong size. - std::string key_b64(key_params.substr(7)), key_str; - if (!rtc::Base64::Decode(key_b64, rtc::Base64::DO_STRICT, &key_str, - nullptr) || - key_str.size() != len) { - return false; - } - - memcpy(key, key_str.c_str(), len); - // TODO(bugs.webrtc.org/8905): Switch to ZeroOnFreeBuffer for storing - // sensitive data. - rtc::ExplicitZeroMemory(&key_str[0], key_str.size()); - return true; -} - -} // namespace cricket diff --git a/pc/srtp_filter.h b/pc/srtp_filter.h deleted file mode 100644 index 59c43f624b..0000000000 --- a/pc/srtp_filter.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2009 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 PC_SRTP_FILTER_H_ -#define PC_SRTP_FILTER_H_ - -#include -#include - -#include -#include -#include -#include -#include - -#include "absl/types/optional.h" -#include "api/array_view.h" -#include "api/crypto_params.h" -#include "api/jsep.h" -#include "api/sequence_checker.h" -#include "pc/session_description.h" -#include "rtc_base/buffer.h" -#include "rtc_base/ssl_stream_adapter.h" - -// Forward declaration to avoid pulling in libsrtp headers here -struct srtp_event_data_t; -struct srtp_ctx_t_; - -namespace cricket { - -// A helper class used to negotiate SDES crypto params. -// TODO(zhihuang): Find a better name for this class, like "SdesNegotiator". -class SrtpFilter { - public: - enum Mode { PROTECT, UNPROTECT }; - enum Error { - ERROR_NONE, - ERROR_FAIL, - ERROR_AUTH, - ERROR_REPLAY, - }; - - SrtpFilter(); - ~SrtpFilter(); - - // Whether the filter is active (i.e. crypto has been properly negotiated). - bool IsActive() const; - - // Handle the offer/answer negotiation of the crypto parameters internally. - // TODO(zhihuang): Make SetOffer/ProvisionalAnswer/Answer private as helper - // methods once start using Process. - bool Process(const std::vector& cryptos, - webrtc::SdpType type, - ContentSource source); - - // Indicates which crypto algorithms and keys were contained in the offer. - // offer_params should contain a list of available parameters to use, or none, - // if crypto is not desired. This must be called before SetAnswer. - bool SetOffer(const std::vector& offer_params, - ContentSource source); - // Same as SetAnwer. But multiple calls are allowed to SetProvisionalAnswer - // after a call to SetOffer. - bool SetProvisionalAnswer(const std::vector& answer_params, - ContentSource source); - // Indicates which crypto algorithms and keys were contained in the answer. - // answer_params should contain the negotiated parameters, which may be none, - // if crypto was not desired or could not be negotiated (and not required). - // This must be called after SetOffer. If crypto negotiation completes - // successfully, this will advance the filter to the active state. - bool SetAnswer(const std::vector& answer_params, - ContentSource source); - - bool ResetParams(); - - static bool ParseKeyParams(const std::string& params, - uint8_t* key, - size_t len); - - absl::optional send_crypto_suite() { return send_crypto_suite_; } - absl::optional recv_crypto_suite() { return recv_crypto_suite_; } - - rtc::ArrayView send_key() { return send_key_; } - rtc::ArrayView recv_key() { return recv_key_; } - - protected: - bool ExpectOffer(ContentSource source); - - bool StoreParams(const std::vector& params, - ContentSource source); - - bool ExpectAnswer(ContentSource source); - - bool DoSetAnswer(const std::vector& answer_params, - ContentSource source, - bool final); - - bool NegotiateParams(const std::vector& answer_params, - CryptoParams* selected_params); - - private: - bool ApplySendParams(const CryptoParams& send_params); - - bool ApplyRecvParams(const CryptoParams& recv_params); - - enum State { - ST_INIT, // SRTP filter unused. - ST_SENTOFFER, // Offer with SRTP parameters sent. - ST_RECEIVEDOFFER, // Offer with SRTP parameters received. - ST_SENTPRANSWER_NO_CRYPTO, // Sent provisional answer without crypto. - // Received provisional answer without crypto. - ST_RECEIVEDPRANSWER_NO_CRYPTO, - ST_ACTIVE, // Offer and answer set. - // SRTP filter is active but new parameters are offered. - // When the answer is set, the state transitions to ST_ACTIVE or ST_INIT. - ST_SENTUPDATEDOFFER, - // SRTP filter is active but new parameters are received. - // When the answer is set, the state transitions back to ST_ACTIVE. - ST_RECEIVEDUPDATEDOFFER, - // SRTP filter is active but the sent answer is only provisional. - // When the final answer is set, the state transitions to ST_ACTIVE or - // ST_INIT. - ST_SENTPRANSWER, - // SRTP filter is active but the received answer is only provisional. - // When the final answer is set, the state transitions to ST_ACTIVE or - // ST_INIT. - ST_RECEIVEDPRANSWER - }; - State state_ = ST_INIT; - std::vector offer_params_; - CryptoParams applied_send_params_; - CryptoParams applied_recv_params_; - absl::optional send_crypto_suite_; - absl::optional recv_crypto_suite_; - rtc::ZeroOnFreeBuffer send_key_; - rtc::ZeroOnFreeBuffer recv_key_; -}; - -} // namespace cricket - -#endif // PC_SRTP_FILTER_H_ diff --git a/pc/srtp_filter_unittest.cc b/pc/srtp_filter_unittest.cc deleted file mode 100644 index fed023199f..0000000000 --- a/pc/srtp_filter_unittest.cc +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright 2004 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 "pc/srtp_filter.h" - -#include - -#include "api/crypto_params.h" -#include "rtc_base/ssl_stream_adapter.h" -#include "test/gtest.h" - -using cricket::CryptoParams; -using cricket::CS_LOCAL; -using cricket::CS_REMOTE; - -namespace rtc { - -static const char kTestKeyParams1[] = - "inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz"; -static const char kTestKeyParams2[] = - "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR"; -static const char kTestKeyParams3[] = - "inline:1234X19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz"; -static const char kTestKeyParams4[] = - "inline:4567QCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR"; -static const char kTestKeyParamsGcm1[] = - "inline:e166KFlKzJsGW0d5apX+rrI05vxbrvMJEzFI14aTDCa63IRTlLK4iH66uOI="; -static const char kTestKeyParamsGcm2[] = - "inline:6X0oCd55zfz4VgtOwsuqcFq61275PDYN5uwuu3p7ZUHbfUY2FMpdP4m2PEo="; -static const char kTestKeyParamsGcm3[] = - "inline:YKlABGZWMgX32xuMotrG0v0T7G83veegaVzubQ=="; -static const char kTestKeyParamsGcm4[] = - "inline:gJ6tWoUym2v+/F6xjr7xaxiS3QbJJozl3ZD/0A=="; -static const cricket::CryptoParams kTestCryptoParams1(1, - "AES_CM_128_HMAC_SHA1_80", - kTestKeyParams1, - ""); -static const cricket::CryptoParams kTestCryptoParams2(1, - "AES_CM_128_HMAC_SHA1_80", - kTestKeyParams2, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm1(1, - "AEAD_AES_256_GCM", - kTestKeyParamsGcm1, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm2(1, - "AEAD_AES_256_GCM", - kTestKeyParamsGcm2, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm3(1, - "AEAD_AES_128_GCM", - kTestKeyParamsGcm3, - ""); -static const cricket::CryptoParams kTestCryptoParamsGcm4(1, - "AEAD_AES_128_GCM", - kTestKeyParamsGcm4, - ""); - -class SrtpFilterTest : public ::testing::Test { - protected: - SrtpFilterTest() {} - static std::vector MakeVector(const CryptoParams& params) { - std::vector vec; - vec.push_back(params); - return vec; - } - - void TestSetParams(const std::vector& params1, - const std::vector& params2) { - EXPECT_TRUE(f1_.SetOffer(params1, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(params1, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetAnswer(params2, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(params2, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - } - - void VerifyKeysAreEqual(ArrayView key1, - ArrayView key2) { - EXPECT_EQ(key1.size(), key2.size()); - EXPECT_EQ(0, memcmp(key1.data(), key2.data(), key1.size())); - } - - void VerifyCryptoParamsMatch(const std::string& cs1, const std::string& cs2) { - EXPECT_EQ(rtc::SrtpCryptoSuiteFromName(cs1), f1_.send_crypto_suite()); - EXPECT_EQ(rtc::SrtpCryptoSuiteFromName(cs2), f2_.send_crypto_suite()); - VerifyKeysAreEqual(f1_.send_key(), f2_.recv_key()); - VerifyKeysAreEqual(f2_.send_key(), f1_.recv_key()); - } - - cricket::SrtpFilter f1_; - cricket::SrtpFilter f2_; -}; - -// Test that we can set up the session and keys properly. -TEST_F(SrtpFilterTest, TestGoodSetupOneCryptoSuite) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -TEST_F(SrtpFilterTest, TestGoodSetupOneCryptoSuiteGcm) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParamsGcm1), CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParamsGcm2), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -// Test that we can set up things with multiple params. -TEST_F(SrtpFilterTest, TestGoodSetupMultipleCryptoSuites) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - answer[0].tag = 2; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -TEST_F(SrtpFilterTest, TestGoodSetupMultipleCryptoSuitesGcm) { - std::vector offer(MakeVector(kTestCryptoParamsGcm1)); - std::vector answer(MakeVector(kTestCryptoParamsGcm3)); - offer.push_back(kTestCryptoParamsGcm4); - offer[1].tag = 2; - answer[0].tag = 2; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); -} - -// Test that we handle the cases where crypto is not desired. -TEST_F(SrtpFilterTest, TestGoodSetupNoCryptoSuites) { - std::vector offer, answer; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we handle the cases where crypto is not desired by the remote side. -TEST_F(SrtpFilterTest, TestGoodSetupNoAnswerCryptoSuites) { - std::vector answer; - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we call the functions the wrong way. -TEST_F(SrtpFilterTest, TestBadSetup) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we can set offer multiple times from the same source. -TEST_F(SrtpFilterTest, TestGoodSetupMultipleOffers) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_TRUE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); -} -// Test that we can't set offer multiple times from different sources. -TEST_F(SrtpFilterTest, TestBadSetupMultipleOffers) { - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_FALSE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_REMOTE)); - EXPECT_TRUE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); - EXPECT_TRUE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetOffer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f2_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_TRUE(f2_.SetAnswer(MakeVector(kTestCryptoParams2), CS_LOCAL)); -} - -// Test that we fail if we have params in the answer when none were offered. -TEST_F(SrtpFilterTest, TestNoAnswerCryptoSuites) { - std::vector offer; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(MakeVector(kTestCryptoParams2), CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we have too many params in our answer. -TEST_F(SrtpFilterTest, TestMultipleAnswerCryptoSuites) { - std::vector answer(MakeVector(kTestCryptoParams2)); - answer.push_back(kTestCryptoParams2); - answer[1].tag = 2; - answer[1].crypto_suite = kCsAesCm128HmacSha1_32; - EXPECT_TRUE(f1_.SetOffer(MakeVector(kTestCryptoParams1), CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we don't support the crypto suite. -TEST_F(SrtpFilterTest, TestInvalidCryptoSuite) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - offer[0].crypto_suite = answer[0].crypto_suite = "FOO"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we can't agree on a tag. -TEST_F(SrtpFilterTest, TestNoMatchingTag) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - answer[0].tag = 99; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail if we can't agree on a crypto suite. -TEST_F(SrtpFilterTest, TestNoMatchingCryptoSuite) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - answer[0].tag = 2; - answer[0].crypto_suite = "FOO"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys with bad base64 content. -TEST_F(SrtpFilterTest, TestInvalidKeyData) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "inline:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys with the wrong key-method. -TEST_F(SrtpFilterTest, TestWrongKeyMethod) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "outline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys of the wrong length. -TEST_F(SrtpFilterTest, TestKeyTooShort) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtx"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys of the wrong length. -TEST_F(SrtpFilterTest, TestKeyTooLong) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBRABCD"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we fail keys with lifetime or MKI set (since we don't support) -TEST_F(SrtpFilterTest, TestUnsupportedOptions) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - answer[0].key_params = - "inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:4"; - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); -} - -// Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_80. -TEST_F(SrtpFilterTest, TestProtect_AES_CM_128_HMAC_SHA1_80) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); -} - -// Test that we can encrypt/decrypt after negotiating AES_CM_128_HMAC_SHA1_32. -TEST_F(SrtpFilterTest, TestProtect_AES_CM_128_HMAC_SHA1_32) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - answer[0].tag = 2; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_32, kCsAesCm128HmacSha1_32); -} - -// Test that we can change encryption parameters. -TEST_F(SrtpFilterTest, TestChangeParameters) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - // Change the key parameters and crypto_suite. - offer[0].key_params = kTestKeyParams3; - offer[0].crypto_suite = kCsAesCm128HmacSha1_32; - answer[0].key_params = kTestKeyParams4; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f1_.IsActive()); - - // Test that the old keys are valid until the negotiation is complete. - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - // Complete the negotiation and test that we can still understand each other. - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_32, kCsAesCm128HmacSha1_32); -} - -// Test that we can send and receive provisional answers with crypto enabled. -// Also test that we can change the crypto. -TEST_F(SrtpFilterTest, TestProvisionalAnswer) { - std::vector offer(MakeVector(kTestCryptoParams1)); - offer.push_back(kTestCryptoParams1); - offer[1].tag = 2; - offer[1].crypto_suite = kCsAesCm128HmacSha1_32; - std::vector answer(MakeVector(kTestCryptoParams2)); - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetProvisionalAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetProvisionalAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - answer[0].key_params = kTestKeyParams4; - answer[0].tag = 2; - answer[0].crypto_suite = kCsAesCm128HmacSha1_32; - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_32, kCsAesCm128HmacSha1_32); -} - -// Test that a provisional answer doesn't need to contain a crypto. -TEST_F(SrtpFilterTest, TestProvisionalAnswerWithoutCrypto) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer; - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - EXPECT_TRUE(f2_.SetProvisionalAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetProvisionalAnswer(answer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - - answer.push_back(kTestCryptoParams2); - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); -} - -// Test that if we get a new local offer after a provisional answer -// with no crypto, that we are in an inactive state. -TEST_F(SrtpFilterTest, TestLocalOfferAfterProvisionalAnswerWithoutCrypto) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer; - - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_TRUE(f1_.SetProvisionalAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f2_.SetProvisionalAnswer(answer, CS_LOCAL)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - // The calls to set an offer after a provisional answer fail, so the - // state doesn't change. - EXPECT_FALSE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_FALSE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); - - answer.push_back(kTestCryptoParams2); - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); -} - -// Test that we can disable encryption. -TEST_F(SrtpFilterTest, TestDisableEncryption) { - std::vector offer(MakeVector(kTestCryptoParams1)); - std::vector answer(MakeVector(kTestCryptoParams2)); - - TestSetParams(offer, answer); - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - offer.clear(); - answer.clear(); - EXPECT_TRUE(f1_.SetOffer(offer, CS_LOCAL)); - EXPECT_TRUE(f2_.SetOffer(offer, CS_REMOTE)); - EXPECT_TRUE(f1_.IsActive()); - EXPECT_TRUE(f2_.IsActive()); - - // Test that the old keys are valid until the negotiation is complete. - VerifyCryptoParamsMatch(kCsAesCm128HmacSha1_80, kCsAesCm128HmacSha1_80); - - // Complete the negotiation. - EXPECT_TRUE(f2_.SetAnswer(answer, CS_LOCAL)); - EXPECT_TRUE(f1_.SetAnswer(answer, CS_REMOTE)); - - EXPECT_FALSE(f1_.IsActive()); - EXPECT_FALSE(f2_.IsActive()); -} - -} // namespace rtc diff --git a/pc/srtp_transport.h b/pc/srtp_transport.h index 29721f3b68..bad4adc135 100644 --- a/pc/srtp_transport.h +++ b/pc/srtp_transport.h @@ -19,7 +19,6 @@ #include #include "absl/types/optional.h" -#include "api/crypto_params.h" #include "api/field_trials_view.h" #include "api/rtc_error.h" #include "p2p/base/packet_transport_internal.h" @@ -154,8 +153,6 @@ class SrtpTransport : public RtpTransport { std::unique_ptr send_rtcp_session_; std::unique_ptr recv_rtcp_session_; - absl::optional send_params_; - absl::optional recv_params_; absl::optional send_crypto_suite_; absl::optional recv_crypto_suite_; rtc::ZeroOnFreeBuffer send_key_; diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc index a255233ccc..6b63eb8a6e 100644 --- a/pc/webrtc_sdp.cc +++ b/pc/webrtc_sdp.cc @@ -29,7 +29,6 @@ #include "absl/strings/ascii.h" #include "absl/strings/match.h" #include "api/candidate.h" -#include "api/crypto_params.h" #include "api/jsep_ice_candidate.h" #include "api/jsep_session_description.h" #include "api/media_types.h" @@ -74,7 +73,6 @@ using cricket::AudioContentDescription; using cricket::Candidate; using cricket::Candidates; using cricket::ContentInfo; -using cricket::CryptoParams; using cricket::ICE_CANDIDATE_COMPONENT_RTCP; using cricket::ICE_CANDIDATE_COMPONENT_RTP; using cricket::kApplicationSpecificBandwidth; @@ -157,7 +155,6 @@ static const char kSsrcAttributeMsid[] = "msid"; static const char kDefaultMsid[] = "default"; static const char kNoStreamMsid[] = "-"; static const char kAttributeSsrcGroup[] = "ssrc-group"; -static const char kAttributeCrypto[] = "crypto"; static const char kAttributeCandidate[] = "candidate"; static const char kAttributeCandidateTyp[] = "typ"; static const char kAttributeCandidateRaddr[] = "raddr"; @@ -340,9 +337,6 @@ static bool ParseSsrcAttribute(absl::string_view line, static bool ParseSsrcGroupAttribute(absl::string_view line, SsrcGroupVec* ssrc_groups, SdpParseError* error); -static bool ParseCryptoAttribute(absl::string_view line, - MediaContentDescription* media_desc, - SdpParseError* error); static bool ParseRtpmapAttribute(absl::string_view line, const cricket::MediaType media_type, const std::vector& payload_types, @@ -1668,18 +1662,6 @@ void BuildRtpContentAttributes(const MediaContentDescription* media_desc, AddLine(os.str(), message); } - // RFC 4568 - // a=crypto: [] - for (const CryptoParams& crypto_params : media_desc->cryptos()) { - InitAttrLine(kAttributeCrypto, &os); - os << kSdpDelimiterColon << crypto_params.tag << " " - << crypto_params.crypto_suite << " " << crypto_params.key_params; - if (!crypto_params.session_params.empty()) { - os << " " << crypto_params.session_params; - } - AddLine(os.str(), message); - } - // RFC 4566 // a=rtpmap: / // [/] @@ -3217,10 +3199,6 @@ bool ParseContent(absl::string_view message, if (!ParseSsrcAttribute(*line, &ssrc_infos, msid_signaling, error)) { return false; } - } else if (HasAttribute(*line, kAttributeCrypto)) { - if (!ParseCryptoAttribute(*line, media_desc, error)) { - return false; - } } else if (HasAttribute(*line, kAttributeRtpmap)) { if (!ParseRtpmapAttribute(*line, media_type, payload_types, media_desc, error)) { @@ -3548,37 +3526,6 @@ bool ParseSsrcGroupAttribute(absl::string_view line, return true; } -bool ParseCryptoAttribute(absl::string_view line, - MediaContentDescription* media_desc, - SdpParseError* error) { - std::vector fields = - rtc::split(line.substr(kLinePrefixLength), kSdpDelimiterSpaceChar); - // RFC 4568 - // a=crypto: [] - const size_t expected_min_fields = 3; - if (fields.size() < expected_min_fields) { - return ParseFailedExpectMinFieldNum(line, expected_min_fields, error); - } - std::string tag_value; - if (!GetValue(fields[0], kAttributeCrypto, &tag_value, error)) { - return false; - } - int tag = 0; - if (!GetValueFromString(line, tag_value, &tag, error)) { - return false; - } - const absl::string_view crypto_suite = fields[1]; - const absl::string_view key_params = fields[2]; - absl::string_view session_params; - if (fields.size() > 3) { - session_params = fields[3]; - } - - media_desc->AddCrypto( - CryptoParams(tag, crypto_suite, key_params, session_params)); - return true; -} - // Updates or creates a new codec entry in the audio description with according // to `name`, `clockrate`, `bitrate`, and `channels`. void UpdateCodec(int payload_type, diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc index 382a4967d5..6811381bb7 100644 --- a/pc/webrtc_sdp_unittest.cc +++ b/pc/webrtc_sdp_unittest.cc @@ -25,7 +25,6 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" -#include "api/crypto_params.h" #include "api/jsep_session_description.h" #include "api/media_types.h" #include "api/rtp_parameters.h" @@ -59,7 +58,6 @@ using cricket::AudioContentDescription; using cricket::Candidate; using cricket::ContentGroup; using cricket::ContentInfo; -using cricket::CryptoParams; using cricket::ICE_CANDIDATE_COMPONENT_RTCP; using cricket::ICE_CANDIDATE_COMPONENT_RTP; using cricket::kFecSsrcGroupSemantics; @@ -1343,20 +1341,6 @@ class WebRtcSdpTest : public ::testing::Test { // rtcp_reduced_size EXPECT_EQ(cd1->rtcp_reduced_size(), cd2->rtcp_reduced_size()); - // cryptos - EXPECT_EQ(cd1->cryptos().size(), cd2->cryptos().size()); - if (cd1->cryptos().size() != cd2->cryptos().size()) { - ADD_FAILURE(); - return; - } - for (size_t i = 0; i < cd1->cryptos().size(); ++i) { - const CryptoParams c1 = cd1->cryptos().at(i); - const CryptoParams c2 = cd2->cryptos().at(i); - EXPECT_TRUE(c1.Matches(c2)); - EXPECT_EQ(c1.key_params, c2.key_params); - EXPECT_EQ(c1.session_params, c2.session_params); - } - // protocol // Use an equivalence class here, for old and new versions of the // protocol description. @@ -1631,11 +1615,6 @@ class WebRtcSdpTest : public ::testing::Test { absl::WrapUnique(video_desc_)); } - void RemoveCryptos() { - audio_desc_->set_cryptos(std::vector()); - video_desc_->set_cryptos(std::vector()); - } - // Removes everything in StreamParams from the session description that is // used for a=ssrc lines. void RemoveSsrcSignalingFromStreamParams() { diff --git a/pc/webrtc_session_description_factory.cc b/pc/webrtc_session_description_factory.cc index 42a8da3e70..9919260aa3 100644 --- a/pc/webrtc_session_description_factory.cc +++ b/pc/webrtc_session_description_factory.cc @@ -128,13 +128,10 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( RTC_DCHECK(signaling_thread_); if (!dtls_enabled) { - SetSdesPolicy(cricket::SEC_REQUIRED); - RTC_LOG(LS_VERBOSE) << "DTLS-SRTP disabled."; + RTC_LOG(LS_INFO) << "DTLS-SRTP disabled"; + transport_desc_factory_.SetInsecureForTesting(); return; } - - // SRTP-SDES is disabled if DTLS is on. - SetSdesPolicy(cricket::SEC_DISABLED); if (certificate) { // Use `certificate`. certificate_request_state_ = CERTIFICATE_WAITING; @@ -142,31 +139,32 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( RTC_LOG(LS_VERBOSE) << "DTLS-SRTP enabled; has certificate parameter."; RTC_LOG(LS_INFO) << "Using certificate supplied to the constructor."; SetCertificate(certificate); - } else { - // Generate certificate. - certificate_request_state_ = CERTIFICATE_WAITING; - - auto callback = [weak_ptr = weak_factory_.GetWeakPtr()]( - rtc::scoped_refptr certificate) { - if (!weak_ptr) { - return; - } - if (certificate) { - weak_ptr->SetCertificate(std::move(certificate)); - } else { - weak_ptr->OnCertificateRequestFailed(); - } - }; - - rtc::KeyParams key_params = rtc::KeyParams(); - RTC_LOG(LS_VERBOSE) - << "DTLS-SRTP enabled; sending DTLS identity request (key type: " - << key_params.type() << ")."; - - // Request certificate. This happens asynchronously on a different thread. - cert_generator_->GenerateCertificateAsync(key_params, absl::nullopt, - std::move(callback)); + return; } + // Generate certificate. + RTC_DCHECK(cert_generator_); + certificate_request_state_ = CERTIFICATE_WAITING; + + auto callback = [weak_ptr = weak_factory_.GetWeakPtr()]( + rtc::scoped_refptr certificate) { + if (!weak_ptr) { + return; + } + if (certificate) { + weak_ptr->SetCertificate(std::move(certificate)); + } else { + weak_ptr->OnCertificateRequestFailed(); + } + }; + + rtc::KeyParams key_params = rtc::KeyParams(); + RTC_LOG(LS_VERBOSE) + << "DTLS-SRTP enabled; sending DTLS identity request (key type: " + << key_params.type() << ")."; + + // Request certificate. This happens asynchronously on a different thread. + cert_generator_->GenerateCertificateAsync(key_params, absl::nullopt, + std::move(callback)); } WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { @@ -258,15 +256,6 @@ void WebRtcSessionDescriptionFactory::CreateAnswer( } } -void WebRtcSessionDescriptionFactory::SetSdesPolicy( - cricket::SecurePolicy secure_policy) { - session_desc_factory_.set_secure(secure_policy); -} - -cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { - return session_desc_factory_.secure(); -} - void WebRtcSessionDescriptionFactory::InternalCreateOffer( CreateSessionDescriptionRequest request) { if (sdp_info_->local_description()) { @@ -450,7 +439,6 @@ void WebRtcSessionDescriptionFactory::SetCertificate( on_certificate_ready_(certificate); transport_desc_factory_.set_certificate(std::move(certificate)); - transport_desc_factory_.set_secure(cricket::SEC_ENABLED); while (!create_session_description_requests_.empty()) { if (create_session_description_requests_.front().type == @@ -462,4 +450,5 @@ void WebRtcSessionDescriptionFactory::SetCertificate( create_session_description_requests_.pop(); } } + } // namespace webrtc diff --git a/pc/webrtc_session_description_factory.h b/pc/webrtc_session_description_factory.h index 22ead41d9b..eed922eda7 100644 --- a/pc/webrtc_session_description_factory.h +++ b/pc/webrtc_session_description_factory.h @@ -73,9 +73,6 @@ class WebRtcSessionDescriptionFactory { void CreateAnswer(CreateSessionDescriptionObserver* observer, const cricket::MediaSessionOptions& session_options); - void SetSdesPolicy(cricket::SecurePolicy secure_policy); - cricket::SecurePolicy SdesPolicy() const; - void set_enable_encrypted_rtp_header_extensions(bool enable) { session_desc_factory_.set_enable_encrypted_rtp_header_extensions(enable); } @@ -88,6 +85,9 @@ class WebRtcSessionDescriptionFactory { bool waiting_for_certificate_for_testing() const { return certificate_request_state_ == CERTIFICATE_WAITING; } + void SetInsecureForTesting() { + transport_desc_factory_.SetInsecureForTesting(); + } private: enum CertificateRequestState { @@ -144,6 +144,7 @@ class WebRtcSessionDescriptionFactory { std::function&)> on_certificate_ready_; + rtc::WeakPtrFactory weak_factory_{this}; }; } // namespace webrtc diff --git a/test/peer_scenario/tests/unsignaled_stream_test.cc b/test/peer_scenario/tests/unsignaled_stream_test.cc index 4f478b4b2a..dced274e68 100644 --- a/test/peer_scenario/tests/unsignaled_stream_test.cc +++ b/test/peer_scenario/tests/unsignaled_stream_test.cc @@ -98,7 +98,6 @@ TEST_P(UnsignaledStreamTest, ReplacesUnsignaledStreamOnCompletedSignaling) { PeerScenarioClient::Config config = PeerScenarioClient::Config(); // Disable encryption so that we can inject a fake early media packet without // triggering srtp failures. - config.disable_encryption = true; auto* caller = s.CreateClient(config); auto* callee = s.CreateClient(config); From 6432970fe957f37685aaa4a6bad21c0484e0e3e2 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Tue, 6 Feb 2024 15:44:02 +0100 Subject: [PATCH 102/170] Make it possible to set spatial layer bitrates explicitly Bug: webrtc:14852 Change-Id: Ie41d4223d0d5aef5a79f7e6067f0855f022ed428 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335361 Auto-Submit: Sergey Silkin Commit-Queue: Sergey Silkin Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41698} --- test/video_codec_tester.cc | 155 +++++++++++++++++++--------- test/video_codec_tester_unittest.cc | 132 +++++++++++++++++++++++ 2 files changed, 237 insertions(+), 50 deletions(-) diff --git a/test/video_codec_tester.cc b/test/video_codec_tester.cc index 37ae712f77..e7674dfdab 100644 --- a/test/video_codec_tester.cc +++ b/test/video_codec_tester.cc @@ -1111,8 +1111,6 @@ class Encoder : public EncodedImageCallback { int result = encoder_->InitEncode(&vc, ves); RTC_CHECK(result == WEBRTC_VIDEO_CODEC_OK); - - SetRates(es); } void SetRates(const EncodingSettings& es) { @@ -1261,6 +1259,29 @@ void ConfigureSimulcast(VideoCodec* vc) { } } +void SetDefaultCodecSpecificSettings(VideoCodec* vc, int num_temporal_layers) { + switch (vc->codecType) { + case kVideoCodecVP8: + *(vc->VP8()) = VideoEncoder::GetDefaultVp8Settings(); + vc->VP8()->SetNumberOfTemporalLayers(num_temporal_layers); + break; + case kVideoCodecVP9: { + *(vc->VP9()) = VideoEncoder::GetDefaultVp9Settings(); + vc->VP9()->SetNumberOfTemporalLayers(num_temporal_layers); + } break; + case kVideoCodecH264: { + *(vc->H264()) = VideoEncoder::GetDefaultH264Settings(); + vc->H264()->SetNumberOfTemporalLayers(num_temporal_layers); + } break; + case kVideoCodecAV1: + case kVideoCodecH265: + break; + case kVideoCodecGeneric: + case kVideoCodecMultiplex: + RTC_CHECK_NOTREACHED(); + } +} + std::tuple, ScalabilityMode> SplitBitrateAndUpdateScalabilityMode(std::string codec_type, ScalabilityMode scalability_mode, @@ -1272,11 +1293,11 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, int num_temporal_layers = ScalabilityModeToNumTemporalLayers(scalability_mode); - if (bitrates_kbps.size() > 1 || - (num_spatial_layers == 1 && num_temporal_layers == 1)) { - RTC_CHECK(bitrates_kbps.size() == - static_cast(num_spatial_layers * num_temporal_layers)) - << "bitrates must be provided for all layers"; + int num_bitrates = static_cast(bitrates_kbps.size()); + RTC_CHECK(num_bitrates == 1 || num_bitrates == num_spatial_layers || + num_bitrates == num_spatial_layers * num_temporal_layers); + + if (num_bitrates == num_spatial_layers * num_temporal_layers) { std::vector bitrates; for (const auto& bitrate_kbps : bitrates_kbps) { bitrates.push_back(DataRate::KilobitsPerSec(bitrate_kbps)); @@ -1284,59 +1305,93 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, return std::make_tuple(bitrates, scalability_mode); } + int total_bitrate_kbps = + std::accumulate(bitrates_kbps.begin(), bitrates_kbps.end(), 0); + VideoCodec vc; vc.codecType = PayloadStringToCodecType(codec_type); vc.width = width; vc.height = height; - vc.startBitrate = bitrates_kbps.front(); - vc.maxBitrate = bitrates_kbps.front(); + vc.startBitrate = total_bitrate_kbps; + vc.maxBitrate = total_bitrate_kbps; vc.minBitrate = 0; vc.maxFramerate = static_cast(framerate_fps); vc.numberOfSimulcastStreams = 0; vc.mode = webrtc::VideoCodecMode::kRealtimeVideo; vc.SetScalabilityMode(scalability_mode); + SetDefaultCodecSpecificSettings(&vc, num_temporal_layers); - switch (vc.codecType) { - case kVideoCodecVP8: - // TODO(webrtc:14852): Configure simulcast. - *(vc.VP8()) = VideoEncoder::GetDefaultVp8Settings(); - vc.VP8()->SetNumberOfTemporalLayers(num_temporal_layers); - ConfigureSimulcast(&vc); - break; - case kVideoCodecVP9: { - *(vc.VP9()) = VideoEncoder::GetDefaultVp9Settings(); - vc.VP9()->SetNumberOfTemporalLayers(num_temporal_layers); - const std::vector spatialLayers = GetVp9SvcConfig(vc); - for (size_t i = 0; i < spatialLayers.size(); ++i) { - vc.spatialLayers[i] = spatialLayers[i]; - vc.spatialLayers[i].active = true; - } - } break; - case kVideoCodecAV1: { - bool result = - SetAv1SvcConfig(vc, num_spatial_layers, num_temporal_layers); - RTC_CHECK(result) << "SetAv1SvcConfig failed"; - } break; - case kVideoCodecH264: { - *(vc.H264()) = VideoEncoder::GetDefaultH264Settings(); - vc.H264()->SetNumberOfTemporalLayers(num_temporal_layers); - ConfigureSimulcast(&vc); - } break; - case kVideoCodecH265: - break; - case kVideoCodecGeneric: - case kVideoCodecMultiplex: - RTC_CHECK_NOTREACHED(); - } + if (num_bitrates == num_spatial_layers) { + switch (vc.codecType) { + case kVideoCodecVP8: + case kVideoCodecH264: + case kVideoCodecH265: + vc.numberOfSimulcastStreams = num_spatial_layers; + for (int sidx = 0; sidx < num_spatial_layers; ++sidx) { + SimulcastStream* ss = &vc.simulcastStream[sidx]; + ss->width = width >> (num_spatial_layers - sidx - 1); + ss->height = height >> (num_spatial_layers - sidx - 1); + ss->maxFramerate = vc.maxFramerate; + ss->numberOfTemporalLayers = num_temporal_layers; + ss->maxBitrate = bitrates_kbps[sidx]; + ss->targetBitrate = bitrates_kbps[sidx]; + ss->minBitrate = 0; + ss->qpMax = 0; + ss->active = true; + } + break; + case kVideoCodecVP9: + case kVideoCodecAV1: + for (int sidx = num_spatial_layers - 1; sidx >= 0; --sidx) { + SpatialLayer* ss = &vc.spatialLayers[sidx]; + ss->width = width >> (num_spatial_layers - sidx - 1); + ss->height = height >> (num_spatial_layers - sidx - 1); + ss->maxFramerate = vc.maxFramerate; + ss->numberOfTemporalLayers = num_temporal_layers; + ss->maxBitrate = bitrates_kbps[sidx]; + ss->targetBitrate = bitrates_kbps[sidx]; + ss->minBitrate = 0; + ss->qpMax = 0; + ss->active = true; + } + break; + case kVideoCodecGeneric: + case kVideoCodecMultiplex: + RTC_CHECK_NOTREACHED(); + } + } else { + switch (vc.codecType) { + case kVideoCodecVP8: + case kVideoCodecH264: + case kVideoCodecH265: + ConfigureSimulcast(&vc); + break; + case kVideoCodecVP9: { + const std::vector spatialLayers = GetVp9SvcConfig(vc); + for (size_t i = 0; i < spatialLayers.size(); ++i) { + vc.spatialLayers[i] = spatialLayers[i]; + vc.spatialLayers[i].active = true; + } + } break; + case kVideoCodecAV1: { + bool result = + SetAv1SvcConfig(vc, num_spatial_layers, num_temporal_layers); + RTC_CHECK(result) << "SetAv1SvcConfig failed"; + } break; + case kVideoCodecGeneric: + case kVideoCodecMultiplex: + RTC_CHECK_NOTREACHED(); + } - if (*vc.GetScalabilityMode() != scalability_mode) { - RTC_LOG(LS_WARNING) << "Scalability mode changed from " - << ScalabilityModeToString(scalability_mode) << " to " - << ScalabilityModeToString(*vc.GetScalabilityMode()); - num_spatial_layers = - ScalabilityModeToNumSpatialLayers(*vc.GetScalabilityMode()); - num_temporal_layers = - ScalabilityModeToNumTemporalLayers(*vc.GetScalabilityMode()); + if (*vc.GetScalabilityMode() != scalability_mode) { + RTC_LOG(LS_WARNING) << "Scalability mode changed from " + << ScalabilityModeToString(scalability_mode) << " to " + << ScalabilityModeToString(*vc.GetScalabilityMode()); + num_spatial_layers = + ScalabilityModeToNumSpatialLayers(*vc.GetScalabilityMode()); + num_temporal_layers = + ScalabilityModeToNumTemporalLayers(*vc.GetScalabilityMode()); + } } std::unique_ptr bitrate_allocator = @@ -1344,7 +1399,7 @@ SplitBitrateAndUpdateScalabilityMode(std::string codec_type, vc); VideoBitrateAllocation bitrate_allocation = bitrate_allocator->Allocate(VideoBitrateAllocationParameters( - 1000 * bitrates_kbps.front(), framerate_fps)); + 1000 * total_bitrate_kbps, framerate_fps)); std::vector bitrates; for (int sidx = 0; sidx < num_spatial_layers; ++sidx) { diff --git a/test/video_codec_tester_unittest.cc b/test/video_codec_tester_unittest.cc index ad1e9e3b03..fdd7b37a00 100644 --- a/test/video_codec_tester_unittest.cc +++ b/test/video_codec_tester_unittest.cc @@ -675,5 +675,137 @@ INSTANTIATE_TEST_SUITE_P( std::make_tuple(PacingSettings{.mode = PacingMode::kConstantRate, .constant_rate = Frequency::Hertz(20)}, /*expected_delta_ms=*/50))); + +struct EncodingSettingsTestParameters { + std::string codec_type; + std::string scalability_mode; + std::vector bitrate_kbps; + std::vector expected_bitrate_kbps; +}; + +class VideoCodecTesterTestEncodingSettings + : public ::testing::TestWithParam {}; + +TEST_P(VideoCodecTesterTestEncodingSettings, CreateEncodingSettings) { + EncodingSettingsTestParameters test_params = GetParam(); + std::map encoding_settings = + VideoCodecTester::CreateEncodingSettings( + test_params.codec_type, test_params.scalability_mode, /*width=*/1280, + /*height=*/720, test_params.bitrate_kbps, /*framerate_fps=*/30, + /*num_frames=*/1); + ASSERT_THAT(encoding_settings, SizeIs(1)); + const std::map& layers_settings = + encoding_settings.begin()->second.layers_settings; + std::vector configured_bitrate_kbps; + std::transform(layers_settings.begin(), layers_settings.end(), + std::back_inserter(configured_bitrate_kbps), + [](const auto& layer_settings) { + return layer_settings.second.bitrate.kbps(); + }); + EXPECT_EQ(configured_bitrate_kbps, test_params.expected_bitrate_kbps); +} + +INSTANTIATE_TEST_SUITE_P( + Vp8, + VideoCodecTesterTestEncodingSettings, + Values(EncodingSettingsTestParameters{.codec_type = "VP8", + .scalability_mode = "L1T1", + .bitrate_kbps = {1}, + .expected_bitrate_kbps = {1}}, + EncodingSettingsTestParameters{.codec_type = "VP8", + .scalability_mode = "L1T1", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {10000}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "L1T3", + .bitrate_kbps = {1000}, + .expected_bitrate_kbps = {400, 200, 400}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate_kbps = {100}, + .expected_bitrate_kbps = {40, 20, 40, 0, 0, 0, 0, 0, 0}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {60, 30, 60, 200, 100, 200, 1000, 500, + 1000}}, + EncodingSettingsTestParameters{ + .codec_type = "VP8", + .scalability_mode = "S3T3", + .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, + .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, + 900}})); + +INSTANTIATE_TEST_SUITE_P( + Vp9, + VideoCodecTesterTestEncodingSettings, + Values(EncodingSettingsTestParameters{.codec_type = "VP9", + .scalability_mode = "L1T1", + .bitrate_kbps = {1}, + .expected_bitrate_kbps = {1}}, + EncodingSettingsTestParameters{.codec_type = "VP9", + .scalability_mode = "L1T1", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {10000}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L1T3", + .bitrate_kbps = {1000}, + .expected_bitrate_kbps = {540, 163, 297}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate_kbps = {100}, + .expected_bitrate_kbps = {54, 16, 30, 0, 0, 0, 0, 0, 0}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {77, 23, 42, 226, 68, 124, 823, 249, + 452}}, + EncodingSettingsTestParameters{ + .codec_type = "VP9", + .scalability_mode = "L3T3", + .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, + .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, + 900}})); + +INSTANTIATE_TEST_SUITE_P( + Av1, + VideoCodecTesterTestEncodingSettings, + Values(EncodingSettingsTestParameters{.codec_type = "AV1", + .scalability_mode = "L1T1", + .bitrate_kbps = {1}, + .expected_bitrate_kbps = {1}}, + EncodingSettingsTestParameters{.codec_type = "AV1", + .scalability_mode = "L1T1", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {10000}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L1T3", + .bitrate_kbps = {1000}, + .expected_bitrate_kbps = {540, 163, 297}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate_kbps = {100}, + .expected_bitrate_kbps = {54, 16, 30, 0, 0, 0, 0, 0, 0}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate_kbps = {10000}, + .expected_bitrate_kbps = {77, 23, 42, 226, 68, 124, 823, 249, + 452}}, + EncodingSettingsTestParameters{ + .codec_type = "AV1", + .scalability_mode = "L3T3", + .bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, 900}, + .expected_bitrate_kbps = {100, 200, 300, 400, 500, 600, 700, 800, + 900}})); + } // namespace test } // namespace webrtc From 9183fcdc5311f6b6236597ff725831686a34b8fa Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Thu, 8 Feb 2024 08:02:03 -0800 Subject: [PATCH 103/170] Roll chromium_revision 59df7a60eb..ddf91e6338 (1257821:1257933) Change log: https://chromium.googlesource.com/chromium/src/+log/59df7a60eb..ddf91e6338 Full diff: https://chromium.googlesource.com/chromium/src/+/59df7a60eb..ddf91e6338 Changed dependencies * src/build: https://chromium.googlesource.com/chromium/src/build/+log/c3b35d6b4c..02b6c9f6d1 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/9b810c7888..45defe1bf4 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/fb5d53661a..657a87e64e * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/ce97b0e3f1..3a7918763a * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/6821c955bd..9b78d80da7 * src/third_party/r8: c2PL3_z2rOvwF74DJ36SLbH9iry7D6V-KG7NU_njKJwC..aRZW4VFdf45KlLTJNNkZ-Z8f_PTxChr6X3Nqhjth-FEC * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/e9eee6e818..fa1d49f3c1 DEPS diff: https://chromium.googlesource.com/chromium/src/+/59df7a60eb..ddf91e6338/DEPS No update to Clang. BUG=None Change-Id: I642f23ccca83ee30abc7b6ef08626b93f8c0bd04 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338680 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41699} --- DEPS | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DEPS b/DEPS index 2adbdb4cbc..f40a6f9c71 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '59df7a60ebe13178b3d085397d13486db906e49a', + 'chromium_revision': 'ddf91e63388d24becd59e440056ad53c234f23a4', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -52,7 +52,7 @@ deps = { 'src/base': 'https://chromium.googlesource.com/chromium/src/base@8f11a314ebca4c9aafe89b51736b96d8976f493a', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@c3b35d6b4cff8d6a2c616427726b15e187c57293', + 'https://chromium.googlesource.com/chromium/src/build@02b6c9f6d1336f9e9c4c39c9ccc7454d718f066f', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@6e5b3a31f22a0271a450318fcdeb80cdd2a57374', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@9b810c7888872552ebab3a437c6e5503a179444d', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@45defe1bf4dc750cd4aef8249b6b522141c46b28', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@fb5d53661ab9db51668b32785bdf847437bc20b4', + 'https://chromium.googlesource.com/chromium/src/testing@657a87e64e5a533f25c5acd9b5fd03afc2cc3203', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@ce97b0e3f12a32be4d978a2e25d1eb7cd2c6f8ec', + 'https://chromium.googlesource.com/chromium/src/third_party@3a7918763a412fb7598b704e91fa4cb8d10f5293', 'src/buildtools/linux64': { 'packages': [ @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@6821c955bdf682556ec4828a174a9cd916d0a02a', + 'https://android.googlesource.com/platform/external/perfetto.git@9b78d80da79be8d58590a2c686d66748161a77ff', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', 'src/third_party/libyuv': @@ -331,7 +331,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'c2PL3_z2rOvwF74DJ36SLbH9iry7D6V-KG7NU_njKJwC', + 'version': 'aRZW4VFdf45KlLTJNNkZ-Z8f_PTxChr6X3Nqhjth-FEC', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@e9eee6e8184854da240ea5210043027715f205f0', + 'https://chromium.googlesource.com/chromium/src/tools@fa1d49f3c15e23eb879e8993a16cdbd3349c4f5b', 'src/third_party/accessibility_test_framework': { 'packages': [ From 955839cf5ae418c58475ef11bfa04177fae81ede Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Thu, 8 Feb 2024 12:01:54 -0800 Subject: [PATCH 104/170] Roll chromium_revision ddf91e6338..4795399e45 (1257933:1258106) Change log: https://chromium.googlesource.com/chromium/src/+log/ddf91e6338..4795399e45 Full diff: https://chromium.googlesource.com/chromium/src/+/ddf91e6338..4795399e45 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/8f11a314eb..06afc626ca * src/build: https://chromium.googlesource.com/chromium/src/build/+log/02b6c9f6d1..c40a759ea4 * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/6e5b3a31f2..f90248f2bf * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/45defe1bf4..b5f3373c70 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/657a87e64e..5d2f2bfe72 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/3a7918763a..cf9b98c45c * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/74a6ca92bb..3569608028 * src/third_party/libc++/src: https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git/+log/c51c9efb6c..9d119c1f4a * src/third_party/libvpx/source/libvpx: https://chromium.googlesource.com/webm/libvpx.git/+log/c35f3e9e35..96b64eaac5 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/9b78d80da7..b20333c6f8 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/fa1d49f3c1..e7b1d307ed DEPS diff: https://chromium.googlesource.com/chromium/src/+/ddf91e6338..4795399e45/DEPS No update to Clang. BUG=None Change-Id: I8384b695f24d113c4a2ef017ea2a1e62f933dc56 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338681 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41700} --- DEPS | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/DEPS b/DEPS index f40a6f9c71..095c7ab114 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'ddf91e63388d24becd59e440056ad53c234f23a4', + 'chromium_revision': '4795399e45efb89d9931feae8d319b262057ea30', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@8f11a314ebca4c9aafe89b51736b96d8976f493a', + 'https://chromium.googlesource.com/chromium/src/base@06afc626cadff7b5507b7366a3a0661feaa90171', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@02b6c9f6d1336f9e9c4c39c9ccc7454d718f066f', + 'https://chromium.googlesource.com/chromium/src/build@c40a759ea459e093e168dbbb306b40d830dc9180', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@6e5b3a31f22a0271a450318fcdeb80cdd2a57374', + 'https://chromium.googlesource.com/chromium/src/buildtools@f90248f2bf52549f4110fbda4bb37580e81bc262', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@45defe1bf4dc750cd4aef8249b6b522141c46b28', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@b5f3373c709fe0ff17d31e69c02167ba6864abb2', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@657a87e64e5a533f25c5acd9b5fd03afc2cc3203', + 'https://chromium.googlesource.com/chromium/src/testing@5d2f2bfe729ee285a5cc1175cfff730d43674f69', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@3a7918763a412fb7598b704e91fa4cb8d10f5293', + 'https://chromium.googlesource.com/chromium/src/third_party@cf9b98c45c65dbf5eebcc35486860ee5a886e921', 'src/buildtools/linux64': { 'packages': [ @@ -115,7 +115,7 @@ deps = { 'src/third_party/clang-format/script': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@e5337933f2951cacd3aeacd238ce4578163ca0b9', 'src/third_party/libc++/src': - 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@c51c9efb6c5a83e0e25c1e30864449d2beadd7a8', + 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxx.git@9d119c1f4a097b7d27210874f4eba3fc91a83a4e', 'src/third_party/libc++abi/src': 'https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libcxxabi.git@a7b3d968a3a923886fea64b424bd770e69dc4ea4', 'src/third_party/libunwind/src': @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@74a6ca92bba677fc87328637bf573deb5944ac91', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@35696080284a2d59a8972ca27b509ebc1edc08ef', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,9 +302,9 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@9b78d80da79be8d58590a2c686d66748161a77ff', + 'https://android.googlesource.com/platform/external/perfetto.git@b20333c6f8b603fc3bf842a272126d83403f201f', 'src/third_party/libvpx/source/libvpx': - 'https://chromium.googlesource.com/webm/libvpx.git@c35f3e9e3512d0012180ad8de8834d8813a80b73', + 'https://chromium.googlesource.com/webm/libvpx.git@96b64eaac5adbac59e43e34d87af3ba0fb06bca6', 'src/third_party/libyuv': 'https://chromium.googlesource.com/libyuv/libyuv.git@2f2c04c1576534a7df953c2dc7c7ccf30beacd89', 'src/third_party/lss': { @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@fa1d49f3c15e23eb879e8993a16cdbd3349c4f5b', + 'https://chromium.googlesource.com/chromium/src/tools@e7b1d307ed88afbe0580708033155b8237e16538', 'src/third_party/accessibility_test_framework': { 'packages': [ From bc2593ebc62d9b6b1bc7e4ff3fa32799fabf341a Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Thu, 8 Feb 2024 16:02:25 -0800 Subject: [PATCH 105/170] Roll chromium_revision 4795399e45..7e6b715720 (1258106:1258254) Change log: https://chromium.googlesource.com/chromium/src/+log/4795399e45..7e6b715720 Full diff: https://chromium.googlesource.com/chromium/src/+/4795399e45..7e6b715720 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/06afc626ca..574f773d73 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/b5f3373c70..909831539c * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/5d2f2bfe72..066b13efaa * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/cf9b98c45c..9df0a239be * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/ca502d307f..0bfce82cee * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/3569608028..4d2864f3a1 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/b20333c6f8..ec59b08ccb * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/e7b1d307ed..98c91ad4ba DEPS diff: https://chromium.googlesource.com/chromium/src/+/4795399e45..7e6b715720/DEPS No update to Clang. BUG=None Change-Id: Id8225b47f0739acda261ab645dfa24b8b3bee149 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338760 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41701} --- DEPS | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DEPS b/DEPS index 095c7ab114..56793bef9a 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '4795399e45efb89d9931feae8d319b262057ea30', + 'chromium_revision': '7e6b7157209bcbcfab0d61414f9e4a3edb97dbea', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,7 +50,7 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@06afc626cadff7b5507b7366a3a0661feaa90171', + 'https://chromium.googlesource.com/chromium/src/base@574f773d736833ef4efaf1b7db74fe24d34f2f81', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@c40a759ea459e093e168dbbb306b40d830dc9180', 'src/buildtools': @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@b5f3373c709fe0ff17d31e69c02167ba6864abb2', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@909831539ceb5438b8e15ca20dc2109c1ae57f44', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@5d2f2bfe729ee285a5cc1175cfff730d43674f69', + 'https://chromium.googlesource.com/chromium/src/testing@066b13efaaafb0d350dd5016f77684d6bfec5c06', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@cf9b98c45c65dbf5eebcc35486860ee5a886e921', + 'https://chromium.googlesource.com/chromium/src/third_party@9df0a239becd34481527254f1ccb067959edba8c', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@ca502d307f30e7ac2de76211d8d590ff31e5080f', + 'https://chromium.googlesource.com/catapult.git@0bfce82ceec41df8497fc35054ec3a77c0a88b08', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@35696080284a2d59a8972ca27b509ebc1edc08ef', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@4d2864f3a1e991754ab8ab984e33ad399ee335f7', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@b20333c6f8b603fc3bf842a272126d83403f201f', + 'https://android.googlesource.com/platform/external/perfetto.git@ec59b08ccb4d733b4f3fd3299c825dbbd0e56282', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@96b64eaac5adbac59e43e34d87af3ba0fb06bca6', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@e7b1d307ed88afbe0580708033155b8237e16538', + 'https://chromium.googlesource.com/chromium/src/tools@98c91ad4baee4840f1c020f383071bd056aedc9c', 'src/third_party/accessibility_test_framework': { 'packages': [ From 1d35f76e423ace0ae324d7fd7fc431360d939c08 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Thu, 8 Feb 2024 22:02:14 -0800 Subject: [PATCH 106/170] Roll chromium_revision 7e6b715720..d6c15c3939 (1258254:1258371) Change log: https://chromium.googlesource.com/chromium/src/+log/7e6b715720..d6c15c3939 Full diff: https://chromium.googlesource.com/chromium/src/+/7e6b715720..d6c15c3939 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/574f773d73..2881ff893b * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/066b13efaa..436ce9d454 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/9df0a239be..b5ff79bc56 * src/third_party/android_build_tools/manifest_merger: xxtHLi-sldjnrAZqfTewA7Ai7T_i46GDTkbeOQm4Da4C..DEhOvoBwWVbV8XAI9NG-tn5g27KeMh2pXa44mY4dY10C * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/0bfce82cee..6e8cde260d * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/4d2864f3a1..05048d2cb0 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/98c91ad4ba..c097821eb1 DEPS diff: https://chromium.googlesource.com/chromium/src/+/7e6b715720..d6c15c3939/DEPS No update to Clang. BUG=None Change-Id: I29565bca0e2a13be2dd073269e7bdc444d25863c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338840 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41702} --- DEPS | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DEPS b/DEPS index 56793bef9a..ceba7a29b3 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '7e6b7157209bcbcfab0d61414f9e4a3edb97dbea', + 'chromium_revision': 'd6c15c3939939e4ae6fbc676952ae6d09351b107', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,7 +50,7 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@574f773d736833ef4efaf1b7db74fe24d34f2f81', + 'https://chromium.googlesource.com/chromium/src/base@2881ff893b77366ddcc72448f9eb705f10e868c5', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@c40a759ea459e093e168dbbb306b40d830dc9180', 'src/buildtools': @@ -65,9 +65,9 @@ deps = { 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@066b13efaaafb0d350dd5016f77684d6bfec5c06', + 'https://chromium.googlesource.com/chromium/src/testing@436ce9d45438663671e3a10f2b0f7d99f53f1caa', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@9df0a239becd34481527254f1ccb067959edba8c', + 'https://chromium.googlesource.com/chromium/src/third_party@b5ff79bc5651c46cfcafdeb0da5f07d5ef9398ae', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@0bfce82ceec41df8497fc35054ec3a77c0a88b08', + 'https://chromium.googlesource.com/catapult.git@6e8cde260d37919476e838483bcef14a29e356bf', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@4d2864f3a1e991754ab8ab984e33ad399ee335f7', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@05048d2cb05cc9a801d5af8ca02a16a34edd74f9', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@98c91ad4baee4840f1c020f383071bd056aedc9c', + 'https://chromium.googlesource.com/chromium/src/tools@c097821eb1bd687e7fbe8f432302ce395b26f06d', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -416,7 +416,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': 'xxtHLi-sldjnrAZqfTewA7Ai7T_i46GDTkbeOQm4Da4C', + 'version': 'DEhOvoBwWVbV8XAI9NG-tn5g27KeMh2pXa44mY4dY10C', }, ], 'condition': 'checkout_android', From dcd1ce232572edf16561caccb1e78c50454de39c Mon Sep 17 00:00:00 2001 From: Per K Date: Fri, 9 Feb 2024 08:40:28 +0100 Subject: [PATCH 107/170] Add integration test of PeerConnectionInterface::ReconfigureBandwidthEstimation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test that BWE proving can be started without sending audio or video. Bug: webrtc:14928 Change-Id: Ie55cb2de774f0c3b497b2636e7a6f5eac58d36a0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337322 Commit-Queue: Per Kjellander Reviewed-by: Per Kjellander Reviewed-by: Mirko Bonadei Reviewed-by: Henrik Boström Cr-Commit-Position: refs/heads/main@{#41703} --- test/peer_scenario/peer_scenario_client.cc | 12 +- test/peer_scenario/peer_scenario_client.h | 1 + test/peer_scenario/signaling_route.cc | 39 +++-- test/peer_scenario/signaling_route.h | 17 ++- test/peer_scenario/tests/bwe_ramp_up_test.cc | 150 +++++++++++++++++++ 5 files changed, 206 insertions(+), 13 deletions(-) diff --git a/test/peer_scenario/peer_scenario_client.cc b/test/peer_scenario/peer_scenario_client.cc index 1397b32fe3..3ba4fdb677 100644 --- a/test/peer_scenario/peer_scenario_client.cc +++ b/test/peer_scenario/peer_scenario_client.cc @@ -370,10 +370,13 @@ void PeerScenarioClient::CreateAndSetSdp( void PeerScenarioClient::SetSdpOfferAndGetAnswer( std::string remote_offer, + std::function remote_description_set, std::function answer_handler) { if (!signaling_thread_->IsCurrent()) { - signaling_thread_->PostTask( - [=] { SetSdpOfferAndGetAnswer(remote_offer, answer_handler); }); + signaling_thread_->PostTask([=] { + SetSdpOfferAndGetAnswer(remote_offer, remote_description_set, + answer_handler); + }); return; } RTC_DCHECK_RUN_ON(signaling_thread_); @@ -381,6 +384,11 @@ void PeerScenarioClient::SetSdpOfferAndGetAnswer( CreateSessionDescription(SdpType::kOffer, remote_offer), rtc::make_ref_counted([=](RTCError) { RTC_DCHECK_RUN_ON(signaling_thread_); + if (remote_description_set) { + // Allow the caller to modify transceivers + // before creating the answer. + remote_description_set(); + } peer_connection_->CreateAnswer( rtc::make_ref_counted( [=](std::unique_ptr answer) { diff --git a/test/peer_scenario/peer_scenario_client.h b/test/peer_scenario/peer_scenario_client.h index e863757759..cb025e9879 100644 --- a/test/peer_scenario/peer_scenario_client.h +++ b/test/peer_scenario/peer_scenario_client.h @@ -147,6 +147,7 @@ class PeerScenarioClient { std::function munge_offer, std::function offer_handler); void SetSdpOfferAndGetAnswer(std::string remote_offer, + std::function remote_description_set, std::function answer_handler); void SetSdpAnswer( std::string remote_answer, diff --git a/test/peer_scenario/signaling_route.cc b/test/peer_scenario/signaling_route.cc index eeec7c8657..8688c1abd8 100644 --- a/test/peer_scenario/signaling_route.cc +++ b/test/peer_scenario/signaling_route.cc @@ -59,6 +59,7 @@ void StartSdpNegotiation( CrossTrafficRoute* ret_route, std::function munge_offer, std::function modify_offer, + std::function callee_remote_description_set, std::function exchange_finished) { caller->CreateAndSetSdp(munge_offer, [=](std::string sdp_offer) { if (modify_offer) { @@ -67,11 +68,14 @@ void StartSdpNegotiation( RTC_CHECK(offer->ToString(&sdp_offer)); } send_route->NetworkDelayedAction(kSdpPacketSize, [=] { - callee->SetSdpOfferAndGetAnswer(sdp_offer, [=](std::string answer) { - ret_route->NetworkDelayedAction(kSdpPacketSize, [=] { - caller->SetSdpAnswer(std::move(answer), std::move(exchange_finished)); - }); - }); + callee->SetSdpOfferAndGetAnswer( + sdp_offer, std::move(callee_remote_description_set), + [=](std::string answer) { + ret_route->NetworkDelayedAction(kSdpPacketSize, [=] { + caller->SetSdpAnswer(std::move(answer), + std::move(exchange_finished)); + }); + }); }); }); } @@ -91,23 +95,40 @@ void SignalingRoute::StartIceSignaling() { StartIceSignalingForRoute(callee_, caller_, ret_route_); } +void SignalingRoute::NegotiateSdp( + std::function munge_offer, + std::function modify_offer, + std::function callee_remote_description_set, + std::function + exchange_finished) { + StartSdpNegotiation(caller_, callee_, send_route_, ret_route_, munge_offer, + modify_offer, callee_remote_description_set, + exchange_finished); +} + void SignalingRoute::NegotiateSdp( std::function munge_offer, std::function modify_offer, std::function exchange_finished) { - StartSdpNegotiation(caller_, callee_, send_route_, ret_route_, munge_offer, - modify_offer, exchange_finished); + NegotiateSdp(munge_offer, modify_offer, {}, exchange_finished); } void SignalingRoute::NegotiateSdp( std::function modify_offer, std::function exchange_finished) { - NegotiateSdp({}, modify_offer, exchange_finished); + NegotiateSdp({}, modify_offer, {}, exchange_finished); +} + +void SignalingRoute::NegotiateSdp( + std::function remote_description_set, + std::function + exchange_finished) { + NegotiateSdp({}, {}, remote_description_set, exchange_finished); } void SignalingRoute::NegotiateSdp( std::function exchange_finished) { - NegotiateSdp({}, {}, exchange_finished); + NegotiateSdp({}, {}, {}, exchange_finished); } } // namespace test diff --git a/test/peer_scenario/signaling_route.h b/test/peer_scenario/signaling_route.h index a95ae5c9f7..9b317d2552 100644 --- a/test/peer_scenario/signaling_route.h +++ b/test/peer_scenario/signaling_route.h @@ -35,9 +35,18 @@ class SignalingRoute { // The `munge_offer` callback is used to modify an offer between its creation // and set local description. This behavior is forbidden according to the spec // but available here in order to allow test coverage on corner cases. - // The `exchange_finished` callback is called with the answer produced after - // SDP negotations has completed. + // `callee_remote_description_set` is invoked when callee has applied the + // offer but not yet created an answer. The purpose is to allow tests to + // modify transceivers created from the offer. The `exchange_finished` + // callback is called with the answer produced after SDP negotations has + // completed. // TODO(srte): Handle lossy links. + void NegotiateSdp( + std::function munge_offer, + std::function modify_offer, + std::function callee_remote_description_set, + std::function + exchange_finished); void NegotiateSdp( std::function munge_offer, std::function modify_offer, @@ -47,6 +56,10 @@ class SignalingRoute { std::function modify_offer, std::function exchange_finished); + void NegotiateSdp( + std::function remote_description_set, + std::function + exchange_finished); void NegotiateSdp( std::function exchange_finished); diff --git a/test/peer_scenario/tests/bwe_ramp_up_test.cc b/test/peer_scenario/tests/bwe_ramp_up_test.cc index a7a17bbfd1..f8eaa47858 100644 --- a/test/peer_scenario/tests/bwe_ramp_up_test.cc +++ b/test/peer_scenario/tests/bwe_ramp_up_test.cc @@ -25,6 +25,9 @@ namespace webrtc { namespace test { using ::testing::SizeIs; +using ::testing::Test; +using ::testing::ValuesIn; +using ::testing::WithParamInterface; rtc::scoped_refptr GetStatsAndProcess( PeerScenario& s, @@ -124,5 +127,152 @@ TEST(BweRampupTest, RampUpWithUndemuxableRtpPackets) { // ensure BWE has increased beyond noise levels. EXPECT_GT(final_bwe, initial_bwe + DataRate::KilobitsPerSec(345)); } + +struct InitialProbeTestParams { + DataRate network_capacity; + DataRate expected_bwe_min; +}; +class BweRampupWithInitialProbeTest + : public Test, + public WithParamInterface {}; + +INSTANTIATE_TEST_SUITE_P( + BweRampupWithInitialProbeTest, + BweRampupWithInitialProbeTest, + ValuesIn( + {{ + .network_capacity = DataRate::KilobitsPerSec(3000), + .expected_bwe_min = DataRate::KilobitsPerSec(2500), + }, + { + .network_capacity = webrtc::DataRate::KilobitsPerSec(500), + .expected_bwe_min = webrtc::DataRate::KilobitsPerSec(400), + }})); + +// Test that caller and callee BWE rampup even if no media packets are sent. +// - BandWidthEstimationSettings.allow_probe_without_media must be set. +// - A Video RtpTransceiver with RTX support needs to be negotiated. +TEST_P(BweRampupWithInitialProbeTest, BweRampUpBothDirectionsWithoutMedia) { + PeerScenario s(*::testing::UnitTest::GetInstance()->current_test_info()); + InitialProbeTestParams test_params = GetParam(); + + PeerScenarioClient* caller = s.CreateClient({}); + PeerScenarioClient* callee = s.CreateClient({}); + + auto video_result = caller->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO); + ASSERT_EQ(video_result.error().type(), RTCErrorType::NONE); + + caller->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + callee->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + + auto node_builder = + s.net()->NodeBuilder().capacity_kbps(test_params.network_capacity.kbps()); + auto caller_node = node_builder.Build().node; + auto callee_node = node_builder.Build().node; + s.net()->CreateRoute(caller->endpoint(), {caller_node}, callee->endpoint()); + s.net()->CreateRoute(callee->endpoint(), {callee_node}, caller->endpoint()); + + auto signaling = + s.ConnectSignaling(caller, callee, {caller_node}, {callee_node}); + signaling.StartIceSignaling(); + + std::atomic offer_exchange_done(false); + signaling.NegotiateSdp( + [&]() { + // When remote description has been set, a transceiver is created. + // Set the diretion to sendrecv so that it can be used for BWE probing + // from callee -> caller. + ASSERT_THAT(callee->pc()->GetTransceivers(), SizeIs(1)); + ASSERT_TRUE( + callee->pc() + ->GetTransceivers()[0] + ->SetDirectionWithError(RtpTransceiverDirection::kSendRecv) + .ok()); + }, + [&](const SessionDescriptionInterface& answer) { + offer_exchange_done = true; + }); + // Wait for SDP negotiation. + s.WaitAndProcess(&offer_exchange_done); + + // Test that 1s after offer/answer exchange finish, we have a BWE estimate, + // even though no video frames have been sent. + s.ProcessMessages(TimeDelta::Seconds(1)); + + auto callee_inbound_stats = + GetStatsAndProcess(s, callee)->GetStatsOfType(); + ASSERT_THAT(callee_inbound_stats, SizeIs(1)); + ASSERT_EQ(*callee_inbound_stats[0]->frames_received, 0u); + auto caller_inbound_stats = + GetStatsAndProcess(s, caller)->GetStatsOfType(); + ASSERT_THAT(caller_inbound_stats, SizeIs(1)); + ASSERT_EQ(*caller_inbound_stats[0]->frames_received, 0u); + + DataRate caller_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + EXPECT_GT(caller_bwe.kbps(), test_params.expected_bwe_min.kbps()); + EXPECT_LE(caller_bwe.kbps(), test_params.network_capacity.kbps()); + DataRate callee_bwe = GetAvailableSendBitrate(GetStatsAndProcess(s, callee)); + EXPECT_GT(callee_bwe.kbps(), test_params.expected_bwe_min.kbps()); + EXPECT_LE(callee_bwe.kbps(), test_params.network_capacity.kbps()); +} + +// Test that we can reconfigure bandwidth estimation and send new BWE probes. +// In this test, camera is stopped, and some times later, the app want to get a +// new BWE estimate. +TEST(BweRampupTest, CanReconfigureBweAfterStopingVideo) { + PeerScenario s(*::testing::UnitTest::GetInstance()->current_test_info()); + PeerScenarioClient* caller = s.CreateClient({}); + PeerScenarioClient* callee = s.CreateClient({}); + + auto node_builder = s.net()->NodeBuilder().capacity_kbps(1000); + auto caller_node = node_builder.Build().node; + auto callee_node = node_builder.Build().node; + s.net()->CreateRoute(caller->endpoint(), {caller_node}, callee->endpoint()); + s.net()->CreateRoute(callee->endpoint(), {callee_node}, caller->endpoint()); + + PeerScenarioClient::VideoSendTrack track = caller->CreateVideo("VIDEO", {}); + + auto signaling = + s.ConnectSignaling(caller, callee, {caller_node}, {callee_node}); + + signaling.StartIceSignaling(); + + std::atomic offer_exchange_done(false); + signaling.NegotiateSdp([&](const SessionDescriptionInterface& answer) { + offer_exchange_done = true; + }); + // Wait for SDP negotiation. + s.WaitAndProcess(&offer_exchange_done); + + // Send a TCP messages to the receiver using the same downlink node. + // This is done just to force a lower BWE than the link capacity. + webrtc::TcpMessageRoute* tcp_route = s.net()->CreateTcpRoute( + s.net()->CreateRoute({caller_node}), s.net()->CreateRoute({callee_node})); + DataRate bwe_before_restart = DataRate::Zero(); + + std::atomic message_delivered(false); + tcp_route->SendMessage( + /*size=*/5'00'000, + /*on_received=*/[&]() { message_delivered = true; }); + s.WaitAndProcess(&message_delivered); + bwe_before_restart = GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + + // Camera is stopped. + track.capturer->Stop(); + s.ProcessMessages(TimeDelta::Seconds(2)); + + // Some time later, the app is interested in restarting BWE since we may want + // to resume video eventually. + caller->pc()->ReconfigureBandwidthEstimation( + {.allow_probe_without_media = true}); + s.ProcessMessages(TimeDelta::Seconds(1)); + DataRate bwe_after_restart = + GetAvailableSendBitrate(GetStatsAndProcess(s, caller)); + EXPECT_GT(bwe_after_restart.kbps(), bwe_before_restart.kbps() + 300); + EXPECT_LT(bwe_after_restart.kbps(), 1000); +} + } // namespace test } // namespace webrtc From 5ba4f2ab58a3393a52b8c8a0b160e846b54610d9 Mon Sep 17 00:00:00 2001 From: Dor Hen Date: Thu, 8 Feb 2024 12:47:54 +0200 Subject: [PATCH 108/170] Make file/directory related tests safe for concurrent execution Providing unique identifiers for files and directories created as part of unit tests. Bug: webrtc:15833 Change-Id: If2835c362c47a111aa99b0e3c6ad6a33be061978 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338260 Reviewed-by: Mirko Bonadei Reviewed-by: Harald Alvestrand Commit-Queue: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41704} --- common_audio/BUILD.gn | 1 + common_audio/wav_file_unittest.cc | 4 +++- modules/audio_device/BUILD.gn | 1 + modules/audio_device/include/test_audio_device_unittest.cc | 3 ++- test/BUILD.gn | 1 + test/testsupport/file_utils_unittest.cc | 7 +++++-- 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn index 2ae6d32710..620d01e6d5 100644 --- a/common_audio/BUILD.gn +++ b/common_audio/BUILD.gn @@ -375,6 +375,7 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base:checks", "../rtc_base:macromagic", "../rtc_base:rtc_base_tests_utils", + "../rtc_base:ssl", "../rtc_base:stringutils", "../rtc_base:timeutils", "../rtc_base/system:arch", diff --git a/common_audio/wav_file_unittest.cc b/common_audio/wav_file_unittest.cc index 97cecc345f..6a0cfdc680 100644 --- a/common_audio/wav_file_unittest.cc +++ b/common_audio/wav_file_unittest.cc @@ -17,6 +17,7 @@ #include #include "common_audio/wav_header.h" +#include "rtc_base/helpers.h" #include "test/gtest.h" #include "test/testsupport/file_utils.h" @@ -35,7 +36,8 @@ static const float kSamples[] = {0.0, 10.0, 4e4, -1e9}; // Write a tiny WAV file with the C++ interface and verify the result. TEST(WavWriterTest, MAYBE_CPP) { - const std::string outfile = test::OutputPath() + "wavtest1.wav"; + const std::string outfile = + test::OutputPath() + "wavtest1-" + rtc::CreateRandomUuid() + ".wav"; static const size_t kNumSamples = 3; { WavWriter w(outfile, 14099, 1); diff --git a/modules/audio_device/BUILD.gn b/modules/audio_device/BUILD.gn index 2088e74dcd..baba0a36d9 100644 --- a/modules/audio_device/BUILD.gn +++ b/modules/audio_device/BUILD.gn @@ -488,6 +488,7 @@ if (rtc_include_tests && !build_with_chromium) { "../../rtc_base:race_checker", "../../rtc_base:rtc_event", "../../rtc_base:safe_conversions", + "../../rtc_base:ssl", "../../rtc_base:timeutils", "../../rtc_base/synchronization:mutex", "../../system_wrappers", diff --git a/modules/audio_device/include/test_audio_device_unittest.cc b/modules/audio_device/include/test_audio_device_unittest.cc index 7a122ca84b..d79697bb52 100644 --- a/modules/audio_device/include/test_audio_device_unittest.cc +++ b/modules/audio_device/include/test_audio_device_unittest.cc @@ -24,6 +24,7 @@ #include "common_audio/wav_header.h" #include "modules/audio_device/include/audio_device_defines.h" #include "rtc_base/checks.h" +#include "rtc_base/helpers.h" #include "rtc_base/logging.h" #include "rtc_base/synchronization/mutex.h" #include "test/gmock.h" @@ -41,7 +42,7 @@ void RunWavTest(const std::vector& input_samples, const std::string output_filename = test::OutputPath() + "BoundedWavFileWriterTest_" + test_info->name() + - "_" + std::to_string(std::rand()) + ".wav"; + "_" + rtc::CreateRandomUuid() + ".wav"; static const size_t kSamplesPerFrame = 8; static const int kSampleRate = kSamplesPerFrame * 100; diff --git a/test/BUILD.gn b/test/BUILD.gn index 185f12c3ed..574496f2e3 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -950,6 +950,7 @@ rtc_library("fileutils_unittests") { ":fileutils", ":test_support", "../rtc_base:checks", + "../rtc_base:ssl", ] absl_deps = [ "//third_party/abseil-cpp/absl/strings:strings", diff --git a/test/testsupport/file_utils_unittest.cc b/test/testsupport/file_utils_unittest.cc index b9de01d09d..666d574a85 100644 --- a/test/testsupport/file_utils_unittest.cc +++ b/test/testsupport/file_utils_unittest.cc @@ -19,6 +19,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "rtc_base/checks.h" +#include "rtc_base/helpers.h" #include "test/gmock.h" #include "test/gtest.h" @@ -147,7 +148,8 @@ TEST_F(FileUtilsTest, GenerateTempFilename) { #define MAYBE_CreateDir CreateDir #endif TEST_F(FileUtilsTest, MAYBE_CreateDir) { - std::string directory = "fileutils-unittest-empty-dir"; + std::string directory = test::OutputPath() + "fileutils-unittest-empty-dir" + + rtc::CreateRandomUuid(); // Make sure it's removed if a previous test has failed: remove(directory.c_str()); ASSERT_TRUE(webrtc::test::CreateDir(directory)); @@ -231,7 +233,8 @@ TEST_F(FileUtilsTest, WriteReadDeleteFilesAndDirs) { // Create an empty temporary directory for this test. const std::string temp_directory = - OutputPath() + Path("TempFileUtilsTestReadDirectory/"); + OutputPath() + + Path("TempFileUtilsTestReadDirectory" + rtc::CreateRandomUuid() + "/"); CreateDir(temp_directory); EXPECT_NO_FATAL_FAILURE(CleanDir(temp_directory, &num_deleted_entries)); EXPECT_TRUE(DirExists(temp_directory)); From 15062c87397efc4d97c6fd8e5d1ebc0790b19044 Mon Sep 17 00:00:00 2001 From: Bjorn Terelius Date: Thu, 8 Feb 2024 23:33:11 +0100 Subject: [PATCH 109/170] Create helper for constructing empty LoggedPacketInfo for testing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: b/318801494 Change-Id: Ie063ac3a63276f5fbc14794b6aba8e7b839cc910 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338740 Reviewed-by: Mirko Bonadei Commit-Queue: Björn Terelius Cr-Commit-Position: refs/heads/main@{#41705} --- logging/rtc_event_log/rtc_event_log_parser.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/logging/rtc_event_log/rtc_event_log_parser.h b/logging/rtc_event_log/rtc_event_log_parser.h index def9f0ab35..c24e5e8186 100644 --- a/logging/rtc_event_log/rtc_event_log_parser.h +++ b/logging/rtc_event_log/rtc_event_log_parser.h @@ -71,12 +71,15 @@ enum PacketDirection { kIncomingPacket = 0, kOutgoingPacket }; enum class LoggedMediaType : uint8_t { kUnknown, kAudio, kVideo }; struct LoggedPacketInfo { + static LoggedPacketInfo CreateEmptyForTesting() { return LoggedPacketInfo(); } + LoggedPacketInfo(const LoggedRtpPacket& rtp, LoggedMediaType media_type, bool rtx, Timestamp capture_time); LoggedPacketInfo(const LoggedPacketInfo&); ~LoggedPacketInfo(); + int64_t log_time_ms() const { return log_packet_time.ms(); } int64_t log_time_us() const { return log_packet_time.us(); } uint32_t ssrc; @@ -114,6 +117,12 @@ struct LoggedPacketInfo { // time, and this is instead calculated as the difference in reported receive // time between this packet and the last packet in the same feedback message. TimeDelta feedback_hold_duration = TimeDelta::MinusInfinity(); + + private: + LoggedPacketInfo() + : capture_time(Timestamp::MinusInfinity()), + log_packet_time(Timestamp::MinusInfinity()), + reported_send_time(Timestamp::MinusInfinity()) {} }; struct InferredRouteChangeEvent { From 61b1f53a4c707410730fe85163af3bfed27dd99e Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 29 Jan 2024 10:36:53 +0100 Subject: [PATCH 110/170] Extend test::FunctionVideoDecoderFactory to propagate Environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To reduce number calls to the CreateVideoDecoder Bug: webrtc:15791 Change-Id: I5d6ecc2e5e68165d4e012b3ad7edb6eaa40e1913 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336420 Commit-Queue: Danil Chapovalov Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/main@{#41706} --- api/test/video/BUILD.gn | 1 + .../video/function_video_decoder_factory.h | 19 ++++++++++++------- modules/video_coding/BUILD.gn | 2 ++ .../utility/simulcast_test_fixture_impl.cc | 5 ++++- video/BUILD.gn | 1 + .../multi_codec_receive_tests.cc | 3 ++- video/video_quality_test.cc | 10 ++++++---- video/video_quality_test.h | 2 ++ 8 files changed, 30 insertions(+), 13 deletions(-) diff --git a/api/test/video/BUILD.gn b/api/test/video/BUILD.gn index 0eae85aef3..cf6dd599c9 100644 --- a/api/test/video/BUILD.gn +++ b/api/test/video/BUILD.gn @@ -18,6 +18,7 @@ rtc_library("function_video_factory") { deps = [ "../../../rtc_base:checks", + "../../environment", "../../video_codecs:video_codecs_api", ] } diff --git a/api/test/video/function_video_decoder_factory.h b/api/test/video/function_video_decoder_factory.h index 2145c71bff..2f2eeb5886 100644 --- a/api/test/video/function_video_decoder_factory.h +++ b/api/test/video/function_video_decoder_factory.h @@ -16,6 +16,7 @@ #include #include +#include "api/environment/environment.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder_factory.h" @@ -29,17 +30,20 @@ class FunctionVideoDecoderFactory final : public VideoDecoderFactory { public: explicit FunctionVideoDecoderFactory( std::function()> create) - : create_([create = std::move(create)](const SdpVideoFormat&) { + : create_([create = std::move(create)](const Environment&, + const SdpVideoFormat&) { return create(); }) {} explicit FunctionVideoDecoderFactory( - std::function(const SdpVideoFormat&)> + std::function(const Environment&, + const SdpVideoFormat&)> create) : create_(std::move(create)) {} FunctionVideoDecoderFactory( std::function()> create, std::vector sdp_video_formats) - : create_([create = std::move(create)](const SdpVideoFormat&) { + : create_([create = std::move(create)](const Environment&, + const SdpVideoFormat&) { return create(); }), sdp_video_formats_(std::move(sdp_video_formats)) {} @@ -48,13 +52,14 @@ class FunctionVideoDecoderFactory final : public VideoDecoderFactory { return sdp_video_formats_; } - std::unique_ptr CreateVideoDecoder( - const SdpVideoFormat& format) override { - return create_(format); + std::unique_ptr Create(const Environment& env, + const SdpVideoFormat& format) override { + return create_(env, format); } private: - const std::function(const SdpVideoFormat&)> + const std::function(const Environment& env, + const SdpVideoFormat&)> create_; const std::vector sdp_video_formats_; }; diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index a31d759baa..5256c02e70 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -820,6 +820,8 @@ if (rtc_include_tests) { "../../api:mock_video_decoder", "../../api:mock_video_encoder", "../../api:simulcast_test_fixture_api", + "../../api/environment", + "../../api/environment:environment_factory", "../../api/video:encoded_image", "../../api/video:video_frame", "../../api/video:video_rtp_headers", diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc index c6e51e8068..ac076fde71 100644 --- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc +++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc @@ -15,6 +15,8 @@ #include #include +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/video/encoded_image.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_encoder.h" @@ -258,8 +260,9 @@ SimulcastTestFixtureImpl::SimulcastTestFixtureImpl( std::unique_ptr decoder_factory, SdpVideoFormat video_format) : codec_type_(PayloadStringToCodecType(video_format.name)) { + Environment env = CreateEnvironment(); encoder_ = encoder_factory->CreateVideoEncoder(video_format); - decoder_ = decoder_factory->CreateVideoDecoder(video_format); + decoder_ = decoder_factory->Create(env, video_format); SetUpCodec((codec_type_ == kVideoCodecVP8 || codec_type_ == kVideoCodecH264) ? kDefaultTemporalLayerProfile : kNoTemporalLayerProfile); diff --git a/video/BUILD.gn b/video/BUILD.gn index 5a114c5fb7..e4e1f275f4 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -519,6 +519,7 @@ if (rtc_include_tests) { "../api:rtc_event_log_output_file", "../api:test_dependency_factory", "../api:video_quality_test_fixture_api", + "../api/environment", "../api/numerics", "../api/rtc_event_log:rtc_event_log_factory", "../api/task_queue", diff --git a/video/end_to_end_tests/multi_codec_receive_tests.cc b/video/end_to_end_tests/multi_codec_receive_tests.cc index 307b5085c9..e236af007b 100644 --- a/video/end_to_end_tests/multi_codec_receive_tests.cc +++ b/video/end_to_end_tests/multi_codec_receive_tests.cc @@ -213,7 +213,8 @@ void MultiCodecReceiveTest::RunTestWithCodecs( return nullptr; }); test::FunctionVideoDecoderFactory decoder_factory( - [](const SdpVideoFormat& format) -> std::unique_ptr { + [](const Environment& env, + const SdpVideoFormat& format) -> std::unique_ptr { if (format.name == "VP8") { return VP8Decoder::Create(); } diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc index 99b722322a..ebfc24130e 100644 --- a/video/video_quality_test.cc +++ b/video/video_quality_test.cc @@ -294,6 +294,7 @@ void PressEnterToContinue(TaskQueueBase* /*task_queue*/) { } // namespace std::unique_ptr VideoQualityTest::CreateVideoDecoder( + const Environment& env, const SdpVideoFormat& format) { std::unique_ptr decoder; if (format.name == "multiplex") { @@ -302,7 +303,7 @@ std::unique_ptr VideoQualityTest::CreateVideoDecoder( } else if (format.name == "FakeCodec") { decoder = webrtc::FakeVideoDecoderFactory::CreateVideoDecoder(); } else { - decoder = decoder_factory_->CreateVideoDecoder(format); + decoder = decoder_factory_->Create(env, format); } if (!params_.logging.encoded_frame_base_path.empty()) { rtc::StringBuilder str; @@ -375,9 +376,10 @@ VideoQualityTest::VideoQualityTest( std::unique_ptr injection_components) : clock_(Clock::GetRealTimeClock()), task_queue_factory_(CreateDefaultTaskQueueFactory()), - video_decoder_factory_([this](const SdpVideoFormat& format) { - return this->CreateVideoDecoder(format); - }), + video_decoder_factory_( + [this](const Environment& env, const SdpVideoFormat& format) { + return this->CreateVideoDecoder(env, format); + }), video_encoder_factory_([this](const SdpVideoFormat& format) { return this->CreateVideoEncoder(format, nullptr); }), diff --git a/video/video_quality_test.h b/video/video_quality_test.h index 63fa4813f0..c5e63ddf48 100644 --- a/video/video_quality_test.h +++ b/video/video_quality_test.h @@ -15,6 +15,7 @@ #include #include +#include "api/environment/environment.h" #include "api/fec_controller.h" #include "api/rtc_event_log/rtc_event_log_factory.h" #include "api/task_queue/task_queue_base.h" @@ -79,6 +80,7 @@ class VideoQualityTest : public test::CallTest, size_t video_idx); void SetupThumbnailCapturers(size_t num_thumbnail_streams); std::unique_ptr CreateVideoDecoder( + const Environment& env, const SdpVideoFormat& format); std::unique_ptr CreateVideoEncoder(const SdpVideoFormat& format, VideoAnalyzer* analyzer); From 3f3f991c03bb4073a06da37c822daaa9deed9307 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Thu, 4 Jan 2024 18:59:05 +0100 Subject: [PATCH 111/170] Let port allocator create ice tie breaker Moves the responsibility for creating the ICE tie breaker from the JSEP transport controller to the port allocator. This will allow a future change to separate the ICE tie breaker (which is sent over the network and hence known to the peer) from the "port allocator random" (that is used to seed the ICE candidate foundation crc32 checksum) as an implementation detail. BUG=webrtc:14626 Change-Id: I3a9a0980238d6108b1b154f45de2975b08793b1c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/281660 Reviewed-by: Harald Alvestrand Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41707} --- p2p/base/fake_port_allocator.h | 2 +- p2p/base/p2p_transport_channel.cc | 8 +++----- p2p/base/p2p_transport_channel.h | 2 +- p2p/base/p2p_transport_channel_unittest.cc | 7 ------- p2p/base/port_allocator.cc | 12 +++--------- p2p/base/port_allocator.h | 16 +++++++--------- p2p/base/port_allocator_unittest.cc | 5 +---- p2p/base/regathering_controller_unittest.cc | 2 -- p2p/client/basic_port_allocator.cc | 19 +++++++++++++++++-- p2p/client/basic_port_allocator.h | 7 +++++++ p2p/client/basic_port_allocator_unittest.cc | 5 ----- pc/jsep_transport_controller.cc | 4 +--- pc/jsep_transport_controller.h | 2 +- pc/peer_connection_ice_unittest.cc | 2 -- pc/peer_connection_interface_unittest.cc | 2 -- 15 files changed, 42 insertions(+), 53 deletions(-) diff --git a/p2p/base/fake_port_allocator.h b/p2p/base/fake_port_allocator.h index 0bb7dd0139..706635778b 100644 --- a/p2p/base/fake_port_allocator.h +++ b/p2p/base/fake_port_allocator.h @@ -92,6 +92,7 @@ class FakePortAllocatorSession : public PortAllocatorSession { component, ice_ufrag, ice_pwd, + /*kTiebreakerDefault = */ 44444, allocator->flags()), network_thread_(network_thread), factory_(factory), @@ -110,7 +111,6 @@ class FakePortAllocatorSession : public PortAllocatorSession { field_trials_(field_trials) { ipv4_network_.AddIP(rtc::IPAddress(INADDR_LOOPBACK)); ipv6_network_.AddIP(rtc::IPAddress(in6addr_loopback)); - set_ice_tiebreaker(/*kTiebreakerDefault = */ 44444); } void SetCandidateFilter(uint32_t filter) override { diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc index 0bccb67209..2f18f1dbb9 100644 --- a/p2p/base/p2p_transport_channel.cc +++ b/p2p/base/p2p_transport_channel.cc @@ -164,7 +164,7 @@ P2PTransportChannel::P2PTransportChannel( error_(0), remote_ice_mode_(ICEMODE_FULL), ice_role_(ICEROLE_UNKNOWN), - tiebreaker_(0), + ice_tiebreaker_(0), gathering_state_(kIceGatheringNew), weak_ping_interval_(GetWeakPingIntervalInFieldTrial(field_trials)), config_(RECEIVING_TIMEOUT, @@ -326,7 +326,7 @@ void P2PTransportChannel::SetIceTiebreaker(uint64_t tiebreaker) { return; } - tiebreaker_ = tiebreaker; + ice_tiebreaker_ = tiebreaker; } IceTransportState P2PTransportChannel::GetState() const { @@ -885,7 +885,6 @@ void P2PTransportChannel::MaybeStartGathering() { ice_parameters_.ufrag, ice_parameters_.pwd); if (pooled_session) { - pooled_session->set_ice_tiebreaker(tiebreaker_); AddAllocatorSession(std::move(pooled_session)); PortAllocatorSession* raw_pooled_session = allocator_sessions_.back().get(); @@ -902,7 +901,6 @@ void P2PTransportChannel::MaybeStartGathering() { AddAllocatorSession(allocator_->CreateSession( transport_name(), component(), ice_parameters_.ufrag, ice_parameters_.pwd)); - allocator_sessions_.back()->set_ice_tiebreaker(tiebreaker_); allocator_sessions_.back()->StartGettingPorts(); } } @@ -930,7 +928,7 @@ void P2PTransportChannel::OnPortReady(PortAllocatorSession* session, // if one is pending. port->SetIceRole(ice_role_); - port->SetIceTiebreaker(tiebreaker_); + port->SetIceTiebreaker(ice_tiebreaker_); ports_.push_back(port); port->SignalUnknownAddress.connect(this, &P2PTransportChannel::OnUnknownAddress); diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h index da7933f2e7..f7472df38a 100644 --- a/p2p/base/p2p_transport_channel.h +++ b/p2p/base/p2p_transport_channel.h @@ -439,7 +439,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal, RTC_GUARDED_BY(network_thread_); IceMode remote_ice_mode_ RTC_GUARDED_BY(network_thread_); IceRole ice_role_ RTC_GUARDED_BY(network_thread_); - uint64_t tiebreaker_ RTC_GUARDED_BY(network_thread_); + uint64_t ice_tiebreaker_ RTC_GUARDED_BY(network_thread_); IceGatheringState gathering_state_ RTC_GUARDED_BY(network_thread_); std::unique_ptr regathering_controller_ RTC_GUARDED_BY(network_thread_); diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index 5bcfee0473..79e984cfec 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -141,7 +141,6 @@ const cricket::IceParameters kIceParams[4] = { const uint64_t kLowTiebreaker = 11111; const uint64_t kHighTiebreaker = 22222; -const uint64_t kTiebreakerDefault = 44444; cricket::IceConfig CreateIceConfig( int receiving_timeout, @@ -299,10 +298,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, &ep2_.network_manager_, socket_factory_.get(), stun_servers, kTurnUdpIntAddr, rtc::SocketAddress())); - ep1_.SetIceTiebreaker(kTiebreakerDefault); - ep1_.allocator_->SetIceTiebreaker(kTiebreakerDefault); - ep2_.SetIceTiebreaker(kTiebreakerDefault); - ep2_.allocator_->SetIceTiebreaker(kTiebreakerDefault); webrtc::metrics::Reset(); } @@ -3347,7 +3342,6 @@ class P2PTransportChannelPingTest : public ::testing::Test, protected: void PrepareChannel(P2PTransportChannel* ch) { ch->SetIceRole(ICEROLE_CONTROLLING); - ch->SetIceTiebreaker(kTiebreakerDefault); ch->SetIceParameters(kIceParams[0]); ch->SetRemoteIceParameters(kIceParams[1]); ch->SignalNetworkRouteChanged.connect( @@ -3715,7 +3709,6 @@ TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) { &field_trials_); P2PTransportChannel ch("TestChannel", 1, &pa, &field_trials_); ch.SetIceRole(ICEROLE_CONTROLLING); - ch.SetIceTiebreaker(kTiebreakerDefault); ch.SetIceParameters(kIceParams[0]); ch.MaybeStartGathering(); EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(), diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc index 3745717510..30bcfb1732 100644 --- a/p2p/base/port_allocator.cc +++ b/p2p/base/port_allocator.cc @@ -62,6 +62,7 @@ PortAllocatorSession::PortAllocatorSession(absl::string_view content_name, int component, absl::string_view ice_ufrag, absl::string_view ice_pwd, + uint64_t ice_tiebreaker, uint32_t flags) : flags_(flags), generation_(0), @@ -69,7 +70,7 @@ PortAllocatorSession::PortAllocatorSession(absl::string_view content_name, component_(component), ice_ufrag_(ice_ufrag), ice_pwd_(ice_pwd), - tiebreaker_(0) { + ice_tiebreaker_(ice_tiebreaker) { // Pooled sessions are allowed to be created with empty content name, // component, ufrag and password. RTC_DCHECK(ice_ufrag.empty() == ice_pwd.empty()); @@ -101,7 +102,7 @@ PortAllocator::PortAllocator() step_delay_(kDefaultStepDelay), allow_tcp_listen_(true), candidate_filter_(CF_ALL), - tiebreaker_(0) { + tiebreaker_(rtc::CreateRandomId64()) { // The allocator will be attached to a thread in Initialize. thread_checker_.Detach(); } @@ -197,13 +198,6 @@ bool PortAllocator::SetConfiguration( return true; } -void PortAllocator::SetIceTiebreaker(uint64_t tiebreaker) { - tiebreaker_ = tiebreaker; - for (auto& pooled_session : pooled_sessions_) { - pooled_session->set_ice_tiebreaker(tiebreaker_); - } -} - std::unique_ptr PortAllocator::CreateSession( absl::string_view content_name, int component, diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h index b8cffca9c0..e9630df143 100644 --- a/p2p/base/port_allocator.h +++ b/p2p/base/port_allocator.h @@ -199,6 +199,7 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { int component, absl::string_view ice_ufrag, absl::string_view ice_pwd, + uint64_t ice_tiebreaker, uint32_t flags); // Subclasses should clean up any ports created. @@ -212,9 +213,9 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { const std::string& ice_pwd() const { return ice_pwd_; } bool pooled() const { return pooled_; } - // TODO(bugs.webrtc.org/14605): move this to the constructor - void set_ice_tiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; } - uint64_t ice_tiebreaker() const { return tiebreaker_; } + // TODO(bugs.webrtc.org/14605): remove once downstream code has been updated. + void set_ice_tiebreaker(uint64_t tiebreaker) { ice_tiebreaker_ = tiebreaker; } + uint64_t ice_tiebreaker() const { return ice_tiebreaker_; } // Setting this filter should affect not only candidates gathered in the // future, but candidates already gathered and ports already "ready", @@ -329,12 +330,10 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { int component_; std::string ice_ufrag_; std::string ice_pwd_; + uint64_t ice_tiebreaker_; bool pooled_ = false; - // TODO(bugs.webrtc.org/14605): move this to the constructor - uint64_t tiebreaker_; - // SetIceParameters is an implementation detail which only PortAllocator // should be able to call. friend class PortAllocator; @@ -387,9 +386,6 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { const absl::optional& stun_candidate_keepalive_interval = absl::nullopt); - void SetIceTiebreaker(uint64_t tiebreaker); - uint64_t IceTiebreaker() const { return tiebreaker_; } - const ServerAddresses& stun_servers() const { CheckRunOnValidThreadIfInitialized(); return stun_servers_; @@ -461,6 +457,8 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { // 3. mDNS concealment of private IPs is enabled. Candidate SanitizeCandidate(const Candidate& c) const; + uint64_t ice_tiebreaker() const { return tiebreaker_; } + uint32_t flags() const { CheckRunOnValidThreadIfInitialized(); return flags_; diff --git a/p2p/base/port_allocator_unittest.cc b/p2p/base/port_allocator_unittest.cc index 836a2fa494..2df8662f62 100644 --- a/p2p/base/port_allocator_unittest.cc +++ b/p2p/base/port_allocator_unittest.cc @@ -26,7 +26,6 @@ static const char kIceUfrag[] = "UF00"; static const char kIcePwd[] = "TESTICEPWD00000000000000"; static const char kTurnUsername[] = "test"; static const char kTurnPassword[] = "test"; -constexpr uint64_t kTiebreakerDefault = 44444; class PortAllocatorTest : public ::testing::Test, public sigslot::has_slots<> { public: @@ -38,9 +37,7 @@ class PortAllocatorTest : public ::testing::Test, public sigslot::has_slots<> { allocator_(std::make_unique( rtc::Thread::Current(), packet_socket_factory_.get(), - &field_trials_)) { - allocator_->SetIceTiebreaker(kTiebreakerDefault); - } + &field_trials_)) {} protected: void SetConfigurationWithPoolSize(int candidate_pool_size) { diff --git a/p2p/base/regathering_controller_unittest.cc b/p2p/base/regathering_controller_unittest.cc index 91b7270f77..573c0fd23f 100644 --- a/p2p/base/regathering_controller_unittest.cc +++ b/p2p/base/regathering_controller_unittest.cc @@ -40,7 +40,6 @@ const rtc::SocketAddress kTurnUdpIntAddr("99.99.99.3", const cricket::RelayCredentials kRelayCredentials("test", "test"); const char kIceUfrag[] = "UF00"; const char kIcePwd[] = "TESTICEPWD00000000000000"; -constexpr uint64_t kTiebreakerDefault = 44444; } // namespace @@ -59,7 +58,6 @@ class RegatheringControllerTest : public ::testing::Test, rtc::Thread::Current(), packet_socket_factory_.get(), &field_trials_)) { - allocator_->SetIceTiebreaker(kTiebreakerDefault); BasicRegatheringController::Config regathering_config; regathering_config.regather_on_failed_networks_interval = 0; regathering_controller_.reset(new BasicRegatheringController( diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc index e95033efeb..92c0ac37f6 100644 --- a/p2p/client/basic_port_allocator.cc +++ b/p2p/client/basic_port_allocator.cc @@ -243,7 +243,7 @@ PortAllocatorSession* BasicPortAllocator::CreateSessionInternal( CheckRunOnValidThreadAndInitialized(); return new BasicPortAllocatorSession(this, std::string(content_name), component, std::string(ice_ufrag), - std::string(ice_pwd)); + std::string(ice_pwd), ice_tiebreaker()); } void BasicPortAllocator::AddTurnServerForTesting( @@ -261,11 +261,13 @@ BasicPortAllocatorSession::BasicPortAllocatorSession( absl::string_view content_name, int component, absl::string_view ice_ufrag, - absl::string_view ice_pwd) + absl::string_view ice_pwd, + uint64_t ice_tiebreaker) : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd, + ice_tiebreaker, allocator->flags()), allocator_(allocator), network_thread_(rtc::Thread::Current()), @@ -281,6 +283,19 @@ BasicPortAllocatorSession::BasicPortAllocatorSession( allocator_->network_manager()->StartUpdating(); } +BasicPortAllocatorSession::BasicPortAllocatorSession( + BasicPortAllocator* allocator, + absl::string_view content_name, + int component, + absl::string_view ice_ufrag, + absl::string_view ice_pwd) + : BasicPortAllocatorSession(allocator, + content_name, + component, + ice_ufrag, + ice_pwd, + 0) {} + BasicPortAllocatorSession::~BasicPortAllocatorSession() { TRACE_EVENT0("webrtc", "BasicPortAllocatorSession::~BasicPortAllocatorSession"); diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h index 25201fd016..1612f77d35 100644 --- a/p2p/client/basic_port_allocator.h +++ b/p2p/client/basic_port_allocator.h @@ -116,6 +116,13 @@ enum class SessionState { // destroyed on the network thread. class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession { public: + BasicPortAllocatorSession(BasicPortAllocator* allocator, + absl::string_view content_name, + int component, + absl::string_view ice_ufrag, + absl::string_view ice_pwd, + uint64_t ice_tiebreaker); + // TODO(bugs.webrtc.org/14605): remove this constructor BasicPortAllocatorSession(BasicPortAllocator* allocator, absl::string_view content_name, int component, diff --git a/p2p/client/basic_port_allocator_unittest.cc b/p2p/client/basic_port_allocator_unittest.cc index 77443eedbb..f77040d128 100644 --- a/p2p/client/basic_port_allocator_unittest.cc +++ b/p2p/client/basic_port_allocator_unittest.cc @@ -112,8 +112,6 @@ static const char kTurnPassword[] = "test"; // Add some margin of error for slow bots. static const int kStunTimeoutMs = cricket::STUN_TOTAL_TIMEOUT; -constexpr uint64_t kTiebreakerDefault = 44444; - namespace { void CheckStunKeepaliveIntervalOfAllReadyPorts( @@ -176,7 +174,6 @@ class BasicPortAllocatorTestBase : public ::testing::Test, &network_manager_, &socket_factory_, stun_servers, &field_trials_); allocator_->Initialize(); allocator_->set_step_delay(kMinimumStepDelay); - allocator_->SetIceTiebreaker(kTiebreakerDefault); webrtc::metrics::Reset(); } @@ -214,7 +211,6 @@ class BasicPortAllocatorTestBase : public ::testing::Test, allocator_.reset( new BasicPortAllocator(&network_manager_, &socket_factory_)); allocator_->Initialize(); - allocator_->SetIceTiebreaker(kTiebreakerDefault); allocator_->set_step_delay(kMinimumStepDelay); } // Endpoint is behind a NAT, with STUN specified. @@ -299,7 +295,6 @@ class BasicPortAllocatorTestBase : public ::testing::Test, this, &BasicPortAllocatorTestBase::OnCandidatesRemoved); session->SignalCandidatesAllocationDone.connect( this, &BasicPortAllocatorTestBase::OnCandidatesAllocationDone); - session->set_ice_tiebreaker(kTiebreakerDefault); return session; } diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index 9473d962ef..d5eb0c633d 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -55,6 +55,7 @@ JsepTransportController::JsepTransportController( }), config_(std::move(config)), active_reset_srtp_params_(config.active_reset_srtp_params), + ice_tiebreaker_(port_allocator ? port_allocator->ice_tiebreaker() : 0), bundles_(config.bundle_policy) { // The `transport_observer` is assumed to be non-null. RTC_DCHECK(config_.transport_observer); @@ -62,9 +63,6 @@ JsepTransportController::JsepTransportController( RTC_DCHECK(config_.ice_transport_factory); RTC_DCHECK(config_.on_dtls_handshake_error_); RTC_DCHECK(config_.field_trials); - if (port_allocator_) { - port_allocator_->SetIceTiebreaker(ice_tiebreaker_); - } } JsepTransportController::~JsepTransportController() { diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h index 448844ac79..7f06c22969 100644 --- a/pc/jsep_transport_controller.h +++ b/pc/jsep_transport_controller.h @@ -507,7 +507,7 @@ class JsepTransportController : public sigslot::has_slots<> { cricket::IceConfig ice_config_; cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING; - uint64_t ice_tiebreaker_ = rtc::CreateRandomId64(); + uint64_t ice_tiebreaker_; rtc::scoped_refptr certificate_; BundleManager bundles_; diff --git a/pc/peer_connection_ice_unittest.cc b/pc/peer_connection_ice_unittest.cc index 492e108cbc..bd4848cf8b 100644 --- a/pc/peer_connection_ice_unittest.cc +++ b/pc/peer_connection_ice_unittest.cc @@ -94,7 +94,6 @@ using ::testing::Values; constexpr int kIceCandidatesTimeout = 10000; constexpr int64_t kWaitTimeout = 10000; -constexpr uint64_t kTiebreakerDefault = 44444; class PeerConnectionWrapperForIceTest : public PeerConnectionWrapper { public: @@ -1448,7 +1447,6 @@ class PeerConnectionIceConfigTest : public ::testing::Test { packet_socket_factory_.get(), &field_trials_)); port_allocator_ = port_allocator.get(); - port_allocator_->SetIceTiebreaker(kTiebreakerDefault); PeerConnectionDependencies pc_dependencies(&observer_); pc_dependencies.allocator = std::move(port_allocator); auto result = pc_factory_->CreatePeerConnectionOrError( diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc index 08fb1632d6..71c85d4c6f 100644 --- a/pc/peer_connection_interface_unittest.cc +++ b/pc/peer_connection_interface_unittest.cc @@ -114,7 +114,6 @@ static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"}; static const char kRecvonly[] = "recvonly"; static const char kSendrecv[] = "sendrecv"; -constexpr uint64_t kTiebreakerDefault = 44444; // Reference SDP with a MediaStream with label "stream1" and audio track with // id "audio_1" and a video track with id "video_1; @@ -711,7 +710,6 @@ class PeerConnectionInterfaceBaseTest : public ::testing::Test { std::make_unique(vss_.get()), &field_trials_)); port_allocator_ = port_allocator.get(); - port_allocator_->SetIceTiebreaker(kTiebreakerDefault); // Create certificate generator unless DTLS constraint is explicitly set to // false. From 9d4961e5964dbaaacdf9376a3339af434a262a07 Mon Sep 17 00:00:00 2001 From: Per K Date: Fri, 9 Feb 2024 13:01:35 +0100 Subject: [PATCH 112/170] Check IsRunning() in VideoSendStreamImpl::SignalEncoderActive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure VideoSendStreamImpl does not register allocation on stray encoded image if there is no active encodings. Bug: chromium:41497180 Change-Id: I32afd7cc71f154dff240934e2be1745d8ead127c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338920 Reviewed-by: Erik Språng Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/main@{#41708} --- video/video_send_stream_impl.cc | 3 +- video/video_send_stream_impl_unittest.cc | 51 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc index 8c748dd81d..ec63b51816 100644 --- a/video/video_send_stream_impl.cc +++ b/video/video_send_stream_impl.cc @@ -522,6 +522,7 @@ VideoSendStreamImpl::~VideoSendStreamImpl() { RTC_DCHECK_RUN_ON(&thread_checker_); RTC_LOG(LS_INFO) << "~VideoSendStreamImpl: " << config_.ToString(); RTC_DCHECK(!started()); + RTC_DCHECK(!IsRunning()); transport_->DestroyRtpVideoSender(rtp_video_sender_); } @@ -764,7 +765,7 @@ void VideoSendStreamImpl::OnVideoLayersAllocationUpdated( void VideoSendStreamImpl::SignalEncoderActive() { RTC_DCHECK_RUN_ON(&thread_checker_); - if (rtp_video_sender_->IsActive()) { + if (IsRunning()) { RTC_LOG(LS_INFO) << "SignalEncoderActive, Encoder is active."; bitrate_allocator_->AddObserver(this, GetAllocationConfig()); } diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc index fe5f999a39..f6b43cb958 100644 --- a/video/video_send_stream_impl_unittest.cc +++ b/video/video_send_stream_impl_unittest.cc @@ -70,6 +70,7 @@ namespace internal { namespace { using ::testing::_; using ::testing::AllOf; +using ::testing::AnyNumber; using ::testing::Field; using ::testing::Invoke; using ::testing::Mock; @@ -271,6 +272,56 @@ TEST_F(VideoSendStreamImplTest, vss_impl->Stop(); } +TEST_F(VideoSendStreamImplTest, + DoNotRegistersAsBitrateObserverOnStrayEncodedImage) { + auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig()); + + EncodedImage encoded_image; + CodecSpecificInfo codec_specific; + ON_CALL(rtp_video_sender_, OnEncodedImage) + .WillByDefault(Return( + EncodedImageCallback::Result(EncodedImageCallback::Result::OK))); + + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)) + .Times(AnyNumber()); + vss_impl->Start(); + time_controller_.AdvanceTime(TimeDelta::Zero()); + + // VideoSendStreamImpl gets an allocated bitrate. + const uint32_t kBitrateBps = 100000; + EXPECT_CALL(rtp_video_sender_, GetPayloadBitrateBps()) + .Times(1) + .WillOnce(Return(kBitrateBps)); + static_cast(vss_impl.get()) + ->OnBitrateUpdated(CreateAllocation(kBitrateBps)); + // A frame is encoded. + encoder_queue_->PostTask([&] { + static_cast(vss_impl.get()) + ->OnEncodedImage(encoded_image, &codec_specific); + }); + + // Expect allocation to be removed if encoder stop producing frames. + EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).Times(1); + time_controller_.AdvanceTime(TimeDelta::Seconds(5)); + Mock::VerifyAndClearExpectations(&bitrate_allocator_); + + EXPECT_CALL(bitrate_allocator_, AddObserver(vss_impl.get(), _)).Times(0); + + VideoEncoderConfig no_active_encodings = TestVideoEncoderConfig(); + no_active_encodings.simulcast_layers[0].active = false; + vss_impl->ReconfigureVideoEncoder(std::move(no_active_encodings)); + + // Expect that allocation in not resumed if a stray encoded image is received. + encoder_queue_->PostTask([&] { + static_cast(vss_impl.get()) + ->OnEncodedImage(encoded_image, &codec_specific); + }); + + time_controller_.AdvanceTime(TimeDelta::Zero()); + + vss_impl->Stop(); +} + TEST_F(VideoSendStreamImplTest, UpdatesObserverOnConfigurationChange) { const bool kSuspend = false; config_.suspend_below_min_bitrate = kSuspend; From d49058e702801d6bbe81f4fd88fa2d1db8d51581 Mon Sep 17 00:00:00 2001 From: Hanna Silen Date: Thu, 14 Dec 2023 17:08:10 +0200 Subject: [PATCH 113/170] AGC2: Enable clipping predictor by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:7494 Change-Id: I36a98ac06230f9bd54055e8177ac28fb9cd11442 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/331540 Commit-Queue: Hanna Silen Reviewed-by: Per Åhgren Reviewed-by: Sam Zackrisson Cr-Commit-Position: refs/heads/main@{#41709} --- modules/audio_processing/agc2/input_volume_controller.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/audio_processing/agc2/input_volume_controller.h b/modules/audio_processing/agc2/input_volume_controller.h index 21405542dc..0bec7af450 100644 --- a/modules/audio_processing/agc2/input_volume_controller.h +++ b/modules/audio_processing/agc2/input_volume_controller.h @@ -50,7 +50,7 @@ class InputVolumeController final { // Limited to values higher than 0. int clipped_wait_frames = 300; // Enables clipping prediction functionality. - bool enable_clipping_predictor = false; + bool enable_clipping_predictor = true; // Speech level target range (dBFS). If the speech level is in the range // [`target_range_min_dbfs`, `target_range_max_dbfs`], no input volume // adjustments are done based on the speech level. For speech levels below From 951372774b350f253b7e12f9480e9fa8aeb98997 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Fri, 9 Feb 2024 06:18:00 -0800 Subject: [PATCH 114/170] Roll chromium_revision d6c15c3939..91eaa36325 (1258371:1258480) Change log: https://chromium.googlesource.com/chromium/src/+log/d6c15c3939..91eaa36325 Full diff: https://chromium.googlesource.com/chromium/src/+/d6c15c3939..91eaa36325 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/2881ff893b..896320bc94 * src/build: https://chromium.googlesource.com/chromium/src/build/+log/c40a759ea4..2304a0bd73 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/909831539c..43bf7f8fe9 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/436ce9d454..4f90ff4a62 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/b5ff79bc56..a25684473e * src/third_party/androidx: 7mJZ3v-PCBM6d2aoz8s5V6ix1M_RJi-94No7oO0IIC0C..G5BlTdQ3N9XCIYScX3yJxRJtxWtNX1Qb1BWkgkh-z6AC * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/c097821eb1..5c64a518b3 DEPS diff: https://chromium.googlesource.com/chromium/src/+/d6c15c3939..91eaa36325/DEPS No update to Clang. BUG=None Change-Id: Id8034528a201b2a9ea964e018ef87c246b8c5bdd Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338960 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41710} --- DEPS | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DEPS b/DEPS index ceba7a29b3..f8fdbdbed5 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'd6c15c3939939e4ae6fbc676952ae6d09351b107', + 'chromium_revision': '91eaa36325fa7173904306198dd63247ff926971', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,9 +50,9 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@2881ff893b77366ddcc72448f9eb705f10e868c5', + 'https://chromium.googlesource.com/chromium/src/base@896320bc941b7acca61fbcce8d8eb12075c9b8cc', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@c40a759ea459e093e168dbbb306b40d830dc9180', + 'https://chromium.googlesource.com/chromium/src/build@2304a0bd73c502019e0346718f31ffffe3ff9321', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@f90248f2bf52549f4110fbda4bb37580e81bc262', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@909831539ceb5438b8e15ca20dc2109c1ae57f44', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@43bf7f8fe903991c5817f55d9ec00d80d3f10b4d', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@436ce9d45438663671e3a10f2b0f7d99f53f1caa', + 'https://chromium.googlesource.com/chromium/src/testing@4f90ff4a62b6e72626c6ba71836d0dfcccc812c7', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@b5ff79bc5651c46cfcafdeb0da5f07d5ef9398ae', + 'https://chromium.googlesource.com/chromium/src/third_party@a25684473e17e795ed36e209ec2e574c260212fa', 'src/buildtools/linux64': { 'packages': [ @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@c097821eb1bd687e7fbe8f432302ce395b26f06d', + 'https://chromium.googlesource.com/chromium/src/tools@5c64a518b3d0a68d33f01814f114953e7b024486', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -405,7 +405,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '7mJZ3v-PCBM6d2aoz8s5V6ix1M_RJi-94No7oO0IIC0C', + 'version': 'G5BlTdQ3N9XCIYScX3yJxRJtxWtNX1Qb1BWkgkh-z6AC', }, ], 'condition': 'checkout_android', From 32f2a30e5e149358d7ddd1ae9818fff339e5f9f5 Mon Sep 17 00:00:00 2001 From: Tommi Date: Thu, 8 Feb 2024 19:16:49 +0100 Subject: [PATCH 115/170] Move IceCandidateType to candidate.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: none Change-Id: I3152d36c379ef0b2c8928a0e5750e012157fd26c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336920 Commit-Queue: Tomas Gunnarsson Reviewed-by: Björn Terelius Cr-Commit-Position: refs/heads/main@{#41711} --- api/candidate.h | 4 ++++ logging/BUILD.gn | 1 + .../events/rtc_event_ice_candidate_pair_config.h | 9 +-------- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/api/candidate.h b/api/candidate.h index d48f4fc559..3fefd1114b 100644 --- a/api/candidate.h +++ b/api/candidate.h @@ -24,6 +24,10 @@ #include "rtc_base/socket_address.h" #include "rtc_base/system/rtc_export.h" +namespace webrtc { +enum class IceCandidateType : int { kHost, kSrflx, kPrflx, kRelay }; +} // namespace webrtc + namespace cricket { // TODO(tommi): These are temporarily here, moved from `port.h` and will diff --git a/logging/BUILD.gn b/logging/BUILD.gn index 415c52789c..117d5c4a3c 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -688,6 +688,7 @@ rtc_library("ice_log") { deps = [ ":rtc_event_field", + "../api:candidate", "../api:dtls_transport_interface", "../api:libjingle_logging_api", "../api/rtc_event_log", diff --git a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h index 14984b324f..8198659cb2 100644 --- a/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h +++ b/logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h @@ -18,6 +18,7 @@ #include #include "absl/strings/string_view.h" +#include "api/candidate.h" #include "api/rtc_event_log/rtc_event.h" #include "api/units/timestamp.h" #include "logging/rtc_event_log/events/rtc_event_field_encoding_parser.h" @@ -32,14 +33,6 @@ enum class IceCandidatePairConfigType { kNumValues, }; -// TODO(tommi): Move this definition to candidate.h. -enum class IceCandidateType { - kHost, - kSrflx, - kPrflx, - kRelay, -}; - enum class IceCandidatePairProtocol { kUnknown, kUdp, From 25cdac7d7ec85b8074aaf709cbbb1a91482693d1 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Fri, 9 Feb 2024 20:07:37 -0800 Subject: [PATCH 116/170] Update WebRTC code version (2024-02-10T04:07:36). Bug: None Change-Id: I313b61596a3772b26ec36fe33024a33c4874b638 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339120 Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41712} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 5a4a798c73..53072c0bb2 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-08T04:02:04"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-10T04:07:36"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 541f202354e2b4906935c8db6e54386aa8bc8d1f Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Tue, 6 Feb 2024 10:56:05 +0100 Subject: [PATCH 117/170] Video capture PipeWire: simplify thread and lock annotations Use only one RaceChecker as intended with the original change. This gets rid of specific RaceChecker for PipeWire members. Make PipeWireSession guarded by API checker instead, since this member is accessed only in [Start/Stop]Capture and move the race checker within PipeWire thread loop lock. Also remove race check from OnStreamStateChanged where we only modify one property guarded by API mutex. Partially reverts a9d497b52dc21497fdfd0e8c03ab2f8559e02d15 reviewed on https://webrtc-review.googlesource.com/c/src/+/326781. Bug: webrtc:15181 Change-Id: I46449fce86611124688a65d5337771c75853f2ca Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338021 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Jan Grulich Cr-Commit-Position: refs/heads/main@{#41713} --- .../linux/video_capture_pipewire.cc | 25 ++++++++++++------- .../linux/video_capture_pipewire.h | 14 +++++------ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/modules/video_capture/linux/video_capture_pipewire.cc b/modules/video_capture/linux/video_capture_pipewire.cc index fb813e331f..8af483636a 100644 --- a/modules/video_capture/linux/video_capture_pipewire.cc +++ b/modules/video_capture/linux/video_capture_pipewire.cc @@ -121,7 +121,6 @@ static spa_pod* BuildFormat(spa_pod_builder* builder, int32_t VideoCaptureModulePipeWire::StartCapture( const VideoCaptureCapability& capability) { - RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); RTC_DCHECK_RUN_ON(&api_checker_); if (initialized_) { @@ -134,10 +133,17 @@ int32_t VideoCaptureModulePipeWire::StartCapture( uint8_t buffer[1024] = {}; + // We don't want members above to be guarded by capture_checker_ as + // it's meant to be for members that are accessed on the API thread + // only when we are not capturing. The code above can be called many + // times while sharing instance of VideoCapturePipeWire between + // websites and therefore it would not follow the requirements of this + // checker. + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); + PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_); + RTC_LOG(LS_VERBOSE) << "Creating new PipeWire stream for node " << node_id_; - PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_); - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); pw_properties* reuse_props = pw_properties_new_string("pipewire.client.reuse=1"); stream_ = pw_stream_new(session_->pw_core_, "camera-stream", reuse_props); @@ -188,11 +194,13 @@ int32_t VideoCaptureModulePipeWire::StartCapture( } int32_t VideoCaptureModulePipeWire::StopCapture() { - RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); RTC_DCHECK_RUN_ON(&api_checker_); PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_); - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); + // PipeWireSession is guarded by API checker so just make sure we do + // race detection when the PipeWire loop is locked/stopped to not run + // any callback at this point. + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); if (stream_) { pw_stream_destroy(stream_); stream_ = nullptr; @@ -225,14 +233,14 @@ void VideoCaptureModulePipeWire::OnStreamParamChanged( VideoCaptureModulePipeWire* that = static_cast(data); RTC_DCHECK(that); - RTC_CHECK_RUNS_SERIALIZED(&that->pipewire_checker_); + RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_); if (format && id == SPA_PARAM_Format) that->OnFormatChanged(format); } void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) { - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); uint32_t media_type, media_subtype; @@ -331,7 +339,6 @@ void VideoCaptureModulePipeWire::OnStreamStateChanged( VideoCaptureModulePipeWire* that = static_cast(data); RTC_DCHECK(that); - RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_); MutexLock lock(&that->api_lock_); switch (state) { @@ -374,7 +381,7 @@ static VideoRotation VideorotationFromPipeWireTransform(uint32_t transform) { } void VideoCaptureModulePipeWire::ProcessBuffers() { - RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_); + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); while (pw_buffer* buffer = pw_stream_dequeue_buffer(stream_)) { struct spa_meta_header* h; diff --git a/modules/video_capture/linux/video_capture_pipewire.h b/modules/video_capture/linux/video_capture_pipewire.h index 5d6794ed65..eeb3b9497c 100644 --- a/modules/video_capture/linux/video_capture_pipewire.h +++ b/modules/video_capture/linux/video_capture_pipewire.h @@ -43,18 +43,16 @@ class VideoCaptureModulePipeWire : public VideoCaptureImpl { void OnFormatChanged(const struct spa_pod* format); void ProcessBuffers(); - rtc::RaceChecker pipewire_checker_; - const rtc::scoped_refptr session_ - RTC_GUARDED_BY(capture_checker_); + RTC_GUARDED_BY(api_checker_); + bool initialized_ RTC_GUARDED_BY(api_checker_); + bool started_ RTC_GUARDED_BY(api_lock_); int node_id_ RTC_GUARDED_BY(capture_checker_); VideoCaptureCapability configured_capability_ - RTC_GUARDED_BY(pipewire_checker_); - bool initialized_ RTC_GUARDED_BY(capture_checker_); - bool started_ RTC_GUARDED_BY(api_lock_); + RTC_GUARDED_BY(capture_checker_); - struct pw_stream* stream_ RTC_GUARDED_BY(pipewire_checker_) = nullptr; - struct spa_hook stream_listener_ RTC_GUARDED_BY(pipewire_checker_); + struct pw_stream* stream_ RTC_GUARDED_BY(capture_checker_) = nullptr; + struct spa_hook stream_listener_ RTC_GUARDED_BY(capture_checker_); }; } // namespace videocapturemodule } // namespace webrtc From 52fec7d3e9c8503d5c7455398784a874a1fed90f Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Sun, 11 Feb 2024 11:26:01 +0100 Subject: [PATCH 118/170] Video capture V4L2: fix wrong usage of capture race checker This RaceChecker is intended to be used on API thread only when we are not capturing, however, since StartCapture() can be called while already capturing, we have to avoid using it to guard members that do not meet this expectations. Use API checker for _captureStarted instead and move the capture race checker down where we can be sure that capturing is not happening. Bug: webrtc:15181 Change-Id: I52f74b893f2c36c3ce0facd053b003fa497101b0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338040 Reviewed-by: Ilya Nikolaevskiy Commit-Queue: Jan Grulich Cr-Commit-Position: refs/heads/main@{#41714} --- .../video_capture/linux/video_capture_v4l2.cc | 19 ++++++++++++++----- .../video_capture/linux/video_capture_v4l2.h | 3 ++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/modules/video_capture/linux/video_capture_v4l2.cc b/modules/video_capture/linux/video_capture_v4l2.cc index 7a70c2ff88..377c1ec878 100644 --- a/modules/video_capture/linux/video_capture_v4l2.cc +++ b/modules/video_capture/linux/video_capture_v4l2.cc @@ -112,7 +112,6 @@ VideoCaptureModuleV4L2::~VideoCaptureModuleV4L2() { int32_t VideoCaptureModuleV4L2::StartCapture( const VideoCaptureCapability& capability) { RTC_DCHECK_RUN_ON(&api_checker_); - RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); if (_captureStarted) { if (capability == _requestedCapability) { @@ -122,6 +121,13 @@ int32_t VideoCaptureModuleV4L2::StartCapture( } } + // We don't want members above to be guarded by capture_checker_ as + // it's meant to be for members that are accessed on the API thread + // only when we are not capturing. The code above can be called many + // times while sharing instance of VideoCaptureV4L2 between websites + // and therefore it would not follow the requirements of this checker. + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); + // Set a baseline of configured parameters. It is updated here during // configuration, then read from the capture thread. configured_capability_ = capability; @@ -283,6 +289,7 @@ int32_t VideoCaptureModuleV4L2::StartCapture( _requestedCapability = capability; _captureStarted = true; + _streaming = true; // start capture thread; if (_captureThread.empty()) { @@ -310,10 +317,12 @@ int32_t VideoCaptureModuleV4L2::StopCapture() { _captureThread.Finalize(); } + _captureStarted = false; + RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); MutexLock lock(&capture_lock_); - if (_captureStarted) { - _captureStarted = false; + if (_streaming) { + _streaming = false; DeAllocateVideoBuffers(); close(_deviceFd); @@ -397,7 +406,7 @@ bool VideoCaptureModuleV4L2::DeAllocateVideoBuffers() { } bool VideoCaptureModuleV4L2::CaptureStarted() { - RTC_CHECK_RUNS_SERIALIZED(&capture_checker_); + RTC_DCHECK_RUN_ON(&api_checker_); return _captureStarted; } @@ -434,7 +443,7 @@ bool VideoCaptureModuleV4L2::CaptureProcess() { return true; } - if (_captureStarted) { + if (_streaming) { struct v4l2_buffer buf; memset(&buf, 0, sizeof(struct v4l2_buffer)); buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; diff --git a/modules/video_capture/linux/video_capture_v4l2.h b/modules/video_capture/linux/video_capture_v4l2.h index 0191e41876..9bc4ce8402 100644 --- a/modules/video_capture/linux/video_capture_v4l2.h +++ b/modules/video_capture/linux/video_capture_v4l2.h @@ -50,7 +50,8 @@ class VideoCaptureModuleV4L2 : public VideoCaptureImpl { int32_t _buffersAllocatedByDevice RTC_GUARDED_BY(capture_lock_); VideoCaptureCapability configured_capability_ RTC_GUARDED_BY(capture_checker_); - bool _captureStarted RTC_GUARDED_BY(capture_checker_); + bool _streaming RTC_GUARDED_BY(capture_checker_); + bool _captureStarted RTC_GUARDED_BY(api_checker_); struct Buffer { void* start; size_t length; From 407367d053dffe4653732e3f6b5acac28caa1382 Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Mon, 12 Feb 2024 08:52:04 +0000 Subject: [PATCH 119/170] Revert "Let port allocator create ice tie breaker" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 3f3f991c03bb4073a06da37c822daaa9deed9307. Reason for revert: API breaking change on PortAllocatorSession. Is it possible to duplicate the ctor of PortAllocatorSession and remove the deprecated one (the one without ice_tiebreaker) in another CL? Original change's description: > Let port allocator create ice tie breaker > > Moves the responsibility for creating the ICE tie breaker from the JSEP transport controller to the port allocator. This will allow a future change to separate the ICE tie breaker (which is sent over the network and hence known to the peer) from the "port allocator random" (that is used to seed the ICE candidate foundation crc32 checksum) as an implementation detail. > > BUG=webrtc:14626 > > Change-Id: I3a9a0980238d6108b1b154f45de2975b08793b1c > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/281660 > Reviewed-by: Harald Alvestrand > Commit-Queue: Philipp Hancke > Cr-Commit-Position: refs/heads/main@{#41707} Bug: webrtc:14626 Change-Id: I342c9a96ac1909244aedea6a7779f5682088a5fc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339280 Bot-Commit: rubber-stamper@appspot.gserviceaccount.com Commit-Queue: Mirko Bonadei Reviewed-by: Björn Terelius Owners-Override: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41715} --- p2p/base/fake_port_allocator.h | 2 +- p2p/base/p2p_transport_channel.cc | 8 +++++--- p2p/base/p2p_transport_channel.h | 2 +- p2p/base/p2p_transport_channel_unittest.cc | 7 +++++++ p2p/base/port_allocator.cc | 12 +++++++++--- p2p/base/port_allocator.h | 16 +++++++++------- p2p/base/port_allocator_unittest.cc | 5 ++++- p2p/base/regathering_controller_unittest.cc | 2 ++ p2p/client/basic_port_allocator.cc | 19 ++----------------- p2p/client/basic_port_allocator.h | 7 ------- p2p/client/basic_port_allocator_unittest.cc | 5 +++++ pc/jsep_transport_controller.cc | 4 +++- pc/jsep_transport_controller.h | 2 +- pc/peer_connection_ice_unittest.cc | 2 ++ pc/peer_connection_interface_unittest.cc | 2 ++ 15 files changed, 53 insertions(+), 42 deletions(-) diff --git a/p2p/base/fake_port_allocator.h b/p2p/base/fake_port_allocator.h index 706635778b..0bb7dd0139 100644 --- a/p2p/base/fake_port_allocator.h +++ b/p2p/base/fake_port_allocator.h @@ -92,7 +92,6 @@ class FakePortAllocatorSession : public PortAllocatorSession { component, ice_ufrag, ice_pwd, - /*kTiebreakerDefault = */ 44444, allocator->flags()), network_thread_(network_thread), factory_(factory), @@ -111,6 +110,7 @@ class FakePortAllocatorSession : public PortAllocatorSession { field_trials_(field_trials) { ipv4_network_.AddIP(rtc::IPAddress(INADDR_LOOPBACK)); ipv6_network_.AddIP(rtc::IPAddress(in6addr_loopback)); + set_ice_tiebreaker(/*kTiebreakerDefault = */ 44444); } void SetCandidateFilter(uint32_t filter) override { diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc index 2f18f1dbb9..0bccb67209 100644 --- a/p2p/base/p2p_transport_channel.cc +++ b/p2p/base/p2p_transport_channel.cc @@ -164,7 +164,7 @@ P2PTransportChannel::P2PTransportChannel( error_(0), remote_ice_mode_(ICEMODE_FULL), ice_role_(ICEROLE_UNKNOWN), - ice_tiebreaker_(0), + tiebreaker_(0), gathering_state_(kIceGatheringNew), weak_ping_interval_(GetWeakPingIntervalInFieldTrial(field_trials)), config_(RECEIVING_TIMEOUT, @@ -326,7 +326,7 @@ void P2PTransportChannel::SetIceTiebreaker(uint64_t tiebreaker) { return; } - ice_tiebreaker_ = tiebreaker; + tiebreaker_ = tiebreaker; } IceTransportState P2PTransportChannel::GetState() const { @@ -885,6 +885,7 @@ void P2PTransportChannel::MaybeStartGathering() { ice_parameters_.ufrag, ice_parameters_.pwd); if (pooled_session) { + pooled_session->set_ice_tiebreaker(tiebreaker_); AddAllocatorSession(std::move(pooled_session)); PortAllocatorSession* raw_pooled_session = allocator_sessions_.back().get(); @@ -901,6 +902,7 @@ void P2PTransportChannel::MaybeStartGathering() { AddAllocatorSession(allocator_->CreateSession( transport_name(), component(), ice_parameters_.ufrag, ice_parameters_.pwd)); + allocator_sessions_.back()->set_ice_tiebreaker(tiebreaker_); allocator_sessions_.back()->StartGettingPorts(); } } @@ -928,7 +930,7 @@ void P2PTransportChannel::OnPortReady(PortAllocatorSession* session, // if one is pending. port->SetIceRole(ice_role_); - port->SetIceTiebreaker(ice_tiebreaker_); + port->SetIceTiebreaker(tiebreaker_); ports_.push_back(port); port->SignalUnknownAddress.connect(this, &P2PTransportChannel::OnUnknownAddress); diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h index f7472df38a..da7933f2e7 100644 --- a/p2p/base/p2p_transport_channel.h +++ b/p2p/base/p2p_transport_channel.h @@ -439,7 +439,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal, RTC_GUARDED_BY(network_thread_); IceMode remote_ice_mode_ RTC_GUARDED_BY(network_thread_); IceRole ice_role_ RTC_GUARDED_BY(network_thread_); - uint64_t ice_tiebreaker_ RTC_GUARDED_BY(network_thread_); + uint64_t tiebreaker_ RTC_GUARDED_BY(network_thread_); IceGatheringState gathering_state_ RTC_GUARDED_BY(network_thread_); std::unique_ptr regathering_controller_ RTC_GUARDED_BY(network_thread_); diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index 79e984cfec..5bcfee0473 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -141,6 +141,7 @@ const cricket::IceParameters kIceParams[4] = { const uint64_t kLowTiebreaker = 11111; const uint64_t kHighTiebreaker = 22222; +const uint64_t kTiebreakerDefault = 44444; cricket::IceConfig CreateIceConfig( int receiving_timeout, @@ -298,6 +299,10 @@ class P2PTransportChannelTestBase : public ::testing::Test, &ep2_.network_manager_, socket_factory_.get(), stun_servers, kTurnUdpIntAddr, rtc::SocketAddress())); + ep1_.SetIceTiebreaker(kTiebreakerDefault); + ep1_.allocator_->SetIceTiebreaker(kTiebreakerDefault); + ep2_.SetIceTiebreaker(kTiebreakerDefault); + ep2_.allocator_->SetIceTiebreaker(kTiebreakerDefault); webrtc::metrics::Reset(); } @@ -3342,6 +3347,7 @@ class P2PTransportChannelPingTest : public ::testing::Test, protected: void PrepareChannel(P2PTransportChannel* ch) { ch->SetIceRole(ICEROLE_CONTROLLING); + ch->SetIceTiebreaker(kTiebreakerDefault); ch->SetIceParameters(kIceParams[0]); ch->SetRemoteIceParameters(kIceParams[1]); ch->SignalNetworkRouteChanged.connect( @@ -3709,6 +3715,7 @@ TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) { &field_trials_); P2PTransportChannel ch("TestChannel", 1, &pa, &field_trials_); ch.SetIceRole(ICEROLE_CONTROLLING); + ch.SetIceTiebreaker(kTiebreakerDefault); ch.SetIceParameters(kIceParams[0]); ch.MaybeStartGathering(); EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(), diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc index 30bcfb1732..3745717510 100644 --- a/p2p/base/port_allocator.cc +++ b/p2p/base/port_allocator.cc @@ -62,7 +62,6 @@ PortAllocatorSession::PortAllocatorSession(absl::string_view content_name, int component, absl::string_view ice_ufrag, absl::string_view ice_pwd, - uint64_t ice_tiebreaker, uint32_t flags) : flags_(flags), generation_(0), @@ -70,7 +69,7 @@ PortAllocatorSession::PortAllocatorSession(absl::string_view content_name, component_(component), ice_ufrag_(ice_ufrag), ice_pwd_(ice_pwd), - ice_tiebreaker_(ice_tiebreaker) { + tiebreaker_(0) { // Pooled sessions are allowed to be created with empty content name, // component, ufrag and password. RTC_DCHECK(ice_ufrag.empty() == ice_pwd.empty()); @@ -102,7 +101,7 @@ PortAllocator::PortAllocator() step_delay_(kDefaultStepDelay), allow_tcp_listen_(true), candidate_filter_(CF_ALL), - tiebreaker_(rtc::CreateRandomId64()) { + tiebreaker_(0) { // The allocator will be attached to a thread in Initialize. thread_checker_.Detach(); } @@ -198,6 +197,13 @@ bool PortAllocator::SetConfiguration( return true; } +void PortAllocator::SetIceTiebreaker(uint64_t tiebreaker) { + tiebreaker_ = tiebreaker; + for (auto& pooled_session : pooled_sessions_) { + pooled_session->set_ice_tiebreaker(tiebreaker_); + } +} + std::unique_ptr PortAllocator::CreateSession( absl::string_view content_name, int component, diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h index e9630df143..b8cffca9c0 100644 --- a/p2p/base/port_allocator.h +++ b/p2p/base/port_allocator.h @@ -199,7 +199,6 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { int component, absl::string_view ice_ufrag, absl::string_view ice_pwd, - uint64_t ice_tiebreaker, uint32_t flags); // Subclasses should clean up any ports created. @@ -213,9 +212,9 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { const std::string& ice_pwd() const { return ice_pwd_; } bool pooled() const { return pooled_; } - // TODO(bugs.webrtc.org/14605): remove once downstream code has been updated. - void set_ice_tiebreaker(uint64_t tiebreaker) { ice_tiebreaker_ = tiebreaker; } - uint64_t ice_tiebreaker() const { return ice_tiebreaker_; } + // TODO(bugs.webrtc.org/14605): move this to the constructor + void set_ice_tiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; } + uint64_t ice_tiebreaker() const { return tiebreaker_; } // Setting this filter should affect not only candidates gathered in the // future, but candidates already gathered and ports already "ready", @@ -330,10 +329,12 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { int component_; std::string ice_ufrag_; std::string ice_pwd_; - uint64_t ice_tiebreaker_; bool pooled_ = false; + // TODO(bugs.webrtc.org/14605): move this to the constructor + uint64_t tiebreaker_; + // SetIceParameters is an implementation detail which only PortAllocator // should be able to call. friend class PortAllocator; @@ -386,6 +387,9 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { const absl::optional& stun_candidate_keepalive_interval = absl::nullopt); + void SetIceTiebreaker(uint64_t tiebreaker); + uint64_t IceTiebreaker() const { return tiebreaker_; } + const ServerAddresses& stun_servers() const { CheckRunOnValidThreadIfInitialized(); return stun_servers_; @@ -457,8 +461,6 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { // 3. mDNS concealment of private IPs is enabled. Candidate SanitizeCandidate(const Candidate& c) const; - uint64_t ice_tiebreaker() const { return tiebreaker_; } - uint32_t flags() const { CheckRunOnValidThreadIfInitialized(); return flags_; diff --git a/p2p/base/port_allocator_unittest.cc b/p2p/base/port_allocator_unittest.cc index 2df8662f62..836a2fa494 100644 --- a/p2p/base/port_allocator_unittest.cc +++ b/p2p/base/port_allocator_unittest.cc @@ -26,6 +26,7 @@ static const char kIceUfrag[] = "UF00"; static const char kIcePwd[] = "TESTICEPWD00000000000000"; static const char kTurnUsername[] = "test"; static const char kTurnPassword[] = "test"; +constexpr uint64_t kTiebreakerDefault = 44444; class PortAllocatorTest : public ::testing::Test, public sigslot::has_slots<> { public: @@ -37,7 +38,9 @@ class PortAllocatorTest : public ::testing::Test, public sigslot::has_slots<> { allocator_(std::make_unique( rtc::Thread::Current(), packet_socket_factory_.get(), - &field_trials_)) {} + &field_trials_)) { + allocator_->SetIceTiebreaker(kTiebreakerDefault); + } protected: void SetConfigurationWithPoolSize(int candidate_pool_size) { diff --git a/p2p/base/regathering_controller_unittest.cc b/p2p/base/regathering_controller_unittest.cc index 573c0fd23f..91b7270f77 100644 --- a/p2p/base/regathering_controller_unittest.cc +++ b/p2p/base/regathering_controller_unittest.cc @@ -40,6 +40,7 @@ const rtc::SocketAddress kTurnUdpIntAddr("99.99.99.3", const cricket::RelayCredentials kRelayCredentials("test", "test"); const char kIceUfrag[] = "UF00"; const char kIcePwd[] = "TESTICEPWD00000000000000"; +constexpr uint64_t kTiebreakerDefault = 44444; } // namespace @@ -58,6 +59,7 @@ class RegatheringControllerTest : public ::testing::Test, rtc::Thread::Current(), packet_socket_factory_.get(), &field_trials_)) { + allocator_->SetIceTiebreaker(kTiebreakerDefault); BasicRegatheringController::Config regathering_config; regathering_config.regather_on_failed_networks_interval = 0; regathering_controller_.reset(new BasicRegatheringController( diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc index 92c0ac37f6..e95033efeb 100644 --- a/p2p/client/basic_port_allocator.cc +++ b/p2p/client/basic_port_allocator.cc @@ -243,7 +243,7 @@ PortAllocatorSession* BasicPortAllocator::CreateSessionInternal( CheckRunOnValidThreadAndInitialized(); return new BasicPortAllocatorSession(this, std::string(content_name), component, std::string(ice_ufrag), - std::string(ice_pwd), ice_tiebreaker()); + std::string(ice_pwd)); } void BasicPortAllocator::AddTurnServerForTesting( @@ -261,13 +261,11 @@ BasicPortAllocatorSession::BasicPortAllocatorSession( absl::string_view content_name, int component, absl::string_view ice_ufrag, - absl::string_view ice_pwd, - uint64_t ice_tiebreaker) + absl::string_view ice_pwd) : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd, - ice_tiebreaker, allocator->flags()), allocator_(allocator), network_thread_(rtc::Thread::Current()), @@ -283,19 +281,6 @@ BasicPortAllocatorSession::BasicPortAllocatorSession( allocator_->network_manager()->StartUpdating(); } -BasicPortAllocatorSession::BasicPortAllocatorSession( - BasicPortAllocator* allocator, - absl::string_view content_name, - int component, - absl::string_view ice_ufrag, - absl::string_view ice_pwd) - : BasicPortAllocatorSession(allocator, - content_name, - component, - ice_ufrag, - ice_pwd, - 0) {} - BasicPortAllocatorSession::~BasicPortAllocatorSession() { TRACE_EVENT0("webrtc", "BasicPortAllocatorSession::~BasicPortAllocatorSession"); diff --git a/p2p/client/basic_port_allocator.h b/p2p/client/basic_port_allocator.h index 1612f77d35..25201fd016 100644 --- a/p2p/client/basic_port_allocator.h +++ b/p2p/client/basic_port_allocator.h @@ -116,13 +116,6 @@ enum class SessionState { // destroyed on the network thread. class RTC_EXPORT BasicPortAllocatorSession : public PortAllocatorSession { public: - BasicPortAllocatorSession(BasicPortAllocator* allocator, - absl::string_view content_name, - int component, - absl::string_view ice_ufrag, - absl::string_view ice_pwd, - uint64_t ice_tiebreaker); - // TODO(bugs.webrtc.org/14605): remove this constructor BasicPortAllocatorSession(BasicPortAllocator* allocator, absl::string_view content_name, int component, diff --git a/p2p/client/basic_port_allocator_unittest.cc b/p2p/client/basic_port_allocator_unittest.cc index f77040d128..77443eedbb 100644 --- a/p2p/client/basic_port_allocator_unittest.cc +++ b/p2p/client/basic_port_allocator_unittest.cc @@ -112,6 +112,8 @@ static const char kTurnPassword[] = "test"; // Add some margin of error for slow bots. static const int kStunTimeoutMs = cricket::STUN_TOTAL_TIMEOUT; +constexpr uint64_t kTiebreakerDefault = 44444; + namespace { void CheckStunKeepaliveIntervalOfAllReadyPorts( @@ -174,6 +176,7 @@ class BasicPortAllocatorTestBase : public ::testing::Test, &network_manager_, &socket_factory_, stun_servers, &field_trials_); allocator_->Initialize(); allocator_->set_step_delay(kMinimumStepDelay); + allocator_->SetIceTiebreaker(kTiebreakerDefault); webrtc::metrics::Reset(); } @@ -211,6 +214,7 @@ class BasicPortAllocatorTestBase : public ::testing::Test, allocator_.reset( new BasicPortAllocator(&network_manager_, &socket_factory_)); allocator_->Initialize(); + allocator_->SetIceTiebreaker(kTiebreakerDefault); allocator_->set_step_delay(kMinimumStepDelay); } // Endpoint is behind a NAT, with STUN specified. @@ -295,6 +299,7 @@ class BasicPortAllocatorTestBase : public ::testing::Test, this, &BasicPortAllocatorTestBase::OnCandidatesRemoved); session->SignalCandidatesAllocationDone.connect( this, &BasicPortAllocatorTestBase::OnCandidatesAllocationDone); + session->set_ice_tiebreaker(kTiebreakerDefault); return session; } diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index d5eb0c633d..9473d962ef 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -55,7 +55,6 @@ JsepTransportController::JsepTransportController( }), config_(std::move(config)), active_reset_srtp_params_(config.active_reset_srtp_params), - ice_tiebreaker_(port_allocator ? port_allocator->ice_tiebreaker() : 0), bundles_(config.bundle_policy) { // The `transport_observer` is assumed to be non-null. RTC_DCHECK(config_.transport_observer); @@ -63,6 +62,9 @@ JsepTransportController::JsepTransportController( RTC_DCHECK(config_.ice_transport_factory); RTC_DCHECK(config_.on_dtls_handshake_error_); RTC_DCHECK(config_.field_trials); + if (port_allocator_) { + port_allocator_->SetIceTiebreaker(ice_tiebreaker_); + } } JsepTransportController::~JsepTransportController() { diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h index 7f06c22969..448844ac79 100644 --- a/pc/jsep_transport_controller.h +++ b/pc/jsep_transport_controller.h @@ -507,7 +507,7 @@ class JsepTransportController : public sigslot::has_slots<> { cricket::IceConfig ice_config_; cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING; - uint64_t ice_tiebreaker_; + uint64_t ice_tiebreaker_ = rtc::CreateRandomId64(); rtc::scoped_refptr certificate_; BundleManager bundles_; diff --git a/pc/peer_connection_ice_unittest.cc b/pc/peer_connection_ice_unittest.cc index bd4848cf8b..492e108cbc 100644 --- a/pc/peer_connection_ice_unittest.cc +++ b/pc/peer_connection_ice_unittest.cc @@ -94,6 +94,7 @@ using ::testing::Values; constexpr int kIceCandidatesTimeout = 10000; constexpr int64_t kWaitTimeout = 10000; +constexpr uint64_t kTiebreakerDefault = 44444; class PeerConnectionWrapperForIceTest : public PeerConnectionWrapper { public: @@ -1447,6 +1448,7 @@ class PeerConnectionIceConfigTest : public ::testing::Test { packet_socket_factory_.get(), &field_trials_)); port_allocator_ = port_allocator.get(); + port_allocator_->SetIceTiebreaker(kTiebreakerDefault); PeerConnectionDependencies pc_dependencies(&observer_); pc_dependencies.allocator = std::move(port_allocator); auto result = pc_factory_->CreatePeerConnectionOrError( diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc index 71c85d4c6f..08fb1632d6 100644 --- a/pc/peer_connection_interface_unittest.cc +++ b/pc/peer_connection_interface_unittest.cc @@ -114,6 +114,7 @@ static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"}; static const char kRecvonly[] = "recvonly"; static const char kSendrecv[] = "sendrecv"; +constexpr uint64_t kTiebreakerDefault = 44444; // Reference SDP with a MediaStream with label "stream1" and audio track with // id "audio_1" and a video track with id "video_1; @@ -710,6 +711,7 @@ class PeerConnectionInterfaceBaseTest : public ::testing::Test { std::make_unique(vss_.get()), &field_trials_)); port_allocator_ = port_allocator.get(); + port_allocator_->SetIceTiebreaker(kTiebreakerDefault); // Create certificate generator unless DTLS constraint is explicitly set to // false. From 1b5f47f2d3755d54d8688a50beee70033eedec1e Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Fri, 2 Feb 2024 17:20:34 +0100 Subject: [PATCH 120/170] Set field trials via command line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fix an issue with accessing an unset optional. Bug: webrtc:14852 Change-Id: I45da8c6add87ac562c3c3f3d11c0021244927f8d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337580 Reviewed-by: Mirko Bonadei Reviewed-by: Åsa Persson Commit-Queue: Sergey Silkin Cr-Commit-Position: refs/heads/main@{#41716} --- modules/video_coding/BUILD.gn | 1 + modules/video_coding/codecs/test/video_codec_test.cc | 7 ++++++- test/video_codec_tester.cc | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 5256c02e70..e926ff84d7 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -1014,6 +1014,7 @@ if (rtc_include_tests) { "../../modules/video_coding/svc:scalability_mode_util", "../../rtc_base:logging", "../../rtc_base:stringutils", + "../../test:explicit_key_value_config", "../../test:fileutils", "../../test:test_flags", "../../test:test_main", diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc index d5c7b51484..b6d5967589 100644 --- a/modules/video_coding/codecs/test/video_codec_test.cc +++ b/modules/video_coding/codecs/test/video_codec_test.cc @@ -28,6 +28,7 @@ #include "modules/video_coding/svc/scalability_mode_util.h" #include "rtc_base/logging.h" #include "rtc_base/strings/string_builder.h" +#include "test/explicit_key_value_config.h" #include "test/gtest.h" #include "test/test_flags.h" #include "test/testsupport/file_utils.h" @@ -60,6 +61,7 @@ ABSL_FLAG(double, 30.0, "Encode target frame rate of the top temporal layer in fps."); ABSL_FLAG(int, num_frames, 300, "Number of frames to encode and/or decode."); +ABSL_FLAG(std::string, field_trials, "", "Field trials to apply."); ABSL_FLAG(std::string, test_name, "", "Test name."); ABSL_FLAG(bool, dump_decoder_input, false, "Dump decoder input."); ABSL_FLAG(bool, dump_decoder_output, false, "Dump decoder output."); @@ -531,7 +533,10 @@ INSTANTIATE_TEST_SUITE_P( FramerateAdaptationTest::TestParamsToString); TEST(VideoCodecTest, DISABLED_EncodeDecode) { - const Environment env = CreateEnvironment(); + const Environment env = + CreateEnvironment(std::make_unique( + absl::GetFlag(FLAGS_field_trials))); + std::vector bitrate_str = absl::GetFlag(FLAGS_bitrate_kbps); std::vector bitrate_kbps; std::transform(bitrate_str.begin(), bitrate_str.end(), diff --git a/test/video_codec_tester.cc b/test/video_codec_tester.cc index e7674dfdab..9aef46d44e 100644 --- a/test/video_codec_tester.cc +++ b/test/video_codec_tester.cc @@ -985,7 +985,8 @@ class Encoder : public EncodedImageCallback { // layer >X receive encoded lower layers. int num_spatial_layers = ScalabilityModeToNumSpatialLayers(last_superframe_->scalability_mode); - for (int sidx = *last_superframe_->encoded_frame.SpatialIndex() + 1; + for (int sidx = + last_superframe_->encoded_frame.SpatialIndex().value_or(0) + 1; sidx < num_spatial_layers; ++sidx) { last_superframe_->encoded_frame.SetSpatialIndex(sidx); DeliverEncodedFrame(last_superframe_->encoded_frame); From 24ad9112102d4279c2e28ce6f4997ffdb94be9af Mon Sep 17 00:00:00 2001 From: Hanna Silen Date: Fri, 9 Feb 2024 17:35:39 +0200 Subject: [PATCH 121/170] Use num_output_channels() in GainController2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace num_proc_channels() with num_output_channels() in GainController2. The number of channels is only used in InputVolumeController. Bug: webrtc:7494 Change-Id: I6b3f66980a518401fefab304e18c9910eee28d4e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338922 Reviewed-by: Per Åhgren Commit-Queue: Hanna Silen Cr-Commit-Position: refs/heads/main@{#41717} --- modules/audio_processing/audio_processing_impl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 0104e0c486..0d11e418e6 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -2381,7 +2381,7 @@ void AudioProcessingImpl::InitializeGainController2() { !UseApmVadSubModule(config_, gain_controller2_experiment_params_); submodules_.gain_controller2 = std::make_unique( config_.gain_controller2, input_volume_controller_config, - proc_fullband_sample_rate_hz(), num_proc_channels(), use_internal_vad); + proc_fullband_sample_rate_hz(), num_output_channels(), use_internal_vad); submodules_.gain_controller2->SetCaptureOutputUsed( capture_.capture_output_used); } From cd81d55fec7b4ca0cc2f6e31e2045ccfc8d65239 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 12 Feb 2024 04:01:29 -0800 Subject: [PATCH 122/170] Roll chromium_revision 91eaa36325..f53e0380af (1258480:1259106) Change log: https://chromium.googlesource.com/chromium/src/+log/91eaa36325..f53e0380af Full diff: https://chromium.googlesource.com/chromium/src/+/91eaa36325..f53e0380af Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/896320bc94..a3c0545d76 * src/build: https://chromium.googlesource.com/chromium/src/build/+log/2304a0bd73..100a2e5828 * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/43bf7f8fe9..7d8367c78c * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/4f90ff4a62..24fb660f29 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/a25684473e..513fca12d3 * src/third_party/androidx: G5BlTdQ3N9XCIYScX3yJxRJtxWtNX1Qb1BWkgkh-z6AC..0Jfh-EIa7YBsv86pah7juYpkhvYjTk-Og860SJavIM0C * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/6e8cde260d..4495ac19ba * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/05048d2cb0..32769fe939 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/ec59b08ccb..3d959a6b84 * src/third_party/r8: aRZW4VFdf45KlLTJNNkZ-Z8f_PTxChr6X3Nqhjth-FEC..Ms1b55b8kRNZqqskNs35JxAgZvqbtKGKDimgS_0LGz4C * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/5c64a518b3..daa8c430f1 DEPS diff: https://chromium.googlesource.com/chromium/src/+/91eaa36325..f53e0380af/DEPS No update to Clang. BUG=None Change-Id: I7a4c32e3606716e796311ed1d4dd73f6151a0f79 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339340 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41718} --- DEPS | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/DEPS b/DEPS index f8fdbdbed5..4c8c5c7965 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '91eaa36325fa7173904306198dd63247ff926971', + 'chromium_revision': 'f53e0380af68a8d94163346b451d257db8d59ddc', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,9 +50,9 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@896320bc941b7acca61fbcce8d8eb12075c9b8cc', + 'https://chromium.googlesource.com/chromium/src/base@a3c0545d76119aed96d3ed6775c17f6541b39815', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@2304a0bd73c502019e0346718f31ffffe3ff9321', + 'https://chromium.googlesource.com/chromium/src/build@100a2e5828c11e1d67f01faa8e761f6479f650b6', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@f90248f2bf52549f4110fbda4bb37580e81bc262', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@43bf7f8fe903991c5817f55d9ec00d80d3f10b4d', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@7d8367c78cfa1664531673e52a0d58a949d0eca8', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@4f90ff4a62b6e72626c6ba71836d0dfcccc812c7', + 'https://chromium.googlesource.com/chromium/src/testing@24fb660f299e140977bc4281abbf5d5cc85ff6a9', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@a25684473e17e795ed36e209ec2e574c260212fa', + 'https://chromium.googlesource.com/chromium/src/third_party@513fca12d3d735c92f9913493df0fb92a1988517', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@6e8cde260d37919476e838483bcef14a29e356bf', + 'https://chromium.googlesource.com/catapult.git@4495ac19babd1c6d43f083ddcfe342e58c5bdb95', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@05048d2cb05cc9a801d5af8ca02a16a34edd74f9', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@32769fe9391bcbe32eba867db2b358d47c170562', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@ec59b08ccb4d733b4f3fd3299c825dbbd0e56282', + 'https://android.googlesource.com/platform/external/perfetto.git@3d959a6b84994746c9a357c58516ac8a53299b77', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@96b64eaac5adbac59e43e34d87af3ba0fb06bca6', 'src/third_party/libyuv': @@ -331,7 +331,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'aRZW4VFdf45KlLTJNNkZ-Z8f_PTxChr6X3Nqhjth-FEC', + 'version': 'Ms1b55b8kRNZqqskNs35JxAgZvqbtKGKDimgS_0LGz4C', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@5c64a518b3d0a68d33f01814f114953e7b024486', + 'https://chromium.googlesource.com/chromium/src/tools@daa8c430f199f0038c7d606aad90e4a1b1d897d1', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -405,7 +405,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'G5BlTdQ3N9XCIYScX3yJxRJtxWtNX1Qb1BWkgkh-z6AC', + 'version': '0Jfh-EIa7YBsv86pah7juYpkhvYjTk-Og860SJavIM0C', }, ], 'condition': 'checkout_android', From 1cce1d7ddcbde3a3648007b5a131bd0c2638724b Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Fri, 2 Feb 2024 10:14:39 +0100 Subject: [PATCH 123/170] Make setCodecPreferences only look at receive codecs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit which is what is noted in JSEP: https://www.rfc-editor.org/rfc/rfc8829.html#name-setcodecpreferences Some W3C spec modifications are required since the W3C specification currently takes into account send codecs as well. Spec issue: https://github.com/w3c/webrtc-pc/issues/2888 Spec PR: https://github.com/w3c/webrtc-pc/pull/2926 setCodecPreferences continues to modify the codecs in an offer. Also rename RtpSender::SetCodecPreferences to RtpSender::SetSendCodecs for consistent semantics. BUG=webrtc:15396 Change-Id: I1e8fbe77cb2670575578a777ed1336567a1e4031 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/328780 Reviewed-by: Henrik Boström Commit-Queue: Philipp Hancke Reviewed-by: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41719} --- media/base/media_engine.cc | 18 +- media/base/media_engine.h | 6 +- ...er_connection_encodings_integrationtest.cc | 166 +++++++++--------- pc/peer_connection_media_unittest.cc | 23 --- pc/peer_connection_svc_integrationtest.cc | 27 +-- pc/rtp_sender.cc | 14 +- pc/rtp_sender.h | 10 +- pc/rtp_transceiver.cc | 69 ++------ pc/test/mock_rtp_sender_internal.h | 2 +- 9 files changed, 117 insertions(+), 218 deletions(-) diff --git a/media/base/media_engine.cc b/media/base/media_engine.cc index 7304ab03d7..c551a58cf9 100644 --- a/media/base/media_engine.cc +++ b/media/base/media_engine.cc @@ -67,11 +67,11 @@ std::vector GetDefaultEnabledRtpHeaderExtensions( webrtc::RTCError CheckScalabilityModeValues( const webrtc::RtpParameters& rtp_parameters, - rtc::ArrayView codec_preferences, + rtc::ArrayView send_codecs, absl::optional send_codec) { using webrtc::RTCErrorType; - if (codec_preferences.empty()) { + if (send_codecs.empty()) { // This is an audio sender or an extra check in the stack where the codec // list is not available and we can't check the scalability_mode values. return webrtc::RTCError::OK(); @@ -80,7 +80,7 @@ webrtc::RTCError CheckScalabilityModeValues( for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) { if (rtp_parameters.encodings[i].codec) { bool codecFound = false; - for (const cricket::VideoCodec& codec : codec_preferences) { + for (const cricket::Codec& codec : send_codecs) { if (codec.MatchesRtpCodec(*rtp_parameters.encodings[i].codec)) { codecFound = true; send_codec = codec; @@ -97,7 +97,7 @@ webrtc::RTCError CheckScalabilityModeValues( if (rtp_parameters.encodings[i].scalability_mode) { if (!send_codec) { bool scalabilityModeFound = false; - for (const cricket::VideoCodec& codec : codec_preferences) { + for (const cricket::Codec& codec : send_codecs) { for (const auto& scalability_mode : codec.scalability_modes) { if (ScalabilityModeToString(scalability_mode) == *rtp_parameters.encodings[i].scalability_mode) { @@ -139,7 +139,7 @@ webrtc::RTCError CheckScalabilityModeValues( webrtc::RTCError CheckRtpParametersValues( const webrtc::RtpParameters& rtp_parameters, - rtc::ArrayView codec_preferences, + rtc::ArrayView send_codecs, absl::optional send_codec) { using webrtc::RTCErrorType; @@ -196,8 +196,7 @@ webrtc::RTCError CheckRtpParametersValues( } } - return CheckScalabilityModeValues(rtp_parameters, codec_preferences, - send_codec); + return CheckScalabilityModeValues(rtp_parameters, send_codecs, send_codec); } webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( @@ -210,7 +209,7 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( const webrtc::RtpParameters& old_rtp_parameters, const webrtc::RtpParameters& rtp_parameters, - rtc::ArrayView codec_preferences, + rtc::ArrayView send_codecs, absl::optional send_codec) { using webrtc::RTCErrorType; if (rtp_parameters.encodings.size() != old_rtp_parameters.encodings.size()) { @@ -246,8 +245,7 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( "Attempted to set RtpParameters with modified SSRC"); } - return CheckRtpParametersValues(rtp_parameters, codec_preferences, - send_codec); + return CheckRtpParametersValues(rtp_parameters, send_codecs, send_codec); } CompositeMediaEngine::CompositeMediaEngine( diff --git a/media/base/media_engine.h b/media/base/media_engine.h index 428123516f..b054893163 100644 --- a/media/base/media_engine.h +++ b/media/base/media_engine.h @@ -42,14 +42,14 @@ namespace cricket { // least one video codec of the list. If the list is empty, no check is done. webrtc::RTCError CheckScalabilityModeValues( const webrtc::RtpParameters& new_parameters, - rtc::ArrayView codec_preferences, + rtc::ArrayView send_codecs, absl::optional send_codec); // Checks the parameters have valid and supported values, and checks parameters // with CheckScalabilityModeValues(). webrtc::RTCError CheckRtpParametersValues( const webrtc::RtpParameters& new_parameters, - rtc::ArrayView codec_preferences, + rtc::ArrayView send_codecs, absl::optional send_codec); // Checks that the immutable values have not changed in new_parameters and @@ -57,7 +57,7 @@ webrtc::RTCError CheckRtpParametersValues( webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( const webrtc::RtpParameters& old_parameters, const webrtc::RtpParameters& new_parameters, - rtc::ArrayView codec_preferences, + rtc::ArrayView send_codecs, absl::optional send_codec); // Checks that the immutable values have not changed in new_parameters and diff --git a/pc/peer_connection_encodings_integrationtest.cc b/pc/peer_connection_encodings_integrationtest.cc index 06299d7029..d6c4499210 100644 --- a/pc/peer_connection_encodings_integrationtest.cc +++ b/pc/peer_connection_encodings_integrationtest.cc @@ -134,12 +134,12 @@ class PeerConnectionEncodingsIntegrationTest : public ::testing::Test { return transceiver_or_error.value(); } - bool HasSenderVideoCodecCapability( + bool HasReceiverVideoCodecCapability( rtc::scoped_refptr pc_wrapper, absl::string_view codec_name) { std::vector codecs = pc_wrapper->pc_factory() - ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) + ->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO) .codecs; return std::find_if(codecs.begin(), codecs.end(), [&codec_name](const RtpCodecCapability& codec) { @@ -152,7 +152,7 @@ class PeerConnectionEncodingsIntegrationTest : public ::testing::Test { absl::string_view codec_name) { std::vector codecs = pc_wrapper->pc_factory() - ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) + ->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO) .codecs; codecs.erase(std::remove_if(codecs.begin(), codecs.end(), [&codec_name](const RtpCodecCapability& codec) { @@ -431,7 +431,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP8"); transceiver->SetCodecPreferences(codecs); NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); @@ -464,10 +464,14 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, rtc::scoped_refptr transceiver = AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); - // Restricting codecs restricts what SetParameters() will accept or reject. + // Restricting the local receive codecs will restrict what we offer and + // hence the answer if it is a subset of our offer. std::vector codecs = GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); transceiver->SetCodecPreferences(codecs); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); + // Attempt SVC (L3T3_KEY). This is not possible because only VP8 is up for // negotiation and VP8 does not support it. rtc::scoped_refptr sender = transceiver->sender(); @@ -481,7 +485,6 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, ASSERT_EQ(parameters.encodings.size(), 1u); EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt)); - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); local_pc_wrapper->WaitForConnection(); remote_pc_wrapper->WaitForConnection(); @@ -502,6 +505,60 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt)); } +TEST_F(PeerConnectionEncodingsIntegrationTest, + SetParametersWithScalabilityModeNotSupportedBySubsequentNegotiation) { + rtc::scoped_refptr local_pc_wrapper = CreatePc(); + rtc::scoped_refptr remote_pc_wrapper = CreatePc(); + ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper); + + std::vector layers = + CreateLayers({"f"}, /*active=*/true); + rtc::scoped_refptr transceiver = + AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, + layers); + // Restricting the local receive codecs will restrict what we offer and + // hence the answer if it is a subset of our offer. + std::vector codecs = + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); + transceiver->SetCodecPreferences(codecs); + + // Attempt SVC (L3T3_KEY). This is still possible because VP9 might be + // available from the remote end. + rtc::scoped_refptr sender = transceiver->sender(); + RtpParameters parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + parameters.encodings[0].scalability_mode = "L3T3_KEY"; + parameters.encodings[0].scale_resolution_down_by = 1; + EXPECT_TRUE(sender->SetParameters(parameters).ok()); + + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); + + // `scalability_mode` is set to the VP8 default since that is what was + // negotiated. + parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq("L1T2")); + + local_pc_wrapper->WaitForConnection(); + remote_pc_wrapper->WaitForConnection(); + + // Wait until media is flowing. + ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), + kDefaultTimeout.ms()); + // When `scalability_mode` is not set, VP8 defaults to L1T1. + rtc::scoped_refptr report = GetStats(local_pc_wrapper); + std::vector outbound_rtps = + report->GetStatsOfType(); + ASSERT_THAT(outbound_rtps, SizeIs(1u)); + EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), + StrCaseEq("video/VP8")); + EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T2")); + // GetParameters() confirms `scalability_mode` is still not set. + parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq("L1T2")); +} + TEST_F(PeerConnectionEncodingsIntegrationTest, VP8_FallbackFromSvcResultsInL1T2) { rtc::scoped_refptr local_pc_wrapper = CreatePc(); @@ -558,6 +615,13 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), StrCaseEq("video/VP8")); EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T2")); + + // Now that we know VP8 is used, try setting L3T3 which should fail. + parameters = sender->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + parameters.encodings[0].scalability_mode = "L3T3_KEY"; + parameters.encodings[0].scale_resolution_down_by = 1; + EXPECT_FALSE(sender->SetParameters(parameters).ok()); } // The legacy SVC path is triggered when VP9 us used, but `scalability_mode` has @@ -577,7 +641,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); @@ -622,7 +686,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Configure SVC, a.k.a. "L3T3_KEY". rtc::scoped_refptr sender = transceiver->sender(); @@ -675,7 +739,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Configure SVC, a.k.a. "L3T3_KEY". rtc::scoped_refptr sender = transceiver->sender(); @@ -725,7 +789,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // The original negotiation triggers legacy SVC because we didn't specify @@ -780,7 +844,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Legacy SVC mode and all layers inactive. @@ -817,7 +881,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Standard mode and all layers inactive. @@ -857,7 +921,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, VP9_TargetBitrate_LegacyL1T3) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // In legacy SVC, disabling the bottom two layers encodings is interpreted as @@ -904,7 +968,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, VP9_TargetBitrate_StandardL1T3) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // With standard APIs, L1T3 is explicitly specified and the encodings refers @@ -955,7 +1019,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP8"); transceiver->SetCodecPreferences(codecs); NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); @@ -1364,72 +1428,6 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION); } -TEST_F(PeerConnectionEncodingsIntegrationTest, - SetParametersRejectsNonPreferredCodecParameterAudio) { - rtc::scoped_refptr local_pc_wrapper = CreatePc(); - - absl::optional opus = - local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO, - "opus"); - ASSERT_TRUE(opus); - - std::vector not_opus_codecs = - local_pc_wrapper->pc_factory() - ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO) - .codecs; - not_opus_codecs.erase( - std::remove_if(not_opus_codecs.begin(), not_opus_codecs.end(), - [&](const auto& codec) { - return absl::EqualsIgnoreCase(codec.name, opus->name); - }), - not_opus_codecs.end()); - - auto transceiver_or_error = - local_pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO); - ASSERT_TRUE(transceiver_or_error.ok()); - rtc::scoped_refptr audio_transceiver = - transceiver_or_error.MoveValue(); - ASSERT_TRUE(audio_transceiver->SetCodecPreferences(not_opus_codecs).ok()); - - RtpParameters parameters = audio_transceiver->sender()->GetParameters(); - parameters.encodings[0].codec = opus; - RTCError error = audio_transceiver->sender()->SetParameters(parameters); - EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION); -} - -TEST_F(PeerConnectionEncodingsIntegrationTest, - SetParametersRejectsNonPreferredCodecParameterVideo) { - rtc::scoped_refptr local_pc_wrapper = CreatePc(); - - absl::optional vp8 = - local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO, - "vp8"); - ASSERT_TRUE(vp8); - - std::vector not_vp8_codecs = - local_pc_wrapper->pc_factory() - ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) - .codecs; - not_vp8_codecs.erase( - std::remove_if(not_vp8_codecs.begin(), not_vp8_codecs.end(), - [&](const auto& codec) { - return absl::EqualsIgnoreCase(codec.name, vp8->name); - }), - not_vp8_codecs.end()); - - auto transceiver_or_error = - local_pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO); - ASSERT_TRUE(transceiver_or_error.ok()); - rtc::scoped_refptr video_transceiver = - transceiver_or_error.MoveValue(); - ASSERT_TRUE(video_transceiver->SetCodecPreferences(not_vp8_codecs).ok()); - - RtpParameters parameters = video_transceiver->sender()->GetParameters(); - parameters.encodings[0].codec = vp8; - RTCError error = video_transceiver->sender()->SetParameters(parameters); - EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION); -} - TEST_F(PeerConnectionEncodingsIntegrationTest, SetParametersRejectsNonNegotiatedCodecParameterAudio) { rtc::scoped_refptr local_pc_wrapper = CreatePc(); @@ -1875,7 +1873,7 @@ class PeerConnectionEncodingsIntegrationParameterizedTest bool SkipTestDueToAv1Missing( rtc::scoped_refptr local_pc_wrapper) { if (codec_name_ == "AV1" && - !HasSenderVideoCodecCapability(local_pc_wrapper, "AV1")) { + !HasReceiverVideoCodecCapability(local_pc_wrapper, "AV1")) { RTC_LOG(LS_WARNING) << "\n***\nAV1 is not available, skipping test.\n***"; return true; } @@ -1901,7 +1899,7 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, AllLayersInactive) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, codec_name_); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_); transceiver->SetCodecPreferences(codecs); // Standard mode and all layers inactive. @@ -1944,7 +1942,7 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, Simulcast) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, codec_name_); + GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_); transceiver->SetCodecPreferences(codecs); rtc::scoped_refptr sender = transceiver->sender(); diff --git a/pc/peer_connection_media_unittest.cc b/pc/peer_connection_media_unittest.cc index b892eacb78..04fb9c9e26 100644 --- a/pc/peer_connection_media_unittest.cc +++ b/pc/peer_connection_media_unittest.cc @@ -1547,29 +1547,6 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type()); } -TEST_F(PeerConnectionMediaTestUnifiedPlan, - SetCodecPreferencesAudioMissingSendCodec) { - auto fake_engine = std::make_unique(); - auto recv_codecs = fake_engine->voice().recv_codecs(); - recv_codecs.push_back(cricket::CreateAudioCodec(recv_codecs.back().id + 1, - "recv_only_codec", 0, 1)); - fake_engine->SetAudioRecvCodecs(recv_codecs); - auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine)); - - auto transceiver = caller->pc()->GetTransceivers().front(); - auto capabilities = caller->pc_factory()->GetRtpReceiverCapabilities( - cricket::MediaType::MEDIA_TYPE_AUDIO); - - std::vector codecs; - absl::c_copy_if(capabilities.codecs, std::back_inserter(codecs), - [](const RtpCodecCapability& codec) { - return codec.name.find("_only_") != std::string::npos; - }); - - auto result = transceiver->SetCodecPreferences(codecs); - EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type()); -} - TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesAudioRejectsVideoCodec) { auto caller = CreatePeerConnectionWithAudio(); diff --git a/pc/peer_connection_svc_integrationtest.cc b/pc/peer_connection_svc_integrationtest.cc index 32ca451866..7deafbf428 100644 --- a/pc/peer_connection_svc_integrationtest.cc +++ b/pc/peer_connection_svc_integrationtest.cc @@ -40,7 +40,7 @@ class PeerConnectionSVCIntegrationTest rtc::scoped_refptr transceiver, absl::string_view codec_name) { RtpCapabilities capabilities = - caller()->pc_factory()->GetRtpSenderCapabilities( + caller()->pc_factory()->GetRtpReceiverCapabilities( cricket::MEDIA_TYPE_VIDEO); std::vector codecs; for (const RtpCodecCapability& codec_capability : capabilities.codecs) { @@ -95,7 +95,7 @@ TEST_F(PeerConnectionSVCIntegrationTest, SetParametersAcceptsL1T3WithVP8) { ConnectFakeSignaling(); RtpCapabilities capabilities = - caller()->pc_factory()->GetRtpSenderCapabilities( + caller()->pc_factory()->GetRtpReceiverCapabilities( cricket::MEDIA_TYPE_VIDEO); std::vector vp8_codec; for (const RtpCodecCapability& codec_capability : capabilities.codecs) { @@ -119,27 +119,6 @@ TEST_F(PeerConnectionSVCIntegrationTest, SetParametersAcceptsL1T3WithVP8) { EXPECT_TRUE(result.ok()); } -TEST_F(PeerConnectionSVCIntegrationTest, SetParametersRejectsL3T3WithVP8) { - ASSERT_TRUE(CreatePeerConnectionWrappers()); - ConnectFakeSignaling(); - - RtpTransceiverInit init; - RtpEncodingParameters encoding_parameters; - init.send_encodings.push_back(encoding_parameters); - auto transceiver_or_error = - caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init); - ASSERT_TRUE(transceiver_or_error.ok()); - auto transceiver = transceiver_or_error.MoveValue(); - EXPECT_TRUE(SetCodecPreferences(transceiver, cricket::kVp8CodecName).ok()); - - RtpParameters parameters = transceiver->sender()->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - parameters.encodings[0].scalability_mode = "L3T3"; - auto result = transceiver->sender()->SetParameters(parameters); - EXPECT_FALSE(result.ok()); - EXPECT_EQ(result.type(), RTCErrorType::INVALID_MODIFICATION); -} - TEST_F(PeerConnectionSVCIntegrationTest, SetParametersAcceptsL1T3WithVP8AfterNegotiation) { ASSERT_TRUE(CreatePeerConnectionWrappers()); @@ -251,7 +230,7 @@ TEST_F(PeerConnectionSVCIntegrationTest, FallbackToL1Tx) { auto caller_transceiver = transceiver_or_error.MoveValue(); RtpCapabilities capabilities = - caller()->pc_factory()->GetRtpSenderCapabilities( + caller()->pc_factory()->GetRtpReceiverCapabilities( cricket::MEDIA_TYPE_VIDEO); std::vector send_codecs = capabilities.codecs; // Only keep VP9 in the caller diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc index b0c32eff85..be0975778f 100644 --- a/pc/rtp_sender.cc +++ b/pc/rtp_sender.cc @@ -248,7 +248,7 @@ void RtpSenderBase::SetParametersInternal(const RtpParameters& parameters, } if (!media_channel_ || !ssrc_) { auto result = cricket::CheckRtpParametersInvalidModificationAndValues( - init_parameters_, parameters, codec_preferences_, absl::nullopt); + init_parameters_, parameters, send_codecs_, absl::nullopt); if (result.ok()) { init_parameters_ = parameters; } @@ -299,7 +299,7 @@ RTCError RtpSenderBase::SetParametersInternalWithAllLayers( } if (!media_channel_ || !ssrc_) { auto result = cricket::CheckRtpParametersInvalidModificationAndValues( - init_parameters_, parameters, codec_preferences_, absl::nullopt); + init_parameters_, parameters, send_codecs_, absl::nullopt); if (result.ok()) { init_parameters_ = parameters; } @@ -345,16 +345,14 @@ RTCError RtpSenderBase::CheckCodecParameters(const RtpParameters& parameters) { // the SVC capabilities. absl::optional send_codec_with_svc_info; if (send_codec && send_codec->type == cricket::Codec::Type::kVideo) { - auto codec_match = - absl::c_find_if(codec_preferences_, [&](auto& codec_preference) { - return send_codec->Matches(codec_preference); - }); - if (codec_match != codec_preferences_.end()) { + auto codec_match = absl::c_find_if( + send_codecs_, [&](auto& codec) { return send_codec->Matches(codec); }); + if (codec_match != send_codecs_.end()) { send_codec_with_svc_info = *codec_match; } } - return cricket::CheckScalabilityModeValues(parameters, codec_preferences_, + return cricket::CheckScalabilityModeValues(parameters, send_codecs_, send_codec_with_svc_info); } diff --git a/pc/rtp_sender.h b/pc/rtp_sender.h index 8925230636..90d33aaffc 100644 --- a/pc/rtp_sender.h +++ b/pc/rtp_sender.h @@ -102,8 +102,7 @@ class RtpSenderInternal : public RtpSenderInterface { // Used by the owning transceiver to inform the sender on the currently // selected codecs. - virtual void SetCodecPreferences( - std::vector codec_preferences) = 0; + virtual void SetSendCodecs(std::vector send_codecs) = 0; }; // Shared implementation for RtpSenderInternal interface. @@ -221,9 +220,8 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface { is_transceiver_stopped_ = true; } - void SetCodecPreferences( - std::vector codec_preferences) override { - codec_preferences_ = codec_preferences; + void SetSendCodecs(std::vector send_codecs) override { + send_codecs_ = send_codecs; } protected: @@ -261,7 +259,7 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface { std::vector stream_ids_; RtpParameters init_parameters_; - std::vector codec_preferences_; + std::vector send_codecs_; // TODO(tommi): `media_channel_` and several other member variables in this // class (ssrc_, stopped_, etc) are accessed from more than one thread without diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index de31b2e36a..55a0f7d584 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -41,12 +41,12 @@ namespace { RTCError VerifyCodecPreferences( const std::vector& codecs, - const std::vector& send_codecs, const std::vector& recv_codecs) { // If the intersection between codecs and // RTCRtpSender.getCapabilities(kind).codecs or the intersection between - // codecs and RTCRtpReceiver.getCapabilities(kind).codecs only contains RTX, - // RED or FEC codecs or is an empty set, throw InvalidModificationError. + // codecs and RTCRtpReceiver.getCapabilities(kind).codecs contains only + // contains RTX, RED, FEC or CN codecs or is an empty set, throw + // InvalidModificationError. // This ensures that we always have something to offer, regardless of // transceiver.direction. @@ -62,34 +62,15 @@ RTCError VerifyCodecPreferences( "codec capabilities."); } - if (!absl::c_any_of(codecs, [&send_codecs](const RtpCodecCapability& codec) { - return codec.IsMediaCodec() && - absl::c_any_of(send_codecs, - [&codec](const cricket::Codec& send_codec) { - return send_codec.MatchesRtpCodec(codec); - }); - })) { - LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION, - "Invalid codec preferences: Missing codec from send " - "codec capabilities."); - } - - // Let codecCapabilities be the union of - // RTCRtpSender.getCapabilities(kind).codecs and - // RTCRtpReceiver.getCapabilities(kind).codecs. For each codec in codecs, If + // Let codecCapabilities RTCRtpReceiver.getCapabilities(kind).codecs. + // For each codec in codecs, If // codec is not in codecCapabilities, throw InvalidModificationError. for (const auto& codec_preference : codecs) { bool is_recv_codec = absl::c_any_of( recv_codecs, [&codec_preference](const cricket::Codec& codec) { return codec.MatchesRtpCodec(codec_preference); }); - - bool is_send_codec = absl::c_any_of( - send_codecs, [&codec_preference](const cricket::Codec& codec) { - return codec.MatchesRtpCodec(codec_preference); - }); - - if (!is_recv_codec && !is_send_codec) { + if (!is_recv_codec) { LOG_AND_RETURN_ERROR( RTCErrorType::INVALID_MODIFICATION, std::string("Invalid codec preferences: invalid codec with name \"") + @@ -110,25 +91,6 @@ RTCError VerifyCodecPreferences( return RTCError::OK(); } -// Matches the list of codecs as capabilities (potentially without SVC related -// information) to the list of send codecs and returns the list of codecs with -// all the SVC related information. -std::vector MatchCodecPreferences( - const std::vector& codecs, - const std::vector& send_codecs) { - std::vector result; - - for (const auto& codec_preference : codecs) { - for (const cricket::VideoCodec& send_codec : send_codecs) { - if (send_codec.MatchesRtpCodec(codec_preference)) { - result.push_back(send_codec); - } - } - } - - return result; -} - TaskQueueBase* GetCurrentTaskQueueOrThread() { TaskQueueBase* current = TaskQueueBase::Current(); if (!current) @@ -165,7 +127,7 @@ RtpTransceiver::RtpTransceiver( RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO || media_type_ == cricket::MEDIA_TYPE_VIDEO); RTC_DCHECK_EQ(sender->media_type(), receiver->media_type()); - sender->internal()->SetCodecPreferences( + sender->internal()->SetSendCodecs( sender->media_type() == cricket::MEDIA_TYPE_VIDEO ? media_engine()->video().send_codecs(false) : media_engine()->voice().send_codecs()); @@ -441,10 +403,7 @@ void RtpTransceiver::AddSender( media_type() == cricket::MEDIA_TYPE_VIDEO ? media_engine()->video().send_codecs(false) : media_engine()->voice().send_codecs(); - sender->internal()->SetCodecPreferences( - codec_preferences_.empty() - ? send_codecs - : MatchCodecPreferences(codec_preferences_, send_codecs)); + sender->internal()->SetSendCodecs(send_codecs); senders_.push_back(sender); } @@ -693,10 +652,6 @@ RTCError RtpTransceiver::SetCodecPreferences( // to codecs and abort these steps. if (codec_capabilities.empty()) { codec_preferences_.clear(); - senders_.front()->internal()->SetCodecPreferences( - media_type() == cricket::MEDIA_TYPE_VIDEO - ? media_engine()->video().send_codecs(false) - : media_engine()->voice().send_codecs()); return RTCError::OK(); } @@ -709,19 +664,15 @@ RTCError RtpTransceiver::SetCodecPreferences( // 6. to 8. RTCError result; - std::vector recv_codecs, send_codecs; + std::vector recv_codecs; if (media_type_ == cricket::MEDIA_TYPE_AUDIO) { - send_codecs = media_engine()->voice().send_codecs(); recv_codecs = media_engine()->voice().recv_codecs(); } else if (media_type_ == cricket::MEDIA_TYPE_VIDEO) { - send_codecs = media_engine()->video().send_codecs(context()->use_rtx()); recv_codecs = media_engine()->video().recv_codecs(context()->use_rtx()); } - result = VerifyCodecPreferences(codecs, send_codecs, recv_codecs); + result = VerifyCodecPreferences(codecs, recv_codecs); if (result.ok()) { - senders_.front()->internal()->SetCodecPreferences( - MatchCodecPreferences(codecs, send_codecs)); codec_preferences_ = codecs; } diff --git a/pc/test/mock_rtp_sender_internal.h b/pc/test/mock_rtp_sender_internal.h index 4cfb2cfeaf..9a01aecabb 100644 --- a/pc/test/mock_rtp_sender_internal.h +++ b/pc/test/mock_rtp_sender_internal.h @@ -69,7 +69,7 @@ class MockRtpSenderInternal : public RtpSenderInternal { (const RtpParameters&), (override)); MOCK_METHOD(void, - SetCodecPreferences, + SetSendCodecs, (std::vector), (override)); MOCK_METHOD(rtc::scoped_refptr, From e3fb8122aa218bfc90b57515c6fb118679e6f297 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Mon, 12 Feb 2024 12:21:16 +0100 Subject: [PATCH 124/170] Reland "Let port allocator create ice tie breaker" This is a reland of commit 3f3f991c03bb4073a06da37c822daaa9deed9307 Original change's description: > Let port allocator create ice tie breaker > > Moves the responsibility for creating the ICE tie breaker from the JSEP transport controller to the port allocator. This will allow a future change to separate the ICE tie breaker (which is sent over the network and hence known to the peer) from the "port allocator random" (that is used to seed the ICE candidate foundation crc32 checksum) as an implementation detail. > > BUG=webrtc:14626 > > Change-Id: I3a9a0980238d6108b1b154f45de2975b08793b1c > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/281660 > Reviewed-by: Harald Alvestrand > Commit-Queue: Philipp Hancke > Cr-Commit-Position: refs/heads/main@{#41707} Bug: webrtc:14626 Change-Id: Id3c8f257c5611958551bd66d7ce7a885bf8ba2f9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339320 Reviewed-by: Mirko Bonadei Reviewed-by: Harald Alvestrand Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41720} --- p2p/base/fake_port_allocator.h | 5 +++-- p2p/base/p2p_transport_channel.cc | 8 +++----- p2p/base/p2p_transport_channel.h | 2 +- p2p/base/p2p_transport_channel_unittest.cc | 7 ------- p2p/base/port_allocator.cc | 14 ++------------ p2p/base/port_allocator.h | 12 ++---------- p2p/base/port_allocator_unittest.cc | 5 +---- p2p/base/regathering_controller_unittest.cc | 2 -- p2p/client/basic_port_allocator.cc | 8 ++++---- p2p/client/basic_port_allocator_unittest.cc | 5 ----- pc/jsep_transport_controller.cc | 4 +--- pc/jsep_transport_controller.h | 2 +- pc/peer_connection_ice_unittest.cc | 2 -- pc/peer_connection_interface_unittest.cc | 2 -- 14 files changed, 18 insertions(+), 60 deletions(-) diff --git a/p2p/base/fake_port_allocator.h b/p2p/base/fake_port_allocator.h index 0bb7dd0139..a51a7ca4ee 100644 --- a/p2p/base/fake_port_allocator.h +++ b/p2p/base/fake_port_allocator.h @@ -93,6 +93,7 @@ class FakePortAllocatorSession : public PortAllocatorSession { ice_ufrag, ice_pwd, allocator->flags()), + allocator_(allocator), network_thread_(network_thread), factory_(factory), ipv4_network_("network", @@ -110,7 +111,6 @@ class FakePortAllocatorSession : public PortAllocatorSession { field_trials_(field_trials) { ipv4_network_.AddIP(rtc::IPAddress(INADDR_LOOPBACK)); ipv6_network_.AddIP(rtc::IPAddress(in6addr_loopback)); - set_ice_tiebreaker(/*kTiebreakerDefault = */ 44444); } void SetCandidateFilter(uint32_t filter) override { @@ -127,7 +127,7 @@ class FakePortAllocatorSession : public PortAllocatorSession { username(), password(), false, field_trials_)); RTC_DCHECK(port_); - port_->SetIceTiebreaker(ice_tiebreaker()); + port_->SetIceTiebreaker(allocator_->ice_tiebreaker()); port_->SubscribePortDestroyed( [this](PortInterface* port) { OnPortDestroyed(port); }); AddPort(port_.get()); @@ -199,6 +199,7 @@ class FakePortAllocatorSession : public PortAllocatorSession { port_.release(); } + PortAllocator* allocator_; rtc::Thread* network_thread_; rtc::PacketSocketFactory* factory_; rtc::Network ipv4_network_; diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc index 0bccb67209..2f18f1dbb9 100644 --- a/p2p/base/p2p_transport_channel.cc +++ b/p2p/base/p2p_transport_channel.cc @@ -164,7 +164,7 @@ P2PTransportChannel::P2PTransportChannel( error_(0), remote_ice_mode_(ICEMODE_FULL), ice_role_(ICEROLE_UNKNOWN), - tiebreaker_(0), + ice_tiebreaker_(0), gathering_state_(kIceGatheringNew), weak_ping_interval_(GetWeakPingIntervalInFieldTrial(field_trials)), config_(RECEIVING_TIMEOUT, @@ -326,7 +326,7 @@ void P2PTransportChannel::SetIceTiebreaker(uint64_t tiebreaker) { return; } - tiebreaker_ = tiebreaker; + ice_tiebreaker_ = tiebreaker; } IceTransportState P2PTransportChannel::GetState() const { @@ -885,7 +885,6 @@ void P2PTransportChannel::MaybeStartGathering() { ice_parameters_.ufrag, ice_parameters_.pwd); if (pooled_session) { - pooled_session->set_ice_tiebreaker(tiebreaker_); AddAllocatorSession(std::move(pooled_session)); PortAllocatorSession* raw_pooled_session = allocator_sessions_.back().get(); @@ -902,7 +901,6 @@ void P2PTransportChannel::MaybeStartGathering() { AddAllocatorSession(allocator_->CreateSession( transport_name(), component(), ice_parameters_.ufrag, ice_parameters_.pwd)); - allocator_sessions_.back()->set_ice_tiebreaker(tiebreaker_); allocator_sessions_.back()->StartGettingPorts(); } } @@ -930,7 +928,7 @@ void P2PTransportChannel::OnPortReady(PortAllocatorSession* session, // if one is pending. port->SetIceRole(ice_role_); - port->SetIceTiebreaker(tiebreaker_); + port->SetIceTiebreaker(ice_tiebreaker_); ports_.push_back(port); port->SignalUnknownAddress.connect(this, &P2PTransportChannel::OnUnknownAddress); diff --git a/p2p/base/p2p_transport_channel.h b/p2p/base/p2p_transport_channel.h index da7933f2e7..f7472df38a 100644 --- a/p2p/base/p2p_transport_channel.h +++ b/p2p/base/p2p_transport_channel.h @@ -439,7 +439,7 @@ class RTC_EXPORT P2PTransportChannel : public IceTransportInternal, RTC_GUARDED_BY(network_thread_); IceMode remote_ice_mode_ RTC_GUARDED_BY(network_thread_); IceRole ice_role_ RTC_GUARDED_BY(network_thread_); - uint64_t tiebreaker_ RTC_GUARDED_BY(network_thread_); + uint64_t ice_tiebreaker_ RTC_GUARDED_BY(network_thread_); IceGatheringState gathering_state_ RTC_GUARDED_BY(network_thread_); std::unique_ptr regathering_controller_ RTC_GUARDED_BY(network_thread_); diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index 5bcfee0473..79e984cfec 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -141,7 +141,6 @@ const cricket::IceParameters kIceParams[4] = { const uint64_t kLowTiebreaker = 11111; const uint64_t kHighTiebreaker = 22222; -const uint64_t kTiebreakerDefault = 44444; cricket::IceConfig CreateIceConfig( int receiving_timeout, @@ -299,10 +298,6 @@ class P2PTransportChannelTestBase : public ::testing::Test, &ep2_.network_manager_, socket_factory_.get(), stun_servers, kTurnUdpIntAddr, rtc::SocketAddress())); - ep1_.SetIceTiebreaker(kTiebreakerDefault); - ep1_.allocator_->SetIceTiebreaker(kTiebreakerDefault); - ep2_.SetIceTiebreaker(kTiebreakerDefault); - ep2_.allocator_->SetIceTiebreaker(kTiebreakerDefault); webrtc::metrics::Reset(); } @@ -3347,7 +3342,6 @@ class P2PTransportChannelPingTest : public ::testing::Test, protected: void PrepareChannel(P2PTransportChannel* ch) { ch->SetIceRole(ICEROLE_CONTROLLING); - ch->SetIceTiebreaker(kTiebreakerDefault); ch->SetIceParameters(kIceParams[0]); ch->SetRemoteIceParameters(kIceParams[1]); ch->SignalNetworkRouteChanged.connect( @@ -3715,7 +3709,6 @@ TEST_F(P2PTransportChannelPingTest, PingingStartedAsSoonAsPossible) { &field_trials_); P2PTransportChannel ch("TestChannel", 1, &pa, &field_trials_); ch.SetIceRole(ICEROLE_CONTROLLING); - ch.SetIceTiebreaker(kTiebreakerDefault); ch.SetIceParameters(kIceParams[0]); ch.MaybeStartGathering(); EXPECT_EQ_WAIT(IceGatheringState::kIceGatheringComplete, ch.gathering_state(), diff --git a/p2p/base/port_allocator.cc b/p2p/base/port_allocator.cc index 3745717510..52fc8c1d39 100644 --- a/p2p/base/port_allocator.cc +++ b/p2p/base/port_allocator.cc @@ -68,8 +68,7 @@ PortAllocatorSession::PortAllocatorSession(absl::string_view content_name, content_name_(content_name), component_(component), ice_ufrag_(ice_ufrag), - ice_pwd_(ice_pwd), - tiebreaker_(0) { + ice_pwd_(ice_pwd) { // Pooled sessions are allowed to be created with empty content name, // component, ufrag and password. RTC_DCHECK(ice_ufrag.empty() == ice_pwd.empty()); @@ -101,7 +100,7 @@ PortAllocator::PortAllocator() step_delay_(kDefaultStepDelay), allow_tcp_listen_(true), candidate_filter_(CF_ALL), - tiebreaker_(0) { + tiebreaker_(rtc::CreateRandomId64()) { // The allocator will be attached to a thread in Initialize. thread_checker_.Detach(); } @@ -189,7 +188,6 @@ bool PortAllocator::SetConfiguration( PortAllocatorSession* pooled_session = CreateSessionInternal("", 0, iceCredentials.ufrag, iceCredentials.pwd); pooled_session->set_pooled(true); - pooled_session->set_ice_tiebreaker(tiebreaker_); pooled_session->StartGettingPorts(); pooled_sessions_.push_back( std::unique_ptr(pooled_session)); @@ -197,13 +195,6 @@ bool PortAllocator::SetConfiguration( return true; } -void PortAllocator::SetIceTiebreaker(uint64_t tiebreaker) { - tiebreaker_ = tiebreaker; - for (auto& pooled_session : pooled_sessions_) { - pooled_session->set_ice_tiebreaker(tiebreaker_); - } -} - std::unique_ptr PortAllocator::CreateSession( absl::string_view content_name, int component, @@ -213,7 +204,6 @@ std::unique_ptr PortAllocator::CreateSession( auto session = std::unique_ptr( CreateSessionInternal(content_name, component, ice_ufrag, ice_pwd)); session->SetCandidateFilter(candidate_filter()); - session->set_ice_tiebreaker(tiebreaker_); return session; } diff --git a/p2p/base/port_allocator.h b/p2p/base/port_allocator.h index b8cffca9c0..63ecfc6904 100644 --- a/p2p/base/port_allocator.h +++ b/p2p/base/port_allocator.h @@ -212,10 +212,6 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { const std::string& ice_pwd() const { return ice_pwd_; } bool pooled() const { return pooled_; } - // TODO(bugs.webrtc.org/14605): move this to the constructor - void set_ice_tiebreaker(uint64_t tiebreaker) { tiebreaker_ = tiebreaker; } - uint64_t ice_tiebreaker() const { return tiebreaker_; } - // Setting this filter should affect not only candidates gathered in the // future, but candidates already gathered and ports already "ready", // which would be returned by ReadyCandidates() and ReadyPorts(). @@ -332,9 +328,6 @@ class RTC_EXPORT PortAllocatorSession : public sigslot::has_slots<> { bool pooled_ = false; - // TODO(bugs.webrtc.org/14605): move this to the constructor - uint64_t tiebreaker_; - // SetIceParameters is an implementation detail which only PortAllocator // should be able to call. friend class PortAllocator; @@ -387,9 +380,6 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { const absl::optional& stun_candidate_keepalive_interval = absl::nullopt); - void SetIceTiebreaker(uint64_t tiebreaker); - uint64_t IceTiebreaker() const { return tiebreaker_; } - const ServerAddresses& stun_servers() const { CheckRunOnValidThreadIfInitialized(); return stun_servers_; @@ -461,6 +451,8 @@ class RTC_EXPORT PortAllocator : public sigslot::has_slots<> { // 3. mDNS concealment of private IPs is enabled. Candidate SanitizeCandidate(const Candidate& c) const; + uint64_t ice_tiebreaker() const { return tiebreaker_; } + uint32_t flags() const { CheckRunOnValidThreadIfInitialized(); return flags_; diff --git a/p2p/base/port_allocator_unittest.cc b/p2p/base/port_allocator_unittest.cc index 836a2fa494..2df8662f62 100644 --- a/p2p/base/port_allocator_unittest.cc +++ b/p2p/base/port_allocator_unittest.cc @@ -26,7 +26,6 @@ static const char kIceUfrag[] = "UF00"; static const char kIcePwd[] = "TESTICEPWD00000000000000"; static const char kTurnUsername[] = "test"; static const char kTurnPassword[] = "test"; -constexpr uint64_t kTiebreakerDefault = 44444; class PortAllocatorTest : public ::testing::Test, public sigslot::has_slots<> { public: @@ -38,9 +37,7 @@ class PortAllocatorTest : public ::testing::Test, public sigslot::has_slots<> { allocator_(std::make_unique( rtc::Thread::Current(), packet_socket_factory_.get(), - &field_trials_)) { - allocator_->SetIceTiebreaker(kTiebreakerDefault); - } + &field_trials_)) {} protected: void SetConfigurationWithPoolSize(int candidate_pool_size) { diff --git a/p2p/base/regathering_controller_unittest.cc b/p2p/base/regathering_controller_unittest.cc index 91b7270f77..573c0fd23f 100644 --- a/p2p/base/regathering_controller_unittest.cc +++ b/p2p/base/regathering_controller_unittest.cc @@ -40,7 +40,6 @@ const rtc::SocketAddress kTurnUdpIntAddr("99.99.99.3", const cricket::RelayCredentials kRelayCredentials("test", "test"); const char kIceUfrag[] = "UF00"; const char kIcePwd[] = "TESTICEPWD00000000000000"; -constexpr uint64_t kTiebreakerDefault = 44444; } // namespace @@ -59,7 +58,6 @@ class RegatheringControllerTest : public ::testing::Test, rtc::Thread::Current(), packet_socket_factory_.get(), &field_trials_)) { - allocator_->SetIceTiebreaker(kTiebreakerDefault); BasicRegatheringController::Config regathering_config; regathering_config.regather_on_failed_networks_interval = 0; regathering_controller_.reset(new BasicRegatheringController( diff --git a/p2p/client/basic_port_allocator.cc b/p2p/client/basic_port_allocator.cc index e95033efeb..cc38a66727 100644 --- a/p2p/client/basic_port_allocator.cc +++ b/p2p/client/basic_port_allocator.cc @@ -1483,7 +1483,7 @@ void AllocationSequence::CreateUDPPorts() { } if (port) { - port->SetIceTiebreaker(session_->ice_tiebreaker()); + port->SetIceTiebreaker(session_->allocator()->ice_tiebreaker()); // If shared socket is enabled, STUN candidate will be allocated by the // UDPPort. if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) { @@ -1519,7 +1519,7 @@ void AllocationSequence::CreateTCPPorts() { session_->allocator()->allow_tcp_listen(), session_->allocator()->field_trials()); if (port) { - port->SetIceTiebreaker(session_->ice_tiebreaker()); + port->SetIceTiebreaker(session_->allocator()->ice_tiebreaker()); session_->AddAllocatedPort(port.release(), this); // Since TCPPort is not created using shared socket, `port` will not be // added to the dequeue. @@ -1549,7 +1549,7 @@ void AllocationSequence::CreateStunPorts() { session_->allocator()->stun_candidate_keepalive_interval(), session_->allocator()->field_trials()); if (port) { - port->SetIceTiebreaker(session_->ice_tiebreaker()); + port->SetIceTiebreaker(session_->allocator()->ice_tiebreaker()); session_->AddAllocatedPort(port.release(), this); // Since StunPort is not created using shared socket, `port` will not be // added to the dequeue. @@ -1652,7 +1652,7 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config, } } RTC_DCHECK(port != NULL); - port->SetIceTiebreaker(session_->ice_tiebreaker()); + port->SetIceTiebreaker(session_->allocator()->ice_tiebreaker()); session_->AddAllocatedPort(port.release(), this); } } diff --git a/p2p/client/basic_port_allocator_unittest.cc b/p2p/client/basic_port_allocator_unittest.cc index 77443eedbb..f77040d128 100644 --- a/p2p/client/basic_port_allocator_unittest.cc +++ b/p2p/client/basic_port_allocator_unittest.cc @@ -112,8 +112,6 @@ static const char kTurnPassword[] = "test"; // Add some margin of error for slow bots. static const int kStunTimeoutMs = cricket::STUN_TOTAL_TIMEOUT; -constexpr uint64_t kTiebreakerDefault = 44444; - namespace { void CheckStunKeepaliveIntervalOfAllReadyPorts( @@ -176,7 +174,6 @@ class BasicPortAllocatorTestBase : public ::testing::Test, &network_manager_, &socket_factory_, stun_servers, &field_trials_); allocator_->Initialize(); allocator_->set_step_delay(kMinimumStepDelay); - allocator_->SetIceTiebreaker(kTiebreakerDefault); webrtc::metrics::Reset(); } @@ -214,7 +211,6 @@ class BasicPortAllocatorTestBase : public ::testing::Test, allocator_.reset( new BasicPortAllocator(&network_manager_, &socket_factory_)); allocator_->Initialize(); - allocator_->SetIceTiebreaker(kTiebreakerDefault); allocator_->set_step_delay(kMinimumStepDelay); } // Endpoint is behind a NAT, with STUN specified. @@ -299,7 +295,6 @@ class BasicPortAllocatorTestBase : public ::testing::Test, this, &BasicPortAllocatorTestBase::OnCandidatesRemoved); session->SignalCandidatesAllocationDone.connect( this, &BasicPortAllocatorTestBase::OnCandidatesAllocationDone); - session->set_ice_tiebreaker(kTiebreakerDefault); return session; } diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index 9473d962ef..d5eb0c633d 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -55,6 +55,7 @@ JsepTransportController::JsepTransportController( }), config_(std::move(config)), active_reset_srtp_params_(config.active_reset_srtp_params), + ice_tiebreaker_(port_allocator ? port_allocator->ice_tiebreaker() : 0), bundles_(config.bundle_policy) { // The `transport_observer` is assumed to be non-null. RTC_DCHECK(config_.transport_observer); @@ -62,9 +63,6 @@ JsepTransportController::JsepTransportController( RTC_DCHECK(config_.ice_transport_factory); RTC_DCHECK(config_.on_dtls_handshake_error_); RTC_DCHECK(config_.field_trials); - if (port_allocator_) { - port_allocator_->SetIceTiebreaker(ice_tiebreaker_); - } } JsepTransportController::~JsepTransportController() { diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h index 448844ac79..7f06c22969 100644 --- a/pc/jsep_transport_controller.h +++ b/pc/jsep_transport_controller.h @@ -507,7 +507,7 @@ class JsepTransportController : public sigslot::has_slots<> { cricket::IceConfig ice_config_; cricket::IceRole ice_role_ = cricket::ICEROLE_CONTROLLING; - uint64_t ice_tiebreaker_ = rtc::CreateRandomId64(); + uint64_t ice_tiebreaker_; rtc::scoped_refptr certificate_; BundleManager bundles_; diff --git a/pc/peer_connection_ice_unittest.cc b/pc/peer_connection_ice_unittest.cc index 492e108cbc..bd4848cf8b 100644 --- a/pc/peer_connection_ice_unittest.cc +++ b/pc/peer_connection_ice_unittest.cc @@ -94,7 +94,6 @@ using ::testing::Values; constexpr int kIceCandidatesTimeout = 10000; constexpr int64_t kWaitTimeout = 10000; -constexpr uint64_t kTiebreakerDefault = 44444; class PeerConnectionWrapperForIceTest : public PeerConnectionWrapper { public: @@ -1448,7 +1447,6 @@ class PeerConnectionIceConfigTest : public ::testing::Test { packet_socket_factory_.get(), &field_trials_)); port_allocator_ = port_allocator.get(); - port_allocator_->SetIceTiebreaker(kTiebreakerDefault); PeerConnectionDependencies pc_dependencies(&observer_); pc_dependencies.allocator = std::move(port_allocator); auto result = pc_factory_->CreatePeerConnectionOrError( diff --git a/pc/peer_connection_interface_unittest.cc b/pc/peer_connection_interface_unittest.cc index 08fb1632d6..71c85d4c6f 100644 --- a/pc/peer_connection_interface_unittest.cc +++ b/pc/peer_connection_interface_unittest.cc @@ -114,7 +114,6 @@ static const char kVideoTracks[][32] = {"videotrack0", "videotrack1"}; static const char kRecvonly[] = "recvonly"; static const char kSendrecv[] = "sendrecv"; -constexpr uint64_t kTiebreakerDefault = 44444; // Reference SDP with a MediaStream with label "stream1" and audio track with // id "audio_1" and a video track with id "video_1; @@ -711,7 +710,6 @@ class PeerConnectionInterfaceBaseTest : public ::testing::Test { std::make_unique(vss_.get()), &field_trials_)); port_allocator_ = port_allocator.get(); - port_allocator_->SetIceTiebreaker(kTiebreakerDefault); // Create certificate generator unless DTLS constraint is explicitly set to // false. From 521b8632b642d6337fec466b6411663519795277 Mon Sep 17 00:00:00 2001 From: Tommi Date: Mon, 12 Feb 2024 14:52:13 +0100 Subject: [PATCH 125/170] Change type of candidate type names from char[] to string_view Bug: none Change-Id: I57fcfd486bf4e2fb15288614b0e81f00b10e120a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337443 Reviewed-by: Harald Alvestrand Commit-Queue: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41721} --- api/candidate.cc | 9 +++++---- api/candidate.h | 8 ++++---- pc/rtc_stats_collector_unittest.cc | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/api/candidate.cc b/api/candidate.cc index 865f8e5787..4311556233 100644 --- a/api/candidate.cc +++ b/api/candidate.cc @@ -10,6 +10,7 @@ #include "api/candidate.h" +#include "absl/base/attributes.h" #include "rtc_base/helpers.h" #include "rtc_base/ip_address.h" #include "rtc_base/logging.h" @@ -17,10 +18,10 @@ namespace cricket { -const char LOCAL_PORT_TYPE[] = "local"; -const char STUN_PORT_TYPE[] = "stun"; -const char PRFLX_PORT_TYPE[] = "prflx"; -const char RELAY_PORT_TYPE[] = "relay"; +ABSL_CONST_INIT const absl::string_view LOCAL_PORT_TYPE = "local"; +ABSL_CONST_INIT const absl::string_view STUN_PORT_TYPE = "stun"; +ABSL_CONST_INIT const absl::string_view PRFLX_PORT_TYPE = "prflx"; +ABSL_CONST_INIT const absl::string_view RELAY_PORT_TYPE = "relay"; Candidate::Candidate() : id_(rtc::CreateRandomString(8)), diff --git a/api/candidate.h b/api/candidate.h index 3fefd1114b..12b1512e72 100644 --- a/api/candidate.h +++ b/api/candidate.h @@ -32,10 +32,10 @@ namespace cricket { // TODO(tommi): These are temporarily here, moved from `port.h` and will // eventually be removed once we use enums instead of strings for these values. -RTC_EXPORT extern const char LOCAL_PORT_TYPE[]; -RTC_EXPORT extern const char STUN_PORT_TYPE[]; -RTC_EXPORT extern const char PRFLX_PORT_TYPE[]; -RTC_EXPORT extern const char RELAY_PORT_TYPE[]; +RTC_EXPORT extern const absl::string_view LOCAL_PORT_TYPE; +RTC_EXPORT extern const absl::string_view STUN_PORT_TYPE; +RTC_EXPORT extern const absl::string_view PRFLX_PORT_TYPE; +RTC_EXPORT extern const absl::string_view RELAY_PORT_TYPE; // TURN servers are limited to 32 in accordance with // https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-iceservers diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc index 03512bbcde..98cbd2d7e3 100644 --- a/pc/rtc_stats_collector_unittest.cc +++ b/pc/rtc_stats_collector_unittest.cc @@ -212,7 +212,7 @@ std::unique_ptr CreateFakeCandidate( int port, const std::string& protocol, const rtc::AdapterType adapter_type, - const std::string& candidate_type, + const absl::string_view candidate_type, uint32_t priority, const rtc::AdapterType underlying_type_for_vpn = rtc::ADAPTER_TYPE_UNKNOWN) { From 9a75ae1255c0332191d97bf6f08907e2eee7a125 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 12 Feb 2024 10:15:04 -0800 Subject: [PATCH 126/170] Roll chromium_revision f53e0380af..3455025028 (1259106:1259277) Change log: https://chromium.googlesource.com/chromium/src/+log/f53e0380af..3455025028 Full diff: https://chromium.googlesource.com/chromium/src/+/f53e0380af..3455025028 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/a3c0545d76..f65b89ddd8 * src/build: https://chromium.googlesource.com/chromium/src/build/+log/100a2e5828..f109cb48d1 * src/buildtools: https://chromium.googlesource.com/chromium/src/buildtools/+log/f90248f2bf..f35a7d885a * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/7d8367c78c..650af61823 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/24fb660f29..4a09588758 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/513fca12d3..719cf4d0b4 * src/third_party/androidx: 0Jfh-EIa7YBsv86pah7juYpkhvYjTk-Og860SJavIM0C..rDm_kXJ4QiOAfQYXTO_2ZWlg_5HVE3VWUkkps3x0O3cC * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/32769fe939..2acd6f4c9d * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/3d959a6b84..958abadb3d * src/third_party/r8: Ms1b55b8kRNZqqskNs35JxAgZvqbtKGKDimgS_0LGz4C..szZgxadOOC_Yfq3DhP5R0WR2LMRiVMVrt71WNfL5taIC * src/third_party/turbine: 7NPeRX_XAc2XOUX7V9moyIEyM8RjjPdAhRK-8DLzk_oC..s-hdujub30RR2mH9Qf7pHv6h9uNGEiYVs6W1VXWeEe8C * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/daa8c430f1..d9a4045620 DEPS diff: https://chromium.googlesource.com/chromium/src/+/f53e0380af..3455025028/DEPS No update to Clang. BUG=None Change-Id: I00dff0887ac6f00f20370d23565829a5d350ea19 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339400 Commit-Queue: Autoroller Bot-Commit: Autoroller Cr-Commit-Position: refs/heads/main@{#41722} --- DEPS | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/DEPS b/DEPS index 4c8c5c7965..0fbcbc5616 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': 'f53e0380af68a8d94163346b451d257db8d59ddc', + 'chromium_revision': '3455025028e4b0953324e0fdc736cc10ac4b436d', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,24 +50,24 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@a3c0545d76119aed96d3ed6775c17f6541b39815', + 'https://chromium.googlesource.com/chromium/src/base@f65b89ddd8e82ab0c8c7902269e657b997c90003', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@100a2e5828c11e1d67f01faa8e761f6479f650b6', + 'https://chromium.googlesource.com/chromium/src/build@f109cb48d1764edac8d3be6c923219e21441b11b', 'src/buildtools': - 'https://chromium.googlesource.com/chromium/src/buildtools@f90248f2bf52549f4110fbda4bb37580e81bc262', + 'https://chromium.googlesource.com/chromium/src/buildtools@f35a7d885ace0b7dd8e8ac2376ca759d3905f4dc', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. 'src/examples/androidtests/third_party/gradle': { 'url': 'https://chromium.googlesource.com/external/github.com/gradle/gradle.git@f2d1fb54a951d8b11d25748e4711bec8d128d7e3', 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@7d8367c78cfa1664531673e52a0d58a949d0eca8', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@650af6182389af758ec944ca96f692e8c66949d9', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@24fb660f299e140977bc4281abbf5d5cc85ff6a9', + 'https://chromium.googlesource.com/chromium/src/testing@4a0958875864aa027320e99f92017bdedfe7600d', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@513fca12d3d735c92f9913493df0fb92a1988517', + 'https://chromium.googlesource.com/chromium/src/third_party@719cf4d0b41b05a5661cc531d6501d7978e8d15f', 'src/buildtools/linux64': { 'packages': [ @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@32769fe9391bcbe32eba867db2b358d47c170562', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@2acd6f4c9d29c8a25dae7d7eb9e3a469f586bb1a', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@3d959a6b84994746c9a357c58516ac8a53299b77', + 'https://android.googlesource.com/platform/external/perfetto.git@958abadb3d3c8914fe0a50ae84b5ad7551a60cf9', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@96b64eaac5adbac59e43e34d87af3ba0fb06bca6', 'src/third_party/libyuv': @@ -331,7 +331,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'Ms1b55b8kRNZqqskNs35JxAgZvqbtKGKDimgS_0LGz4C', + 'version': 'szZgxadOOC_Yfq3DhP5R0WR2LMRiVMVrt71WNfL5taIC', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@daa8c430f199f0038c7d606aad90e4a1b1d897d1', + 'https://chromium.googlesource.com/chromium/src/tools@d9a40456206b19adb02160e13f342492eff8f237', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -405,7 +405,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '0Jfh-EIa7YBsv86pah7juYpkhvYjTk-Og860SJavIM0C', + 'version': 'rDm_kXJ4QiOAfQYXTO_2ZWlg_5HVE3VWUkkps3x0O3cC', }, ], 'condition': 'checkout_android', @@ -498,7 +498,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/turbine', - 'version': '7NPeRX_XAc2XOUX7V9moyIEyM8RjjPdAhRK-8DLzk_oC', + 'version': 's-hdujub30RR2mH9Qf7pHv6h9uNGEiYVs6W1VXWeEe8C', }, ], 'condition': 'checkout_android', From 764b8ae655e69946025a05579c6a08d01068b8ec Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 12 Feb 2024 12:02:10 -0800 Subject: [PATCH 127/170] Roll chromium_revision 3455025028..821d081141 (1259277:1259390) Change log: https://chromium.googlesource.com/chromium/src/+log/3455025028..821d081141 Full diff: https://chromium.googlesource.com/chromium/src/+/3455025028..821d081141 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/f65b89ddd8..e39c682e38 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/719cf4d0b4..0ca8b9cff3 * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/2acd6f4c9d..6c92a665e1 * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/958abadb3d..7fae70ec1e * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/d9a4045620..26754ff27f DEPS diff: https://chromium.googlesource.com/chromium/src/+/3455025028..821d081141/DEPS No update to Clang. BUG=None Change-Id: If236e6b0eb18c824fa19ffb19a894bc5fad90810 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339420 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41723} --- DEPS | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DEPS b/DEPS index 0fbcbc5616..979254c12e 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '3455025028e4b0953324e0fdc736cc10ac4b436d', + 'chromium_revision': '821d0811412fa9eaae71e9e81775576054edc7c7', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,7 +50,7 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@f65b89ddd8e82ab0c8c7902269e657b997c90003', + 'https://chromium.googlesource.com/chromium/src/base@e39c682e38fd144aa257bb6a954b1b982f05ef19', 'src/build': 'https://chromium.googlesource.com/chromium/src/build@f109cb48d1764edac8d3be6c923219e21441b11b', 'src/buildtools': @@ -67,7 +67,7 @@ deps = { 'src/testing': 'https://chromium.googlesource.com/chromium/src/testing@4a0958875864aa027320e99f92017bdedfe7600d', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@719cf4d0b41b05a5661cc531d6501d7978e8d15f', + 'https://chromium.googlesource.com/chromium/src/third_party@0ca8b9cff3429139e4247adb25d55dabe82eb1d5', 'src/buildtools/linux64': { 'packages': [ @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@2acd6f4c9d29c8a25dae7d7eb9e3a469f586bb1a', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@6c92a665e180982ca3ed0ad4a9f0738b119e49a9', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@958abadb3d3c8914fe0a50ae84b5ad7551a60cf9', + 'https://android.googlesource.com/platform/external/perfetto.git@7fae70ec1ef2fe1b93f124b5b02d88d339205ead', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@96b64eaac5adbac59e43e34d87af3ba0fb06bca6', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@d9a40456206b19adb02160e13f342492eff8f237', + 'https://chromium.googlesource.com/chromium/src/tools@26754ff27f7bcd36e9452a0436c60c89e5698ef6', 'src/third_party/accessibility_test_framework': { 'packages': [ From e28e60c7401e5ee8ba1cf325c64c2de5a6d09d08 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Mon, 12 Feb 2024 16:01:58 -0800 Subject: [PATCH 128/170] Roll chromium_revision 821d081141..7d6bb2c760 (1259390:1259552) Change log: https://chromium.googlesource.com/chromium/src/+log/821d081141..7d6bb2c760 Full diff: https://chromium.googlesource.com/chromium/src/+/821d081141..7d6bb2c760 Changed dependencies * reclient_version: re_client_version:0.130.0.546556b-gomaip..re_client_version:0.131.1.784ddbb-gomaip * src/base: https://chromium.googlesource.com/chromium/src/base/+log/e39c682e38..6c5ef966eb * src/build: https://chromium.googlesource.com/chromium/src/build/+log/f109cb48d1..fcd7410768 * src/buildtools/reclient: re_client_version:0.130.0.546556b-gomaip..re_client_version:0.131.1.784ddbb-gomaip * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/650af61823..f3dc4ca279 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/4a09588758..13076206a3 * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/0ca8b9cff3..a043caba1c * src/third_party/androidx: rDm_kXJ4QiOAfQYXTO_2ZWlg_5HVE3VWUkkps3x0O3cC..f2NTXeY1WbJ_lRwpAyZWORm3Ho9qRx28GRayw1ol5x8C * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/4495ac19ba..d80f7d1ae4 * src/third_party/depot_tools: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+log/6c92a665e1..f76550541c * src/third_party/perfetto: https://android.googlesource.com/platform/external/perfetto.git/+log/7fae70ec1e..e01c38d714 * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/26754ff27f..6d4102387b DEPS diff: https://chromium.googlesource.com/chromium/src/+/821d081141..7d6bb2c760/DEPS No update to Clang. BUG=None Change-Id: I2592dbba61e434abd5b51a5ee3acd526f89ff478 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339460 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41724} --- DEPS | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/DEPS b/DEPS index 979254c12e..e7a37e36d4 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '821d0811412fa9eaae71e9e81775576054edc7c7', + 'chromium_revision': '7d6bb2c760f35c5be1fd7fea97777f0c4af2de98', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -40,7 +40,7 @@ vars = { # RBE instance to use for running remote builds 'rbe_instance': 'projects/rbe-webrtc-developer/instances/default_instance', # reclient CIPD package version - 'reclient_version': 're_client_version:0.130.0.546556b-gomaip', + 'reclient_version': 're_client_version:0.131.1.784ddbb-gomaip', # ninja CIPD package version # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja @@ -50,9 +50,9 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@e39c682e38fd144aa257bb6a954b1b982f05ef19', + 'https://chromium.googlesource.com/chromium/src/base@6c5ef966eb7ff2c6fd9a2087721627deba03e41d', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@f109cb48d1764edac8d3be6c923219e21441b11b', + 'https://chromium.googlesource.com/chromium/src/build@fcd7410768a2dbcf3f8fe08e7f328f8a73183fe7', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@f35a7d885ace0b7dd8e8ac2376ca759d3905f4dc', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@650af6182389af758ec944ca96f692e8c66949d9', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@f3dc4ca27976b474b2c8eed63b41db141453c260', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@4a0958875864aa027320e99f92017bdedfe7600d', + 'https://chromium.googlesource.com/chromium/src/testing@13076206a34d1e2dd10be092db3e01e203e54945', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@0ca8b9cff3429139e4247adb25d55dabe82eb1d5', + 'https://chromium.googlesource.com/chromium/src/third_party@a043caba1ce7313a0685f9fee77385132c34e0b4', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@4495ac19babd1c6d43f083ddcfe342e58c5bdb95', + 'https://chromium.googlesource.com/catapult.git@d80f7d1ae4c6c010ecc8e660588f33f5768cb177', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -202,7 +202,7 @@ deps = { 'src/third_party/crc32c/src': 'https://chromium.googlesource.com/external/github.com/google/crc32c.git@fa5ade41ee480003d9c5af6f43567ba22e4e17e6', 'src/third_party/depot_tools': - 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@6c92a665e180982ca3ed0ad4a9f0738b119e49a9', + 'https://chromium.googlesource.com/chromium/tools/depot_tools.git@f76550541c751f956ef9287f2695a6c8a74bf709', 'src/third_party/ffmpeg': 'https://chromium.googlesource.com/chromium/third_party/ffmpeg.git@7c1b0b524c639beeb25363b1d0809ebe5c6efe5e', 'src/third_party/flatbuffers/src': @@ -302,7 +302,7 @@ deps = { 'condition': 'checkout_android', }, 'src/third_party/perfetto': - 'https://android.googlesource.com/platform/external/perfetto.git@7fae70ec1ef2fe1b93f124b5b02d88d339205ead', + 'https://android.googlesource.com/platform/external/perfetto.git@e01c38d714f4d55c7ef67aa9414c69479b051b38', 'src/third_party/libvpx/source/libvpx': 'https://chromium.googlesource.com/webm/libvpx.git@96b64eaac5adbac59e43e34d87af3ba0fb06bca6', 'src/third_party/libyuv': @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@26754ff27f7bcd36e9452a0436c60c89e5698ef6', + 'https://chromium.googlesource.com/chromium/src/tools@6d4102387bd73d46e5580019016584d518f788e4', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -405,7 +405,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'rDm_kXJ4QiOAfQYXTO_2ZWlg_5HVE3VWUkkps3x0O3cC', + 'version': 'f2NTXeY1WbJ_lRwpAyZWORm3Ho9qRx28GRayw1ol5x8C', }, ], 'condition': 'checkout_android', From 1e7a6f3b6a8eee7efcb129eec10fe734d718ebc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Bostr=C3=B6m?= Date: Tue, 13 Feb 2024 08:22:20 +0000 Subject: [PATCH 129/170] Revert "Make setCodecPreferences only look at receive codecs" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1cce1d7ddcbde3a3648007b5a131bd0c2638724b. Reason for revert: Breaks WPTs Original change's description: > Make setCodecPreferences only look at receive codecs > > which is what is noted in JSEP: > https://www.rfc-editor.org/rfc/rfc8829.html#name-setcodecpreferences > > Some W3C spec modifications are required since the W3C specification > currently takes into account send codecs as well. > > Spec issue: > https://github.com/w3c/webrtc-pc/issues/2888 > Spec PR: > https://github.com/w3c/webrtc-pc/pull/2926 > > setCodecPreferences continues to modify the codecs in an offer. > > Also rename RtpSender::SetCodecPreferences to RtpSender::SetSendCodecs for consistent semantics. > > BUG=webrtc:15396 > > Change-Id: I1e8fbe77cb2670575578a777ed1336567a1e4031 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/328780 > Reviewed-by: Henrik Boström > Commit-Queue: Philipp Hancke > Reviewed-by: Harald Alvestrand > Cr-Commit-Position: refs/heads/main@{#41719} Bug: webrtc:15396 Change-Id: I7b545e91f820c3affc39841c6e93939eac75c363 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339520 Reviewed-by: Harald Alvestrand Commit-Queue: Harald Alvestrand Owners-Override: Henrik Boström Reviewed-by: Henrik Boström Auto-Submit: Henrik Boström Bot-Commit: rubber-stamper@appspot.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41725} --- media/base/media_engine.cc | 18 +- media/base/media_engine.h | 6 +- ...er_connection_encodings_integrationtest.cc | 166 +++++++++--------- pc/peer_connection_media_unittest.cc | 23 +++ pc/peer_connection_svc_integrationtest.cc | 27 ++- pc/rtp_sender.cc | 14 +- pc/rtp_sender.h | 10 +- pc/rtp_transceiver.cc | 69 ++++++-- pc/test/mock_rtp_sender_internal.h | 2 +- 9 files changed, 218 insertions(+), 117 deletions(-) diff --git a/media/base/media_engine.cc b/media/base/media_engine.cc index c551a58cf9..7304ab03d7 100644 --- a/media/base/media_engine.cc +++ b/media/base/media_engine.cc @@ -67,11 +67,11 @@ std::vector GetDefaultEnabledRtpHeaderExtensions( webrtc::RTCError CheckScalabilityModeValues( const webrtc::RtpParameters& rtp_parameters, - rtc::ArrayView send_codecs, + rtc::ArrayView codec_preferences, absl::optional send_codec) { using webrtc::RTCErrorType; - if (send_codecs.empty()) { + if (codec_preferences.empty()) { // This is an audio sender or an extra check in the stack where the codec // list is not available and we can't check the scalability_mode values. return webrtc::RTCError::OK(); @@ -80,7 +80,7 @@ webrtc::RTCError CheckScalabilityModeValues( for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) { if (rtp_parameters.encodings[i].codec) { bool codecFound = false; - for (const cricket::Codec& codec : send_codecs) { + for (const cricket::VideoCodec& codec : codec_preferences) { if (codec.MatchesRtpCodec(*rtp_parameters.encodings[i].codec)) { codecFound = true; send_codec = codec; @@ -97,7 +97,7 @@ webrtc::RTCError CheckScalabilityModeValues( if (rtp_parameters.encodings[i].scalability_mode) { if (!send_codec) { bool scalabilityModeFound = false; - for (const cricket::Codec& codec : send_codecs) { + for (const cricket::VideoCodec& codec : codec_preferences) { for (const auto& scalability_mode : codec.scalability_modes) { if (ScalabilityModeToString(scalability_mode) == *rtp_parameters.encodings[i].scalability_mode) { @@ -139,7 +139,7 @@ webrtc::RTCError CheckScalabilityModeValues( webrtc::RTCError CheckRtpParametersValues( const webrtc::RtpParameters& rtp_parameters, - rtc::ArrayView send_codecs, + rtc::ArrayView codec_preferences, absl::optional send_codec) { using webrtc::RTCErrorType; @@ -196,7 +196,8 @@ webrtc::RTCError CheckRtpParametersValues( } } - return CheckScalabilityModeValues(rtp_parameters, send_codecs, send_codec); + return CheckScalabilityModeValues(rtp_parameters, codec_preferences, + send_codec); } webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( @@ -209,7 +210,7 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( const webrtc::RtpParameters& old_rtp_parameters, const webrtc::RtpParameters& rtp_parameters, - rtc::ArrayView send_codecs, + rtc::ArrayView codec_preferences, absl::optional send_codec) { using webrtc::RTCErrorType; if (rtp_parameters.encodings.size() != old_rtp_parameters.encodings.size()) { @@ -245,7 +246,8 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( "Attempted to set RtpParameters with modified SSRC"); } - return CheckRtpParametersValues(rtp_parameters, send_codecs, send_codec); + return CheckRtpParametersValues(rtp_parameters, codec_preferences, + send_codec); } CompositeMediaEngine::CompositeMediaEngine( diff --git a/media/base/media_engine.h b/media/base/media_engine.h index b054893163..428123516f 100644 --- a/media/base/media_engine.h +++ b/media/base/media_engine.h @@ -42,14 +42,14 @@ namespace cricket { // least one video codec of the list. If the list is empty, no check is done. webrtc::RTCError CheckScalabilityModeValues( const webrtc::RtpParameters& new_parameters, - rtc::ArrayView send_codecs, + rtc::ArrayView codec_preferences, absl::optional send_codec); // Checks the parameters have valid and supported values, and checks parameters // with CheckScalabilityModeValues(). webrtc::RTCError CheckRtpParametersValues( const webrtc::RtpParameters& new_parameters, - rtc::ArrayView send_codecs, + rtc::ArrayView codec_preferences, absl::optional send_codec); // Checks that the immutable values have not changed in new_parameters and @@ -57,7 +57,7 @@ webrtc::RTCError CheckRtpParametersValues( webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( const webrtc::RtpParameters& old_parameters, const webrtc::RtpParameters& new_parameters, - rtc::ArrayView send_codecs, + rtc::ArrayView codec_preferences, absl::optional send_codec); // Checks that the immutable values have not changed in new_parameters and diff --git a/pc/peer_connection_encodings_integrationtest.cc b/pc/peer_connection_encodings_integrationtest.cc index d6c4499210..06299d7029 100644 --- a/pc/peer_connection_encodings_integrationtest.cc +++ b/pc/peer_connection_encodings_integrationtest.cc @@ -134,12 +134,12 @@ class PeerConnectionEncodingsIntegrationTest : public ::testing::Test { return transceiver_or_error.value(); } - bool HasReceiverVideoCodecCapability( + bool HasSenderVideoCodecCapability( rtc::scoped_refptr pc_wrapper, absl::string_view codec_name) { std::vector codecs = pc_wrapper->pc_factory() - ->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO) + ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) .codecs; return std::find_if(codecs.begin(), codecs.end(), [&codec_name](const RtpCodecCapability& codec) { @@ -152,7 +152,7 @@ class PeerConnectionEncodingsIntegrationTest : public ::testing::Test { absl::string_view codec_name) { std::vector codecs = pc_wrapper->pc_factory() - ->GetRtpReceiverCapabilities(cricket::MEDIA_TYPE_VIDEO) + ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) .codecs; codecs.erase(std::remove_if(codecs.begin(), codecs.end(), [&codec_name](const RtpCodecCapability& codec) { @@ -431,7 +431,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP8"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); transceiver->SetCodecPreferences(codecs); NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); @@ -464,14 +464,10 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, rtc::scoped_refptr transceiver = AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); - // Restricting the local receive codecs will restrict what we offer and - // hence the answer if it is a subset of our offer. + // Restricting codecs restricts what SetParameters() will accept or reject. std::vector codecs = GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); transceiver->SetCodecPreferences(codecs); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); - // Attempt SVC (L3T3_KEY). This is not possible because only VP8 is up for // negotiation and VP8 does not support it. rtc::scoped_refptr sender = transceiver->sender(); @@ -485,6 +481,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, ASSERT_EQ(parameters.encodings.size(), 1u); EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt)); + NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); local_pc_wrapper->WaitForConnection(); remote_pc_wrapper->WaitForConnection(); @@ -505,60 +502,6 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq(absl::nullopt)); } -TEST_F(PeerConnectionEncodingsIntegrationTest, - SetParametersWithScalabilityModeNotSupportedBySubsequentNegotiation) { - rtc::scoped_refptr local_pc_wrapper = CreatePc(); - rtc::scoped_refptr remote_pc_wrapper = CreatePc(); - ExchangeIceCandidates(local_pc_wrapper, remote_pc_wrapper); - - std::vector layers = - CreateLayers({"f"}, /*active=*/true); - rtc::scoped_refptr transceiver = - AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, - layers); - // Restricting the local receive codecs will restrict what we offer and - // hence the answer if it is a subset of our offer. - std::vector codecs = - GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); - transceiver->SetCodecPreferences(codecs); - - // Attempt SVC (L3T3_KEY). This is still possible because VP9 might be - // available from the remote end. - rtc::scoped_refptr sender = transceiver->sender(); - RtpParameters parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - parameters.encodings[0].scalability_mode = "L3T3_KEY"; - parameters.encodings[0].scale_resolution_down_by = 1; - EXPECT_TRUE(sender->SetParameters(parameters).ok()); - - NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); - - // `scalability_mode` is set to the VP8 default since that is what was - // negotiated. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq("L1T2")); - - local_pc_wrapper->WaitForConnection(); - remote_pc_wrapper->WaitForConnection(); - - // Wait until media is flowing. - ASSERT_TRUE_WAIT(HasOutboundRtpBytesSent(local_pc_wrapper, 1u), - kDefaultTimeout.ms()); - // When `scalability_mode` is not set, VP8 defaults to L1T1. - rtc::scoped_refptr report = GetStats(local_pc_wrapper); - std::vector outbound_rtps = - report->GetStatsOfType(); - ASSERT_THAT(outbound_rtps, SizeIs(1u)); - EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), - StrCaseEq("video/VP8")); - EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T2")); - // GetParameters() confirms `scalability_mode` is still not set. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - EXPECT_THAT(parameters.encodings[0].scalability_mode, Eq("L1T2")); -} - TEST_F(PeerConnectionEncodingsIntegrationTest, VP8_FallbackFromSvcResultsInL1T2) { rtc::scoped_refptr local_pc_wrapper = CreatePc(); @@ -615,13 +558,6 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, EXPECT_THAT(GetCurrentCodecMimeType(report, *outbound_rtps[0]), StrCaseEq("video/VP8")); EXPECT_THAT(*outbound_rtps[0]->scalability_mode, StrEq("L1T2")); - - // Now that we know VP8 is used, try setting L3T3 which should fail. - parameters = sender->GetParameters(); - ASSERT_EQ(parameters.encodings.size(), 1u); - parameters.encodings[0].scalability_mode = "L3T3_KEY"; - parameters.encodings[0].scale_resolution_down_by = 1; - EXPECT_FALSE(sender->SetParameters(parameters).ok()); } // The legacy SVC path is triggered when VP9 us used, but `scalability_mode` has @@ -641,7 +577,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); @@ -686,7 +622,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Configure SVC, a.k.a. "L3T3_KEY". rtc::scoped_refptr sender = transceiver->sender(); @@ -739,7 +675,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Configure SVC, a.k.a. "L3T3_KEY". rtc::scoped_refptr sender = transceiver->sender(); @@ -789,7 +725,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // The original negotiation triggers legacy SVC because we didn't specify @@ -844,7 +780,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Legacy SVC mode and all layers inactive. @@ -881,7 +817,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // Standard mode and all layers inactive. @@ -921,7 +857,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, VP9_TargetBitrate_LegacyL1T3) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // In legacy SVC, disabling the bottom two layers encodings is interpreted as @@ -968,7 +904,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, VP9_TargetBitrate_StandardL1T3) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP9"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP9"); transceiver->SetCodecPreferences(codecs); // With standard APIs, L1T3 is explicitly specified and the encodings refers @@ -1019,7 +955,7 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, "VP8"); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, "VP8"); transceiver->SetCodecPreferences(codecs); NegotiateWithSimulcastTweaks(local_pc_wrapper, remote_pc_wrapper); @@ -1428,6 +1364,72 @@ TEST_F(PeerConnectionEncodingsIntegrationTest, EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION); } +TEST_F(PeerConnectionEncodingsIntegrationTest, + SetParametersRejectsNonPreferredCodecParameterAudio) { + rtc::scoped_refptr local_pc_wrapper = CreatePc(); + + absl::optional opus = + local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_AUDIO, + "opus"); + ASSERT_TRUE(opus); + + std::vector not_opus_codecs = + local_pc_wrapper->pc_factory() + ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_AUDIO) + .codecs; + not_opus_codecs.erase( + std::remove_if(not_opus_codecs.begin(), not_opus_codecs.end(), + [&](const auto& codec) { + return absl::EqualsIgnoreCase(codec.name, opus->name); + }), + not_opus_codecs.end()); + + auto transceiver_or_error = + local_pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_AUDIO); + ASSERT_TRUE(transceiver_or_error.ok()); + rtc::scoped_refptr audio_transceiver = + transceiver_or_error.MoveValue(); + ASSERT_TRUE(audio_transceiver->SetCodecPreferences(not_opus_codecs).ok()); + + RtpParameters parameters = audio_transceiver->sender()->GetParameters(); + parameters.encodings[0].codec = opus; + RTCError error = audio_transceiver->sender()->SetParameters(parameters); + EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION); +} + +TEST_F(PeerConnectionEncodingsIntegrationTest, + SetParametersRejectsNonPreferredCodecParameterVideo) { + rtc::scoped_refptr local_pc_wrapper = CreatePc(); + + absl::optional vp8 = + local_pc_wrapper->FindFirstSendCodecWithName(cricket::MEDIA_TYPE_VIDEO, + "vp8"); + ASSERT_TRUE(vp8); + + std::vector not_vp8_codecs = + local_pc_wrapper->pc_factory() + ->GetRtpSenderCapabilities(cricket::MEDIA_TYPE_VIDEO) + .codecs; + not_vp8_codecs.erase( + std::remove_if(not_vp8_codecs.begin(), not_vp8_codecs.end(), + [&](const auto& codec) { + return absl::EqualsIgnoreCase(codec.name, vp8->name); + }), + not_vp8_codecs.end()); + + auto transceiver_or_error = + local_pc_wrapper->pc()->AddTransceiver(cricket::MEDIA_TYPE_VIDEO); + ASSERT_TRUE(transceiver_or_error.ok()); + rtc::scoped_refptr video_transceiver = + transceiver_or_error.MoveValue(); + ASSERT_TRUE(video_transceiver->SetCodecPreferences(not_vp8_codecs).ok()); + + RtpParameters parameters = video_transceiver->sender()->GetParameters(); + parameters.encodings[0].codec = vp8; + RTCError error = video_transceiver->sender()->SetParameters(parameters); + EXPECT_EQ(error.type(), RTCErrorType::INVALID_MODIFICATION); +} + TEST_F(PeerConnectionEncodingsIntegrationTest, SetParametersRejectsNonNegotiatedCodecParameterAudio) { rtc::scoped_refptr local_pc_wrapper = CreatePc(); @@ -1873,7 +1875,7 @@ class PeerConnectionEncodingsIntegrationParameterizedTest bool SkipTestDueToAv1Missing( rtc::scoped_refptr local_pc_wrapper) { if (codec_name_ == "AV1" && - !HasReceiverVideoCodecCapability(local_pc_wrapper, "AV1")) { + !HasSenderVideoCodecCapability(local_pc_wrapper, "AV1")) { RTC_LOG(LS_WARNING) << "\n***\nAV1 is not available, skipping test.\n***"; return true; } @@ -1899,7 +1901,7 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, AllLayersInactive) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, codec_name_); transceiver->SetCodecPreferences(codecs); // Standard mode and all layers inactive. @@ -1942,7 +1944,7 @@ TEST_P(PeerConnectionEncodingsIntegrationParameterizedTest, Simulcast) { AddTransceiverWithSimulcastLayers(local_pc_wrapper, remote_pc_wrapper, layers); std::vector codecs = - GetCapabilitiesAndRestrictToCodec(remote_pc_wrapper, codec_name_); + GetCapabilitiesAndRestrictToCodec(local_pc_wrapper, codec_name_); transceiver->SetCodecPreferences(codecs); rtc::scoped_refptr sender = transceiver->sender(); diff --git a/pc/peer_connection_media_unittest.cc b/pc/peer_connection_media_unittest.cc index 04fb9c9e26..b892eacb78 100644 --- a/pc/peer_connection_media_unittest.cc +++ b/pc/peer_connection_media_unittest.cc @@ -1547,6 +1547,29 @@ TEST_F(PeerConnectionMediaTestUnifiedPlan, EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type()); } +TEST_F(PeerConnectionMediaTestUnifiedPlan, + SetCodecPreferencesAudioMissingSendCodec) { + auto fake_engine = std::make_unique(); + auto recv_codecs = fake_engine->voice().recv_codecs(); + recv_codecs.push_back(cricket::CreateAudioCodec(recv_codecs.back().id + 1, + "recv_only_codec", 0, 1)); + fake_engine->SetAudioRecvCodecs(recv_codecs); + auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine)); + + auto transceiver = caller->pc()->GetTransceivers().front(); + auto capabilities = caller->pc_factory()->GetRtpReceiverCapabilities( + cricket::MediaType::MEDIA_TYPE_AUDIO); + + std::vector codecs; + absl::c_copy_if(capabilities.codecs, std::back_inserter(codecs), + [](const RtpCodecCapability& codec) { + return codec.name.find("_only_") != std::string::npos; + }); + + auto result = transceiver->SetCodecPreferences(codecs); + EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type()); +} + TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesAudioRejectsVideoCodec) { auto caller = CreatePeerConnectionWithAudio(); diff --git a/pc/peer_connection_svc_integrationtest.cc b/pc/peer_connection_svc_integrationtest.cc index 7deafbf428..32ca451866 100644 --- a/pc/peer_connection_svc_integrationtest.cc +++ b/pc/peer_connection_svc_integrationtest.cc @@ -40,7 +40,7 @@ class PeerConnectionSVCIntegrationTest rtc::scoped_refptr transceiver, absl::string_view codec_name) { RtpCapabilities capabilities = - caller()->pc_factory()->GetRtpReceiverCapabilities( + caller()->pc_factory()->GetRtpSenderCapabilities( cricket::MEDIA_TYPE_VIDEO); std::vector codecs; for (const RtpCodecCapability& codec_capability : capabilities.codecs) { @@ -95,7 +95,7 @@ TEST_F(PeerConnectionSVCIntegrationTest, SetParametersAcceptsL1T3WithVP8) { ConnectFakeSignaling(); RtpCapabilities capabilities = - caller()->pc_factory()->GetRtpReceiverCapabilities( + caller()->pc_factory()->GetRtpSenderCapabilities( cricket::MEDIA_TYPE_VIDEO); std::vector vp8_codec; for (const RtpCodecCapability& codec_capability : capabilities.codecs) { @@ -119,6 +119,27 @@ TEST_F(PeerConnectionSVCIntegrationTest, SetParametersAcceptsL1T3WithVP8) { EXPECT_TRUE(result.ok()); } +TEST_F(PeerConnectionSVCIntegrationTest, SetParametersRejectsL3T3WithVP8) { + ASSERT_TRUE(CreatePeerConnectionWrappers()); + ConnectFakeSignaling(); + + RtpTransceiverInit init; + RtpEncodingParameters encoding_parameters; + init.send_encodings.push_back(encoding_parameters); + auto transceiver_or_error = + caller()->pc()->AddTransceiver(caller()->CreateLocalVideoTrack(), init); + ASSERT_TRUE(transceiver_or_error.ok()); + auto transceiver = transceiver_or_error.MoveValue(); + EXPECT_TRUE(SetCodecPreferences(transceiver, cricket::kVp8CodecName).ok()); + + RtpParameters parameters = transceiver->sender()->GetParameters(); + ASSERT_EQ(parameters.encodings.size(), 1u); + parameters.encodings[0].scalability_mode = "L3T3"; + auto result = transceiver->sender()->SetParameters(parameters); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.type(), RTCErrorType::INVALID_MODIFICATION); +} + TEST_F(PeerConnectionSVCIntegrationTest, SetParametersAcceptsL1T3WithVP8AfterNegotiation) { ASSERT_TRUE(CreatePeerConnectionWrappers()); @@ -230,7 +251,7 @@ TEST_F(PeerConnectionSVCIntegrationTest, FallbackToL1Tx) { auto caller_transceiver = transceiver_or_error.MoveValue(); RtpCapabilities capabilities = - caller()->pc_factory()->GetRtpReceiverCapabilities( + caller()->pc_factory()->GetRtpSenderCapabilities( cricket::MEDIA_TYPE_VIDEO); std::vector send_codecs = capabilities.codecs; // Only keep VP9 in the caller diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc index be0975778f..b0c32eff85 100644 --- a/pc/rtp_sender.cc +++ b/pc/rtp_sender.cc @@ -248,7 +248,7 @@ void RtpSenderBase::SetParametersInternal(const RtpParameters& parameters, } if (!media_channel_ || !ssrc_) { auto result = cricket::CheckRtpParametersInvalidModificationAndValues( - init_parameters_, parameters, send_codecs_, absl::nullopt); + init_parameters_, parameters, codec_preferences_, absl::nullopt); if (result.ok()) { init_parameters_ = parameters; } @@ -299,7 +299,7 @@ RTCError RtpSenderBase::SetParametersInternalWithAllLayers( } if (!media_channel_ || !ssrc_) { auto result = cricket::CheckRtpParametersInvalidModificationAndValues( - init_parameters_, parameters, send_codecs_, absl::nullopt); + init_parameters_, parameters, codec_preferences_, absl::nullopt); if (result.ok()) { init_parameters_ = parameters; } @@ -345,14 +345,16 @@ RTCError RtpSenderBase::CheckCodecParameters(const RtpParameters& parameters) { // the SVC capabilities. absl::optional send_codec_with_svc_info; if (send_codec && send_codec->type == cricket::Codec::Type::kVideo) { - auto codec_match = absl::c_find_if( - send_codecs_, [&](auto& codec) { return send_codec->Matches(codec); }); - if (codec_match != send_codecs_.end()) { + auto codec_match = + absl::c_find_if(codec_preferences_, [&](auto& codec_preference) { + return send_codec->Matches(codec_preference); + }); + if (codec_match != codec_preferences_.end()) { send_codec_with_svc_info = *codec_match; } } - return cricket::CheckScalabilityModeValues(parameters, send_codecs_, + return cricket::CheckScalabilityModeValues(parameters, codec_preferences_, send_codec_with_svc_info); } diff --git a/pc/rtp_sender.h b/pc/rtp_sender.h index 90d33aaffc..8925230636 100644 --- a/pc/rtp_sender.h +++ b/pc/rtp_sender.h @@ -102,7 +102,8 @@ class RtpSenderInternal : public RtpSenderInterface { // Used by the owning transceiver to inform the sender on the currently // selected codecs. - virtual void SetSendCodecs(std::vector send_codecs) = 0; + virtual void SetCodecPreferences( + std::vector codec_preferences) = 0; }; // Shared implementation for RtpSenderInternal interface. @@ -220,8 +221,9 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface { is_transceiver_stopped_ = true; } - void SetSendCodecs(std::vector send_codecs) override { - send_codecs_ = send_codecs; + void SetCodecPreferences( + std::vector codec_preferences) override { + codec_preferences_ = codec_preferences; } protected: @@ -259,7 +261,7 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface { std::vector stream_ids_; RtpParameters init_parameters_; - std::vector send_codecs_; + std::vector codec_preferences_; // TODO(tommi): `media_channel_` and several other member variables in this // class (ssrc_, stopped_, etc) are accessed from more than one thread without diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc index 55a0f7d584..de31b2e36a 100644 --- a/pc/rtp_transceiver.cc +++ b/pc/rtp_transceiver.cc @@ -41,12 +41,12 @@ namespace { RTCError VerifyCodecPreferences( const std::vector& codecs, + const std::vector& send_codecs, const std::vector& recv_codecs) { // If the intersection between codecs and // RTCRtpSender.getCapabilities(kind).codecs or the intersection between - // codecs and RTCRtpReceiver.getCapabilities(kind).codecs contains only - // contains RTX, RED, FEC or CN codecs or is an empty set, throw - // InvalidModificationError. + // codecs and RTCRtpReceiver.getCapabilities(kind).codecs only contains RTX, + // RED or FEC codecs or is an empty set, throw InvalidModificationError. // This ensures that we always have something to offer, regardless of // transceiver.direction. @@ -62,15 +62,34 @@ RTCError VerifyCodecPreferences( "codec capabilities."); } - // Let codecCapabilities RTCRtpReceiver.getCapabilities(kind).codecs. - // For each codec in codecs, If + if (!absl::c_any_of(codecs, [&send_codecs](const RtpCodecCapability& codec) { + return codec.IsMediaCodec() && + absl::c_any_of(send_codecs, + [&codec](const cricket::Codec& send_codec) { + return send_codec.MatchesRtpCodec(codec); + }); + })) { + LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_MODIFICATION, + "Invalid codec preferences: Missing codec from send " + "codec capabilities."); + } + + // Let codecCapabilities be the union of + // RTCRtpSender.getCapabilities(kind).codecs and + // RTCRtpReceiver.getCapabilities(kind).codecs. For each codec in codecs, If // codec is not in codecCapabilities, throw InvalidModificationError. for (const auto& codec_preference : codecs) { bool is_recv_codec = absl::c_any_of( recv_codecs, [&codec_preference](const cricket::Codec& codec) { return codec.MatchesRtpCodec(codec_preference); }); - if (!is_recv_codec) { + + bool is_send_codec = absl::c_any_of( + send_codecs, [&codec_preference](const cricket::Codec& codec) { + return codec.MatchesRtpCodec(codec_preference); + }); + + if (!is_recv_codec && !is_send_codec) { LOG_AND_RETURN_ERROR( RTCErrorType::INVALID_MODIFICATION, std::string("Invalid codec preferences: invalid codec with name \"") + @@ -91,6 +110,25 @@ RTCError VerifyCodecPreferences( return RTCError::OK(); } +// Matches the list of codecs as capabilities (potentially without SVC related +// information) to the list of send codecs and returns the list of codecs with +// all the SVC related information. +std::vector MatchCodecPreferences( + const std::vector& codecs, + const std::vector& send_codecs) { + std::vector result; + + for (const auto& codec_preference : codecs) { + for (const cricket::VideoCodec& send_codec : send_codecs) { + if (send_codec.MatchesRtpCodec(codec_preference)) { + result.push_back(send_codec); + } + } + } + + return result; +} + TaskQueueBase* GetCurrentTaskQueueOrThread() { TaskQueueBase* current = TaskQueueBase::Current(); if (!current) @@ -127,7 +165,7 @@ RtpTransceiver::RtpTransceiver( RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO || media_type_ == cricket::MEDIA_TYPE_VIDEO); RTC_DCHECK_EQ(sender->media_type(), receiver->media_type()); - sender->internal()->SetSendCodecs( + sender->internal()->SetCodecPreferences( sender->media_type() == cricket::MEDIA_TYPE_VIDEO ? media_engine()->video().send_codecs(false) : media_engine()->voice().send_codecs()); @@ -403,7 +441,10 @@ void RtpTransceiver::AddSender( media_type() == cricket::MEDIA_TYPE_VIDEO ? media_engine()->video().send_codecs(false) : media_engine()->voice().send_codecs(); - sender->internal()->SetSendCodecs(send_codecs); + sender->internal()->SetCodecPreferences( + codec_preferences_.empty() + ? send_codecs + : MatchCodecPreferences(codec_preferences_, send_codecs)); senders_.push_back(sender); } @@ -652,6 +693,10 @@ RTCError RtpTransceiver::SetCodecPreferences( // to codecs and abort these steps. if (codec_capabilities.empty()) { codec_preferences_.clear(); + senders_.front()->internal()->SetCodecPreferences( + media_type() == cricket::MEDIA_TYPE_VIDEO + ? media_engine()->video().send_codecs(false) + : media_engine()->voice().send_codecs()); return RTCError::OK(); } @@ -664,15 +709,19 @@ RTCError RtpTransceiver::SetCodecPreferences( // 6. to 8. RTCError result; - std::vector recv_codecs; + std::vector recv_codecs, send_codecs; if (media_type_ == cricket::MEDIA_TYPE_AUDIO) { + send_codecs = media_engine()->voice().send_codecs(); recv_codecs = media_engine()->voice().recv_codecs(); } else if (media_type_ == cricket::MEDIA_TYPE_VIDEO) { + send_codecs = media_engine()->video().send_codecs(context()->use_rtx()); recv_codecs = media_engine()->video().recv_codecs(context()->use_rtx()); } - result = VerifyCodecPreferences(codecs, recv_codecs); + result = VerifyCodecPreferences(codecs, send_codecs, recv_codecs); if (result.ok()) { + senders_.front()->internal()->SetCodecPreferences( + MatchCodecPreferences(codecs, send_codecs)); codec_preferences_ = codecs; } diff --git a/pc/test/mock_rtp_sender_internal.h b/pc/test/mock_rtp_sender_internal.h index 9a01aecabb..4cfb2cfeaf 100644 --- a/pc/test/mock_rtp_sender_internal.h +++ b/pc/test/mock_rtp_sender_internal.h @@ -69,7 +69,7 @@ class MockRtpSenderInternal : public RtpSenderInternal { (const RtpParameters&), (override)); MOCK_METHOD(void, - SetSendCodecs, + SetCodecPreferences, (std::vector), (override)); MOCK_METHOD(rtc::scoped_refptr, From e5cd905b9eb779fb205e8d2acedd44c09d9aad85 Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Tue, 13 Feb 2024 00:01:21 -0800 Subject: [PATCH 130/170] Roll chromium_revision 7d6bb2c760..4906525a63 (1259552:1259697) Change log: https://chromium.googlesource.com/chromium/src/+log/7d6bb2c760..4906525a63 Full diff: https://chromium.googlesource.com/chromium/src/+/7d6bb2c760..4906525a63 Changed dependencies * src/base: https://chromium.googlesource.com/chromium/src/base/+log/6c5ef966eb..fd5eca261f * src/build: https://chromium.googlesource.com/chromium/src/build/+log/fcd7410768..a301b4f2a6 * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/13076206a3..a87036f3ca * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/a043caba1c..0c4c3fa25c * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/d80f7d1ae4..99cae5876c * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/6d4102387b..8b818c04f0 DEPS diff: https://chromium.googlesource.com/chromium/src/+/7d6bb2c760..4906525a63/DEPS No update to Clang. BUG=None Change-Id: I5da5f4efa5c7b441752d8605f8256b33b85e0413 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339500 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41726} --- DEPS | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/DEPS b/DEPS index e7a37e36d4..1c15898e34 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '7d6bb2c760f35c5be1fd7fea97777f0c4af2de98', + 'chromium_revision': '4906525a6325738ef7ceaf4f00d2f2a30688bdd8', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -50,9 +50,9 @@ vars = { deps = { # TODO(kjellander): Move this to be Android-only. 'src/base': - 'https://chromium.googlesource.com/chromium/src/base@6c5ef966eb7ff2c6fd9a2087721627deba03e41d', + 'https://chromium.googlesource.com/chromium/src/base@fd5eca261fa03e22f053a0eaa5b010ca01c6fe51', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@fcd7410768a2dbcf3f8fe08e7f328f8a73183fe7', + 'https://chromium.googlesource.com/chromium/src/build@a301b4f2a6f84b49d4390072a534f429c01bcca2', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@f35a7d885ace0b7dd8e8ac2376ca759d3905f4dc', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -65,9 +65,9 @@ deps = { 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@13076206a34d1e2dd10be092db3e01e203e54945', + 'https://chromium.googlesource.com/chromium/src/testing@a87036f3cafb0e067d66ba33f3295c3f21ba97f5', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@a043caba1ce7313a0685f9fee77385132c34e0b4', + 'https://chromium.googlesource.com/chromium/src/third_party@0c4c3fa25c0dc8da2c1048eedd53c37a32bf57b4', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@d80f7d1ae4c6c010ecc8e660588f33f5768cb177', + 'https://chromium.googlesource.com/catapult.git@99cae5876c51001792d8225f77579eb537188490', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@6d4102387bd73d46e5580019016584d518f788e4', + 'https://chromium.googlesource.com/chromium/src/tools@8b818c04f0bd1b2f973f4b8195da73954b4f1000', 'src/third_party/accessibility_test_framework': { 'packages': [ From 14d7d2d845827fbae56d054805e1a4878875046f Mon Sep 17 00:00:00 2001 From: Diep Bui Date: Tue, 13 Feb 2024 11:05:24 +0000 Subject: [PATCH 131/170] Add an option to allow pacing at loss based estimate when network bandwidth is loss limited. Add a small clean up in LossBasedBandwidthEstimatorV2ReadyForUse since IsReady() includes IsEnabled(). Bug: webrtc:12707 Change-Id: I20dfeb2ab31e7724041f89af9f312211a3ae3d23 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339521 Commit-Queue: Diep Bui Reviewed-by: Per Kjellander Cr-Commit-Position: refs/heads/main@{#41727} --- .../goog_cc/goog_cc_network_control.cc | 3 +- .../goog_cc/loss_based_bwe_v2.cc | 11 +++++- .../goog_cc/loss_based_bwe_v2.h | 2 ++ .../goog_cc/loss_based_bwe_v2_test.cc | 36 +++++++++++++++++++ .../goog_cc/send_side_bandwidth_estimation.cc | 8 +++-- .../goog_cc/send_side_bandwidth_estimation.h | 1 + 6 files changed, 57 insertions(+), 4 deletions(-) diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc index 94645dcc4a..d8a0ce9d64 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -720,7 +720,8 @@ PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const { // Pacing rate is based on target rate before congestion window pushback, // because we don't want to build queues in the pacer when pushback occurs. DataRate pacing_rate = DataRate::Zero(); - if (pace_at_max_of_bwe_and_lower_link_capacity_ && estimate_) { + if (pace_at_max_of_bwe_and_lower_link_capacity_ && estimate_ && + !bandwidth_estimation_->PaceAtLossBasedEstimate()) { pacing_rate = std::max({min_total_allocated_bitrate_, estimate_->link_capacity_lower, last_loss_based_target_rate_}) * diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc index 95f821352a..7deeb7ad64 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc @@ -499,6 +499,8 @@ absl::optional LossBasedBweV2::CreateConfig( FieldTrialParameter padding_duration("PaddingDuration", TimeDelta::Zero()); FieldTrialParameter bound_best_candidate("BoundBestCandidate", false); + FieldTrialParameter pace_at_loss_based_estimate( + "PaceAtLossBasedEstimate", false); if (key_value_config) { ParseFieldTrial({&enabled, &bandwidth_rampup_upper_bound_factor, @@ -538,7 +540,8 @@ absl::optional LossBasedBweV2::CreateConfig( &hold_duration_factor, &use_byte_loss_rate, &padding_duration, - &bound_best_candidate}, + &bound_best_candidate, + &pace_at_loss_based_estimate}, key_value_config->Lookup("WebRTC-Bwe-LossBasedBweV2")); } @@ -604,6 +607,7 @@ absl::optional LossBasedBweV2::CreateConfig( config->use_byte_loss_rate = use_byte_loss_rate.Get(); config->padding_duration = padding_duration.Get(); config->bound_best_candidate = bound_best_candidate.Get(); + config->pace_at_loss_based_estimate = pace_at_loss_based_estimate.Get(); return config; } @@ -1199,4 +1203,9 @@ bool LossBasedBweV2::CanKeepIncreasingState(DataRate estimate) const { last_padding_info_.padding_rate < estimate; } +bool LossBasedBweV2::PaceAtLossBasedEstimate() const { + return config_->pace_at_loss_based_estimate && + loss_based_result_.state != LossBasedState::kDelayBasedEstimate; +} + } // namespace webrtc diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h index 9afbb11f1f..34c96c66d9 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h @@ -74,6 +74,7 @@ class LossBasedBweV2 { rtc::ArrayView packet_results, DataRate delay_based_estimate, bool in_alr); + bool PaceAtLossBasedEstimate() const; // For unit testing only. void SetBandwidthEstimate(DataRate bandwidth_estimate); @@ -124,6 +125,7 @@ class LossBasedBweV2 { bool use_byte_loss_rate = false; TimeDelta padding_duration = TimeDelta::Zero(); bool bound_best_candidate = false; + bool pace_at_loss_based_estimate = false; }; struct Derivatives { diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc index 9b7ad03148..bb867f4fb0 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc @@ -1776,5 +1776,41 @@ TEST_F(LossBasedBweV2Test, UseByteLossRate) { DataRate::KilobitsPerSec(150)); } +TEST_F(LossBasedBweV2Test, PaceAtLossBasedEstimate) { + ExplicitKeyValueConfig key_value_config(ShortObservationConfig( + "PaceAtLossBasedEstimate:true,PaddingDuration:1000ms")); + LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); + loss_based_bandwidth_estimator.SetBandwidthEstimate( + DataRate::KilobitsPerSec(1000)); + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWithReceivedPackets( + /*first_packet_timestamp=*/Timestamp::Zero()), + /*delay_based_estimate=*/DataRate::KilobitsPerSec(1000), + /*in_alr=*/false); + EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state, + LossBasedState::kDelayBasedEstimate); + EXPECT_FALSE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate()); + + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWith100pLossRate( + /*first_packet_timestamp=*/Timestamp::Zero() + + kObservationDurationLowerBound), + /*delay_based_estimate=*/DataRate::KilobitsPerSec(1000), + /*in_alr=*/false); + EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state, + LossBasedState::kDecreasing); + EXPECT_TRUE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate()); + + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWithReceivedPackets( + /*first_packet_timestamp=*/Timestamp::Zero() + + kObservationDurationLowerBound * 2), + /*delay_based_estimate=*/DataRate::KilobitsPerSec(1000), + /*in_alr=*/false); + EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state, + LossBasedState::kIncreaseUsingPadding); + EXPECT_TRUE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate()); +} + } // namespace } // namespace webrtc diff --git a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc index 211d86c95d..7b305f12f1 100644 --- a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc +++ b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc @@ -700,8 +700,12 @@ bool SendSideBandwidthEstimation::LossBasedBandwidthEstimatorV2Enabled() const { bool SendSideBandwidthEstimation::LossBasedBandwidthEstimatorV2ReadyForUse() const { - return LossBasedBandwidthEstimatorV2Enabled() && - loss_based_bandwidth_estimator_v2_->IsReady(); + return loss_based_bandwidth_estimator_v2_->IsReady(); +} + +bool SendSideBandwidthEstimation::PaceAtLossBasedEstimate() const { + return LossBasedBandwidthEstimatorV2ReadyForUse() && + loss_based_bandwidth_estimator_v2_->PaceAtLossBasedEstimate(); } } // namespace webrtc diff --git a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h index dd4d25a236..1d919af7b6 100644 --- a/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h +++ b/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h @@ -129,6 +129,7 @@ class SendSideBandwidthEstimation { BandwidthUsage delay_detector_state, absl::optional probe_bitrate, bool in_alr); + bool PaceAtLossBasedEstimate() const; private: friend class GoogCcStatePrinter; From d99fb2f6ffea7d60dd1ffa5d6e29ae58abbd834a Mon Sep 17 00:00:00 2001 From: chromium-webrtc-autoroll Date: Tue, 13 Feb 2024 06:02:35 -0800 Subject: [PATCH 132/170] Roll chromium_revision 4906525a63..a4279f2842 (1259697:1259805) Change log: https://chromium.googlesource.com/chromium/src/+log/4906525a63..a4279f2842 Full diff: https://chromium.googlesource.com/chromium/src/+/4906525a63..a4279f2842 Changed dependencies * src/build: https://chromium.googlesource.com/chromium/src/build/+log/a301b4f2a6..a3566ffdee * src/ios: https://chromium.googlesource.com/chromium/src/ios/+log/f3dc4ca279..37d33be47e * src/testing: https://chromium.googlesource.com/chromium/src/testing/+log/a87036f3ca..a7e90605df * src/third_party: https://chromium.googlesource.com/chromium/src/third_party/+log/0c4c3fa25c..121de111a9 * src/third_party/androidx: f2NTXeY1WbJ_lRwpAyZWORm3Ho9qRx28GRayw1ol5x8C..W2mpTbVe6yo3_GJiaoEVjCGnpicqsSrxcRMEADDJzMMC * src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/99cae5876c..c712e9cc34 * src/third_party/kotlin_stdlib: 7f5xFu_YQrbg_vacQ5mMcUFIkMPpvM_mQ8QERRKYBvUC..-uFeIws_FQzyqmgZlGL37ooRLAD8mwClD33O8rZwnTsC * src/third_party/r8: szZgxadOOC_Yfq3DhP5R0WR2LMRiVMVrt71WNfL5taIC..tp4vVuXzmyHJxDFlwxDb7RYZLLEufc3EnGTyOTCTNkgC * src/tools: https://chromium.googlesource.com/chromium/src/tools/+log/8b818c04f0..2b9f1d699f DEPS diff: https://chromium.googlesource.com/chromium/src/+/4906525a63..a4279f2842/DEPS No update to Clang. BUG=None Change-Id: I289ba81e7a357b058915ab8557ee50a89c707ef2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339580 Bot-Commit: Autoroller Commit-Queue: Autoroller Cr-Commit-Position: refs/heads/main@{#41728} --- DEPS | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/DEPS b/DEPS index 1c15898e34..074d19ef94 100644 --- a/DEPS +++ b/DEPS @@ -10,7 +10,7 @@ vars = { # chromium waterfalls. More info at: crbug.com/570091. 'checkout_configuration': 'default', 'checkout_instrumented_libraries': 'checkout_linux and checkout_configuration == "default"', - 'chromium_revision': '4906525a6325738ef7ceaf4f00d2f2a30688bdd8', + 'chromium_revision': 'a4279f28422a0b59acdc9fcfe7233d9f0e3b2dc6', # Fetch the prebuilt binaries for llvm-cov and llvm-profdata. Needed to # process the raw profiles produced by instrumented targets (built with @@ -52,7 +52,7 @@ deps = { 'src/base': 'https://chromium.googlesource.com/chromium/src/base@fd5eca261fa03e22f053a0eaa5b010ca01c6fe51', 'src/build': - 'https://chromium.googlesource.com/chromium/src/build@a301b4f2a6f84b49d4390072a534f429c01bcca2', + 'https://chromium.googlesource.com/chromium/src/build@a3566ffdee8a4dda521d05c378d915427d049292', 'src/buildtools': 'https://chromium.googlesource.com/chromium/src/buildtools@f35a7d885ace0b7dd8e8ac2376ca759d3905f4dc', # Gradle 6.6.1. Used for testing Android Studio project generation for WebRTC. @@ -61,13 +61,13 @@ deps = { 'condition': 'checkout_android', }, 'src/ios': { - 'url': 'https://chromium.googlesource.com/chromium/src/ios@f3dc4ca27976b474b2c8eed63b41db141453c260', + 'url': 'https://chromium.googlesource.com/chromium/src/ios@37d33be47e19e2d4450fcb9cdf6d3213d8e4ef89', 'condition': 'checkout_ios', }, 'src/testing': - 'https://chromium.googlesource.com/chromium/src/testing@a87036f3cafb0e067d66ba33f3295c3f21ba97f5', + 'https://chromium.googlesource.com/chromium/src/testing@a7e90605df75793b837bea0d56815344e28fe071', 'src/third_party': - 'https://chromium.googlesource.com/chromium/src/third_party@0c4c3fa25c0dc8da2c1048eedd53c37a32bf57b4', + 'https://chromium.googlesource.com/chromium/src/third_party@121de111a913373d1ac15e4605da24fd22b21bcf', 'src/buildtools/linux64': { 'packages': [ @@ -189,7 +189,7 @@ deps = { 'src/third_party/breakpad/breakpad': 'https://chromium.googlesource.com/breakpad/breakpad.git@6551ac3632eb7236642366f70a2eb865b87a3329', 'src/third_party/catapult': - 'https://chromium.googlesource.com/catapult.git@99cae5876c51001792d8225f77579eb537188490', + 'https://chromium.googlesource.com/catapult.git@c712e9cc34286f512da4300ede35957ea7c138a6', 'src/third_party/ced/src': { 'url': 'https://chromium.googlesource.com/external/github.com/google/compact_enc_det.git@ba412eaaacd3186085babcd901679a48863c7dd5', }, @@ -267,7 +267,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/kotlin_stdlib', - 'version': '7f5xFu_YQrbg_vacQ5mMcUFIkMPpvM_mQ8QERRKYBvUC', + 'version': '-uFeIws_FQzyqmgZlGL37ooRLAD8mwClD33O8rZwnTsC', }, ], 'condition': 'checkout_android', @@ -331,7 +331,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'szZgxadOOC_Yfq3DhP5R0WR2LMRiVMVrt71WNfL5taIC', + 'version': 'tp4vVuXzmyHJxDFlwxDb7RYZLLEufc3EnGTyOTCTNkgC', }, ], 'condition': 'checkout_android', @@ -355,7 +355,7 @@ deps = { 'condition': 'checkout_android', }, 'src/tools': - 'https://chromium.googlesource.com/chromium/src/tools@8b818c04f0bd1b2f973f4b8195da73954b4f1000', + 'https://chromium.googlesource.com/chromium/src/tools@2b9f1d699f313c182606ca27cdc220d9c4034577', 'src/third_party/accessibility_test_framework': { 'packages': [ @@ -405,7 +405,7 @@ deps = { 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'f2NTXeY1WbJ_lRwpAyZWORm3Ho9qRx28GRayw1ol5x8C', + 'version': 'W2mpTbVe6yo3_GJiaoEVjCGnpicqsSrxcRMEADDJzMMC', }, ], 'condition': 'checkout_android', From 495e23e60f5d01314cc69b23501297c7c07b0257 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Tue, 13 Feb 2024 20:12:35 -0800 Subject: [PATCH 133/170] Update WebRTC code version (2024-02-14T04:12:34). Bug: None Change-Id: I7c64b17a0a0a05e24b11fe19af8f1954f62837d2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339643 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41729} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 53072c0bb2..a536a4203a 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-10T04:07:36"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-14T04:12:34"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 94c3328b6138f75d0f027e04b7d9570cc479324f Mon Sep 17 00:00:00 2001 From: Dor Hen Date: Tue, 13 Feb 2024 11:51:01 +0200 Subject: [PATCH 134/170] Provide unified solution for dir name randomization in tests This approach actually wraps the unique identifier generation into the function that provides the output path for a test. This way we don't need to add `CreateRandomUuid()` everywhere that we have `test::OutputPath` and instead just rename to `test::OutputPathRandomDir` Bug: webrtc:15833 Change-Id: Ic9b69b5b599727f07b2906569a84a40edeecd1a0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338645 Reviewed-by: Harald Alvestrand Reviewed-by: Mirko Bonadei Commit-Queue: Jeremy Leconte Reviewed-by: Artem Titov Cr-Commit-Position: refs/heads/main@{#41730} --- test/BUILD.gn | 1 + test/testsupport/file_utils.cc | 8 ++++++++ test/testsupport/file_utils.h | 5 +++++ test/testsupport/file_utils_unittest.cc | 22 ++++++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/test/BUILD.gn b/test/BUILD.gn index 574496f2e3..ed5dc5173d 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -861,6 +861,7 @@ rtc_library("fileutils") { ":fileutils_override_api", ":fileutils_override_impl", "../rtc_base:checks", + "../rtc_base:ssl", "../rtc_base:stringutils", ] absl_deps = [ diff --git a/test/testsupport/file_utils.cc b/test/testsupport/file_utils.cc index 47fed9ac05..58ee16282e 100644 --- a/test/testsupport/file_utils.cc +++ b/test/testsupport/file_utils.cc @@ -54,6 +54,7 @@ #include "absl/strings/string_view.h" #include "rtc_base/checks.h" +#include "rtc_base/helpers.h" #include "rtc_base/string_utils.h" #include "rtc_base/strings/string_builder.h" #include "test/testsupport/file_utils_override.h" @@ -94,6 +95,13 @@ std::string OutputPath() { return webrtc::test::internal::OutputPath(); } +std::string OutputPathWithRandomDirectory() { + std::string path = webrtc::test::internal::OutputPath(); + std::string rand_dir = path + rtc::CreateRandomUuid(); + + return CreateDir(rand_dir) ? rand_dir + std::string(kPathDelimiter) : path; +} + std::string WorkingDir() { return webrtc::test::internal::WorkingDir(); } diff --git a/test/testsupport/file_utils.h b/test/testsupport/file_utils.h index ab80ca4454..120c6cb279 100644 --- a/test/testsupport/file_utils.h +++ b/test/testsupport/file_utils.h @@ -42,6 +42,11 @@ ABSL_CONST_INIT extern const absl::string_view kPathDelimiter; // found, the current working directory ("./") is returned as a fallback. std::string OutputPath(); +// Same as the above but appends a randomly named folder at the end of the path +// Primerly used to provide a solution for stress testing environments to +// prevent colission of files and folders. +std::string OutputPathWithRandomDirectory(); + // Generates an empty file with a unique name in the specified directory and // returns the file name and path. // TODO(titovartem) rename to TempFile and next method to TempFilename diff --git a/test/testsupport/file_utils_unittest.cc b/test/testsupport/file_utils_unittest.cc index 666d574a85..8f91d6db7c 100644 --- a/test/testsupport/file_utils_unittest.cc +++ b/test/testsupport/file_utils_unittest.cc @@ -120,6 +120,28 @@ TEST_F(FileUtilsTest, OutputPathFromRootWorkingDir) { ASSERT_THAT(result, EndsWith(expected_end)); } +TEST_F(FileUtilsTest, RandomOutputPathFromUnchangedWorkingDir) { + rtc::SetRandomTestMode(true); + std::string fixed_first_uuid = "def01482-f829-429a-bfd4-841706e92cdd"; + std::string expected_end = ExpectedRootDirByPlatform() + fixed_first_uuid + + std::string(kPathDelimiter); + std::string result = webrtc::test::OutputPathWithRandomDirectory(); + + ASSERT_THAT(result, EndsWith(expected_end)); +} + +TEST_F(FileUtilsTest, RandomOutputPathFromRootWorkingDir) { + ASSERT_EQ(0, chdir(kPathDelimiter.data())); + + rtc::SetRandomTestMode(true); + std::string fixed_first_uuid = "def01482-f829-429a-bfd4-841706e92cdd"; + std::string expected_end = ExpectedRootDirByPlatform() + fixed_first_uuid + + std::string(kPathDelimiter); + std::string result = webrtc::test::OutputPathWithRandomDirectory(); + + ASSERT_THAT(result, EndsWith(expected_end)); +} + TEST_F(FileUtilsTest, TempFilename) { std::string temp_filename = webrtc::test::TempFilename( webrtc::test::OutputPath(), "TempFilenameTest"); From 2bd4129e910683af471eefad320c755af4376e4a Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Mon, 12 Feb 2024 17:19:06 +0100 Subject: [PATCH 135/170] Set scoped field trials in encode/decode test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since not all codecs read field trials from the environment yet. Bug: webrtc:14852 Change-Id: Ia2477c41d09dabf91f47c59eb3139d6d6a711548 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339380 Auto-Submit: Sergey Silkin Reviewed-by: Åsa Persson Commit-Queue: Åsa Persson Cr-Commit-Position: refs/heads/main@{#41731} --- modules/video_coding/BUILD.gn | 1 + modules/video_coding/codecs/test/video_codec_test.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index e926ff84d7..ce0a9f1e5e 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -1015,6 +1015,7 @@ if (rtc_include_tests) { "../../rtc_base:logging", "../../rtc_base:stringutils", "../../test:explicit_key_value_config", + "../../test:field_trial", "../../test:fileutils", "../../test:test_flags", "../../test:test_main", diff --git a/modules/video_coding/codecs/test/video_codec_test.cc b/modules/video_coding/codecs/test/video_codec_test.cc index b6d5967589..0811685e33 100644 --- a/modules/video_coding/codecs/test/video_codec_test.cc +++ b/modules/video_coding/codecs/test/video_codec_test.cc @@ -29,6 +29,7 @@ #include "rtc_base/logging.h" #include "rtc_base/strings/string_builder.h" #include "test/explicit_key_value_config.h" +#include "test/field_trial.h" #include "test/gtest.h" #include "test/test_flags.h" #include "test/testsupport/file_utils.h" @@ -533,6 +534,7 @@ INSTANTIATE_TEST_SUITE_P( FramerateAdaptationTest::TestParamsToString); TEST(VideoCodecTest, DISABLED_EncodeDecode) { + ScopedFieldTrials field_trials(absl::GetFlag(FLAGS_field_trials)); const Environment env = CreateEnvironment(std::make_unique( absl::GetFlag(FLAGS_field_trials))); From 7a6a8ebf238469cd18bd8141d04db7f8f619a86f Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Thu, 8 Feb 2024 08:41:01 +0100 Subject: [PATCH 136/170] sdp: backfill default codec parameters for H265 with default values for level-id and tx-mode defined in https://datatracker.ietf.org/doc/html/draft-aboba-avtcore-hevc-webrtc BUG=webrtc:15703 Change-Id: I07d77d69c6376313e693e8ddda1cc0135033549a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338620 Reviewed-by: Harald Alvestrand Reviewed-by: Sergey Silkin Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41732} --- pc/webrtc_sdp.cc | 8 ++++++++ pc/webrtc_sdp_unittest.cc | 12 +++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc index 6b63eb8a6e..ea433583ab 100644 --- a/pc/webrtc_sdp.cc +++ b/pc/webrtc_sdp.cc @@ -2608,6 +2608,14 @@ static void BackfillCodecParameters(std::vector& codecs) { if (!codec.GetParam(cricket::kAv1FmtpTier, &unused_value)) { codec.SetParam(cricket::kAv1FmtpTier, "0"); } + } else if (absl::EqualsIgnoreCase(cricket::kH265CodecName, codec.name)) { + // https://datatracker.ietf.org/doc/html/draft-aboba-avtcore-hevc-webrtc + if (!codec.GetParam(cricket::kH265FmtpLevelId, &unused_value)) { + codec.SetParam(cricket::kH265FmtpLevelId, "93"); + } + if (!codec.GetParam(cricket::kH265FmtpTxMode, &unused_value)) { + codec.SetParam(cricket::kH265FmtpTxMode, "SRST"); + } } } } diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc index 6811381bb7..a31aa2adef 100644 --- a/pc/webrtc_sdp_unittest.cc +++ b/pc/webrtc_sdp_unittest.cc @@ -5061,7 +5061,7 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { "a=setup:actpass\r\n" "a=ice-ufrag:ETEn\r\n" "a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l\r\n" - "m=video 9 UDP/TLS/RTP/SAVPF 96 97 98\r\n" + "m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99\r\n" "c=IN IP4 0.0.0.0\r\n" "a=rtcp-mux\r\n" "a=sendonly\r\n" @@ -5069,6 +5069,7 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { "a=rtpmap:96 H264/90000\r\n" "a=rtpmap:97 VP9/90000\r\n" "a=rtpmap:98 AV1/90000\r\n" + "a=rtpmap:99 H265/90000\r\n" "a=ssrc:1234 cname:test\r\n"; JsepSessionDescription jdesc(kDummyType); EXPECT_TRUE(SdpDeserialize(sdp, &jdesc)); @@ -5077,7 +5078,7 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { const auto* description = content.media_description(); ASSERT_NE(description, nullptr); const std::vector codecs = description->codecs(); - ASSERT_EQ(codecs.size(), 3u); + ASSERT_EQ(codecs.size(), 4u); std::string value; EXPECT_EQ(codecs[0].name, "H264"); @@ -5095,5 +5096,10 @@ TEST_F(WebRtcSdpTest, BackfillsDefaultFmtpValues) { EXPECT_EQ(value, "5"); EXPECT_TRUE(codecs[2].GetParam("tier", &value)); EXPECT_EQ(value, "0"); - RTC_LOG(LS_ERROR) << sdp; + + EXPECT_EQ(codecs[3].name, "H265"); + EXPECT_TRUE(codecs[3].GetParam("level-id", &value)); + EXPECT_EQ(value, "93"); + EXPECT_TRUE(codecs[3].GetParam("tx-mode", &value)); + EXPECT_EQ(value, "SRST"); } From 050ffefd854f8a57071992238723259e9ae0d85a Mon Sep 17 00:00:00 2001 From: henrika Date: Wed, 14 Feb 2024 10:25:56 +0100 Subject: [PATCH 137/170] Extends WebRTC logs for software encoder fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL extends logging related to HW->SW fallbacks on the encoder side in WebRTC. The goal is to make it easier to track down the different steps taken when setting up the video encoder and why/when HW encoding fails. Current logs are added on several lines which makes regexp searching difficult. This CL adds all related information on one line instead. Three new search tags are also added VSE (VideoStreamEncoder), VESFW (VideoEncoderSoftwareFallbackWrapper) and SEA (SimulcastEncoderAdapter). The idea is to allow searching for the tags to see correlated logs. It has been verified that these added logs also show up in WebRTC logs in Meet. Logs from the GPU process are not included due to the sandboxed nature which makes it much more complex to add to the native WebRTC log. I think that these simple logs will provide value as is. Example: https://gist.github.com/henrik-and/41946f7f0b10774241bd14d7687f770b Bug: b/322132132 Change-Id: Iec58c9741a9dd6bab3236a88e9a6e45440f5d980 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339260 Commit-Queue: Henrik Andreassson Reviewed-by: Ilya Nikolaevskiy Reviewed-by: Henrik Boström Cr-Commit-Position: refs/heads/main@{#41733} --- api/video_codecs/video_codec.cc | 30 +++++++++++ api/video_codecs/video_codec.h | 4 ++ ...video_encoder_software_fallback_wrapper.cc | 17 +++++- media/engine/simulcast_encoder_adapter.cc | 15 +++++- modules/video_coding/BUILD.gn | 1 + .../video_coding/include/video_error_codes.cc | 43 +++++++++++++++ .../video_coding/include/video_error_codes.h | 10 ++-- video/video_stream_encoder.cc | 53 ++++++++++--------- 8 files changed, 142 insertions(+), 31 deletions(-) create mode 100644 modules/video_coding/include/video_error_codes.cc diff --git a/api/video_codecs/video_codec.cc b/api/video_codecs/video_codec.cc index 39a345d699..82c9bfc8ea 100644 --- a/api/video_codecs/video_codec.cc +++ b/api/video_codecs/video_codec.cc @@ -16,6 +16,7 @@ #include "absl/strings/match.h" #include "rtc_base/checks.h" +#include "rtc_base/strings/string_builder.h" namespace webrtc { namespace { @@ -73,6 +74,35 @@ VideoCodec::VideoCodec() codec_specific_(), complexity_(VideoCodecComplexity::kComplexityNormal) {} +std::string VideoCodec::ToString() const { + char string_buf[2048]; + rtc::SimpleStringBuilder ss(string_buf); + + ss << "VideoCodec {" << "type: " << CodecTypeToPayloadString(codecType) + << ", mode: " + << (mode == VideoCodecMode::kRealtimeVideo ? "RealtimeVideo" + : "Screensharing"); + if (IsSinglecast()) { + absl::optional scalability_mode = GetScalabilityMode(); + if (scalability_mode.has_value()) { + ss << ", Singlecast: {" << width << "x" << height << " " + << ScalabilityModeToString(*scalability_mode) + << (active ? ", active" : ", inactive") << "}"; + } + } else { + ss << ", Simulcast: {"; + for (size_t i = 0; i < numberOfSimulcastStreams; ++i) { + const SimulcastStream stream = simulcastStream[i]; + ss << "[" << stream.width << "x" << stream.height << " " + << ScalabilityModeToString(stream.GetScalabilityMode()) + << (stream.active ? ", active" : ", inactive") << "]"; + } + ss << "}"; + } + ss << "}"; + return ss.str(); +} + VideoCodecVP8* VideoCodec::VP8() { RTC_DCHECK_EQ(codecType, kVideoCodecVP8); return &codec_specific_.VP8; diff --git a/api/video_codecs/video_codec.h b/api/video_codecs/video_codec.h index a596af1528..e48ffd4b5f 100644 --- a/api/video_codecs/video_codec.h +++ b/api/video_codecs/video_codec.h @@ -141,6 +141,9 @@ class RTC_EXPORT VideoCodec { bool GetFrameDropEnabled() const; void SetFrameDropEnabled(bool enabled); + bool IsSinglecast() const { return numberOfSimulcastStreams <= 1; } + bool IsSimulcast() const { return !IsSinglecast(); } + // Public variables. TODO(hta): Make them private with accessors. VideoCodecType codecType; @@ -193,6 +196,7 @@ class RTC_EXPORT VideoCodec { bool operator==(const VideoCodec& other) const = delete; bool operator!=(const VideoCodec& other) const = delete; + std::string ToString() const; // Accessors for codec specific information. // There is a const version of each that returns a reference, diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc index d35c9f9950..5f34694ae1 100644 --- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc @@ -264,14 +264,17 @@ void VideoEncoderSoftwareFallbackWrapper::PrimeEncoder( } bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder(bool is_forced) { - RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding."; + RTC_LOG(LS_WARNING) << "[VESFW] " << __func__ + << "(is_forced=" << (is_forced ? "true" : "false") << ")"; RTC_DCHECK(encoder_settings_.has_value()); const int ret = fallback_encoder_->InitEncode(&codec_settings_, encoder_settings_.value()); if (ret != WEBRTC_VIDEO_CODEC_OK) { - RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback."; + RTC_LOG(LS_ERROR) + << "[VESFW] software-encoder fallback initialization failed with" + << " error code: " << WebRtcVideoCodecErrorToString(ret); fallback_encoder_->Release(); return false; } @@ -305,6 +308,12 @@ void VideoEncoderSoftwareFallbackWrapper::SetFecControllerOverride( int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( const VideoCodec* codec_settings, const VideoEncoder::Settings& settings) { + RTC_LOG(LS_INFO) << "[VESFW] " << __func__ + << "(codec=" << codec_settings->ToString() + << ", settings={number_of_cores: " + << settings.number_of_cores + << ", max_payload_size: " << settings.max_payload_size + << "})"; // Store settings, in case we need to dynamically switch to the fallback // encoder after a failed Encode call. codec_settings_ = *codec_settings; @@ -327,6 +336,8 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( PrimeEncoder(current_encoder()); return ret; } + RTC_LOG(LS_WARNING) << "[VESFW] Hardware encoder initialization failed with" + << " error code: " << WebRtcVideoCodecErrorToString(ret); // Try to instantiate software codec. if (InitFallbackEncoder(/*is_forced=*/false)) { @@ -335,6 +346,8 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( } // Software encoder failed too, use original return code. + RTC_LOG(LS_WARNING) + << "[VESFW] Software fallback encoder initialization also failed."; encoder_state_ = EncoderState::kUninitialized; return ret; } diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index 4853e68996..cb31306a60 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -360,8 +360,14 @@ int SimulcastEncoderAdapter::InitEncode( bool separate_encoders_needed = !encoder_context->encoder().GetEncoderInfo().supports_simulcast || active_streams_count == 1; + RTC_LOG(LS_INFO) << "[SEA] InitEncode: total_streams_count: " + << total_streams_count_ + << ", active_streams_count: " << active_streams_count + << ", separate_encoders_needed: " + << (separate_encoders_needed ? "true" : "false"); // Singlecast or simulcast with simulcast-capable underlaying encoder. if (total_streams_count_ == 1 || !separate_encoders_needed) { + RTC_LOG(LS_INFO) << "[SEA] InitEncode: Single-encoder mode"; int ret = encoder_context->encoder().InitEncode(&codec_, settings); if (ret >= 0) { stream_contexts_.emplace_back( @@ -377,7 +383,8 @@ int SimulcastEncoderAdapter::InitEncode( encoder_context->Release(); if (total_streams_count_ == 1) { - // Failed to initialize singlecast encoder. + RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: " + << WebRtcVideoCodecErrorToString(ret); return ret; } } @@ -405,10 +412,16 @@ int SimulcastEncoderAdapter::InitEncode( /*is_lowest_quality_stream=*/stream_idx == lowest_quality_stream_idx, /*is_highest_quality_stream=*/stream_idx == highest_quality_stream_idx); + RTC_LOG(LS_INFO) << "[SEA] Multi-encoder mode: initializing stream: " + << stream_idx << ", active: " + << (codec_.simulcastStream[stream_idx].active ? "true" + : "false"); int ret = encoder_context->encoder().InitEncode(&stream_codec, settings); if (ret < 0) { encoder_context.reset(); Release(); + RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: " + << WebRtcVideoCodecErrorToString(ret); return ret; } diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index ce0a9f1e5e..2208b9d967 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -286,6 +286,7 @@ rtc_library("video_codec_interface") { "include/video_codec_interface.cc", "include/video_codec_interface.h", "include/video_coding_defines.h", + "include/video_error_codes.cc", "include/video_error_codes.h", "video_coding_defines.cc", ] diff --git a/modules/video_coding/include/video_error_codes.cc b/modules/video_coding/include/video_error_codes.cc new file mode 100644 index 0000000000..c806753ea7 --- /dev/null +++ b/modules/video_coding/include/video_error_codes.cc @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 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 "modules/video_coding/include/video_error_codes.h" + +namespace webrtc { +const char* WebRtcVideoCodecErrorToString(int32_t error_code) { + switch (error_code) { + case WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT: + return "WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT"; + case WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME: + return "WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME"; + case WEBRTC_VIDEO_CODEC_NO_OUTPUT: + return "WEBRTC_VIDEO_CODEC_NO_OUTPUT"; + case WEBRTC_VIDEO_CODEC_ERROR: + return "WEBRTC_VIDEO_CODEC_ERROR"; + case WEBRTC_VIDEO_CODEC_MEMORY: + return "WEBRTC_VIDEO_CODEC_MEMORY"; + case WEBRTC_VIDEO_CODEC_ERR_PARAMETER: + return "WEBRTC_VIDEO_CODEC_ERR_PARAMETER"; + case WEBRTC_VIDEO_CODEC_TIMEOUT: + return "WEBRTC_VIDEO_CODEC_TIMEOUT"; + case WEBRTC_VIDEO_CODEC_UNINITIALIZED: + return "WEBRTC_VIDEO_CODEC_UNINITIALIZED"; + case WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE: + return "WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE"; + case WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED: + return "WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED"; + case WEBRTC_VIDEO_CODEC_ENCODER_FAILURE: + return "WEBRTC_VIDEO_CODEC_ENCODER_FAILURE"; + default: + return "WEBRTC_VIDEO_CODEC_UNKNOWN"; + } +} + +} // namespace webrtc diff --git a/modules/video_coding/include/video_error_codes.h b/modules/video_coding/include/video_error_codes.h index 17146ce205..1634678aeb 100644 --- a/modules/video_coding/include/video_error_codes.h +++ b/modules/video_coding/include/video_error_codes.h @@ -11,9 +11,7 @@ #ifndef MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ #define MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ -// NOTE: in sync with video_coding_module_defines.h - -// Define return values +#include #define WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT 5 #define WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME 4 @@ -28,4 +26,10 @@ #define WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED -15 #define WEBRTC_VIDEO_CODEC_ENCODER_FAILURE -16 +namespace webrtc { + +const char* WebRtcVideoCodecErrorToString(int32_t error_code); + +} // namespace webrtc + #endif // MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 3730f6eecb..6f398ec455 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -937,6 +937,8 @@ void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config, void VideoStreamEncoder::ReconfigureEncoder() { // Running on the encoder queue. RTC_DCHECK(pending_encoder_reconfiguration_); + RTC_LOG(LS_INFO) << "[VSE] " << __func__ + << " [encoder_config=" << encoder_config_.ToString() << "]"; bool encoder_reset_required = false; if (pending_encoder_creation_) { @@ -1154,37 +1156,38 @@ void VideoStreamEncoder::ReconfigureEncoder() { char log_stream_buf[4 * 1024]; rtc::SimpleStringBuilder log_stream(log_stream_buf); - log_stream << "ReconfigureEncoder:\n"; - log_stream << "Simulcast streams:\n"; + log_stream << "ReconfigureEncoder: simulcast streams: "; for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) { - log_stream << i << ": " << codec.simulcastStream[i].width << "x" - << codec.simulcastStream[i].height - << " min_kbps: " << codec.simulcastStream[i].minBitrate - << " target_kbps: " << codec.simulcastStream[i].targetBitrate - << " max_kbps: " << codec.simulcastStream[i].maxBitrate - << " max_fps: " << codec.simulcastStream[i].maxFramerate - << " max_qp: " << codec.simulcastStream[i].qpMax - << " num_tl: " << codec.simulcastStream[i].numberOfTemporalLayers - << " active: " - << (codec.simulcastStream[i].active ? "true" : "false") << "\n"; + log_stream << "{" << i << ": " << codec.simulcastStream[i].width << "x" + << codec.simulcastStream[i].height << " " + << ScalabilityModeToString( + codec.simulcastStream[i].GetScalabilityMode()) + << ", min_kbps: " << codec.simulcastStream[i].minBitrate + << ", target_kbps: " << codec.simulcastStream[i].targetBitrate + << ", max_kbps: " << codec.simulcastStream[i].maxBitrate + << ", max_fps: " << codec.simulcastStream[i].maxFramerate + << ", max_qp: " << codec.simulcastStream[i].qpMax << ", num_tl: " + << codec.simulcastStream[i].numberOfTemporalLayers + << ", active: " + << (codec.simulcastStream[i].active ? "true" : "false") << "}"; } if (encoder_config_.codec_type == kVideoCodecVP9 || encoder_config_.codec_type == kVideoCodecAV1) { - log_stream << "Spatial layers:\n"; + log_stream << ", spatial layers: "; for (int i = 0; i < GetNumSpatialLayers(codec); ++i) { - log_stream << i << ": " << codec.spatialLayers[i].width << "x" + log_stream << "{" << i << ": " << codec.spatialLayers[i].width << "x" << codec.spatialLayers[i].height - << " min_kbps: " << codec.spatialLayers[i].minBitrate - << " target_kbps: " << codec.spatialLayers[i].targetBitrate - << " max_kbps: " << codec.spatialLayers[i].maxBitrate - << " max_fps: " << codec.spatialLayers[i].maxFramerate - << " max_qp: " << codec.spatialLayers[i].qpMax - << " num_tl: " << codec.spatialLayers[i].numberOfTemporalLayers - << " active: " - << (codec.spatialLayers[i].active ? "true" : "false") << "\n"; + << ", min_kbps: " << codec.spatialLayers[i].minBitrate + << ", target_kbps: " << codec.spatialLayers[i].targetBitrate + << ", max_kbps: " << codec.spatialLayers[i].maxBitrate + << ", max_fps: " << codec.spatialLayers[i].maxFramerate + << ", max_qp: " << codec.spatialLayers[i].qpMax << ", num_tl: " + << codec.spatialLayers[i].numberOfTemporalLayers + << ", active: " + << (codec.spatialLayers[i].active ? "true" : "false") << "}"; } } - RTC_LOG(LS_INFO) << log_stream.str(); + RTC_LOG(LS_INFO) << "[VSE] " << log_stream.str(); codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000, codec.minBitrate); @@ -1319,7 +1322,7 @@ void VideoStreamEncoder::ReconfigureEncoder() { << " max frame rate " << codec.maxFramerate << " max payload size " << max_data_payload_length_; } else { - RTC_LOG(LS_ERROR) << "Failed to configure encoder."; + RTC_LOG(LS_ERROR) << "[VSE] Failed to configure encoder."; rate_allocator_ = nullptr; } @@ -1917,7 +1920,7 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, stream_resource_manager_.ConfigureQualityScaler(info); stream_resource_manager_.ConfigureBandwidthQualityScaler(info); - RTC_LOG(LS_INFO) << "Encoder info changed to " << info.ToString(); + RTC_LOG(LS_INFO) << "[VSE] Encoder info changed to " << info.ToString(); } if (bitrate_adjuster_) { From 7fc9535d8bd8d159db6802bcc6d52e75d85c99c8 Mon Sep 17 00:00:00 2001 From: Johannes Kron Date: Fri, 9 Feb 2024 16:23:18 +0100 Subject: [PATCH 138/170] Add trace event with qp value to VideoStreamEncoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: None Change-Id: I11c88a948b1940cac91ac6132e44107db0c5c46a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338980 Reviewed-by: Erik Språng Commit-Queue: Johannes Kron Cr-Commit-Position: refs/heads/main@{#41734} --- video/video_stream_encoder.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 6f398ec455..73cd7826f9 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -2105,6 +2105,8 @@ EncodedImage VideoStreamEncoder::AugmentEncodedImage( .Parse(codec_type, stream_idx, image_copy.data(), image_copy.size()) .value_or(-1); } + TRACE_EVENT2("webrtc", "VideoStreamEncoder::AugmentEncodedImage", + "stream_idx", stream_idx, "qp", image_copy.qp_); RTC_LOG(LS_VERBOSE) << __func__ << " ntp time " << encoded_image.NtpTimeMs() << " stream_idx " << stream_idx << " qp " << image_copy.qp_; From 23c32da48ae3f5f146dbd60b8b7fe4416f3750b4 Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Wed, 14 Feb 2024 13:43:31 +0000 Subject: [PATCH 139/170] Revert "Extends WebRTC logs for software encoder fallback" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 050ffefd854f8a57071992238723259e9ae0d85a. Reason for revert: Breaks downstream project. Original change's description: > Extends WebRTC logs for software encoder fallback > > This CL extends logging related to HW->SW fallbacks on the encoder > side in WebRTC. The goal is to make it easier to track down the > different steps taken when setting up the video encoder and why/when > HW encoding fails. > > Current logs are added on several lines which makes regexp searching > difficult. This CL adds all related information on one line instead. > > Three new search tags are also added VSE (VideoStreamEncoder), VESFW > (VideoEncoderSoftwareFallbackWrapper) and SEA (SimulcastEncoderAdapter). The idea is to allow searching for the tags to see correlated logs. > > It has been verified that these added logs also show up in WebRTC > logs in Meet. > > Logs from the GPU process are not included due to the sandboxed > nature which makes it much more complex to add to the native > WebRTC log. I think that these simple logs will provide value as is. > > Example: https://gist.github.com/henrik-and/41946f7f0b10774241bd14d7687f770b > > Bug: b/322132132 > Change-Id: Iec58c9741a9dd6bab3236a88e9a6e45440f5d980 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339260 > Commit-Queue: Henrik Andreassson > Reviewed-by: Ilya Nikolaevskiy > Reviewed-by: Henrik Boström > Cr-Commit-Position: refs/heads/main@{#41733} Bug: b/322132132 Change-Id: I24d0a4e71a43ac192485f1af208563a51d919865 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339661 Bot-Commit: rubber-stamper@appspot.gserviceaccount.com Owners-Override: Mirko Bonadei Commit-Queue: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41735} --- api/video_codecs/video_codec.cc | 30 ----------- api/video_codecs/video_codec.h | 4 -- ...video_encoder_software_fallback_wrapper.cc | 17 +----- media/engine/simulcast_encoder_adapter.cc | 15 +----- modules/video_coding/BUILD.gn | 1 - .../video_coding/include/video_error_codes.cc | 43 --------------- .../video_coding/include/video_error_codes.h | 10 ++-- video/video_stream_encoder.cc | 53 +++++++++---------- 8 files changed, 31 insertions(+), 142 deletions(-) delete mode 100644 modules/video_coding/include/video_error_codes.cc diff --git a/api/video_codecs/video_codec.cc b/api/video_codecs/video_codec.cc index 82c9bfc8ea..39a345d699 100644 --- a/api/video_codecs/video_codec.cc +++ b/api/video_codecs/video_codec.cc @@ -16,7 +16,6 @@ #include "absl/strings/match.h" #include "rtc_base/checks.h" -#include "rtc_base/strings/string_builder.h" namespace webrtc { namespace { @@ -74,35 +73,6 @@ VideoCodec::VideoCodec() codec_specific_(), complexity_(VideoCodecComplexity::kComplexityNormal) {} -std::string VideoCodec::ToString() const { - char string_buf[2048]; - rtc::SimpleStringBuilder ss(string_buf); - - ss << "VideoCodec {" << "type: " << CodecTypeToPayloadString(codecType) - << ", mode: " - << (mode == VideoCodecMode::kRealtimeVideo ? "RealtimeVideo" - : "Screensharing"); - if (IsSinglecast()) { - absl::optional scalability_mode = GetScalabilityMode(); - if (scalability_mode.has_value()) { - ss << ", Singlecast: {" << width << "x" << height << " " - << ScalabilityModeToString(*scalability_mode) - << (active ? ", active" : ", inactive") << "}"; - } - } else { - ss << ", Simulcast: {"; - for (size_t i = 0; i < numberOfSimulcastStreams; ++i) { - const SimulcastStream stream = simulcastStream[i]; - ss << "[" << stream.width << "x" << stream.height << " " - << ScalabilityModeToString(stream.GetScalabilityMode()) - << (stream.active ? ", active" : ", inactive") << "]"; - } - ss << "}"; - } - ss << "}"; - return ss.str(); -} - VideoCodecVP8* VideoCodec::VP8() { RTC_DCHECK_EQ(codecType, kVideoCodecVP8); return &codec_specific_.VP8; diff --git a/api/video_codecs/video_codec.h b/api/video_codecs/video_codec.h index e48ffd4b5f..a596af1528 100644 --- a/api/video_codecs/video_codec.h +++ b/api/video_codecs/video_codec.h @@ -141,9 +141,6 @@ class RTC_EXPORT VideoCodec { bool GetFrameDropEnabled() const; void SetFrameDropEnabled(bool enabled); - bool IsSinglecast() const { return numberOfSimulcastStreams <= 1; } - bool IsSimulcast() const { return !IsSinglecast(); } - // Public variables. TODO(hta): Make them private with accessors. VideoCodecType codecType; @@ -196,7 +193,6 @@ class RTC_EXPORT VideoCodec { bool operator==(const VideoCodec& other) const = delete; bool operator!=(const VideoCodec& other) const = delete; - std::string ToString() const; // Accessors for codec specific information. // There is a const version of each that returns a reference, diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc index 5f34694ae1..d35c9f9950 100644 --- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc @@ -264,17 +264,14 @@ void VideoEncoderSoftwareFallbackWrapper::PrimeEncoder( } bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder(bool is_forced) { - RTC_LOG(LS_WARNING) << "[VESFW] " << __func__ - << "(is_forced=" << (is_forced ? "true" : "false") << ")"; + RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding."; RTC_DCHECK(encoder_settings_.has_value()); const int ret = fallback_encoder_->InitEncode(&codec_settings_, encoder_settings_.value()); if (ret != WEBRTC_VIDEO_CODEC_OK) { - RTC_LOG(LS_ERROR) - << "[VESFW] software-encoder fallback initialization failed with" - << " error code: " << WebRtcVideoCodecErrorToString(ret); + RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback."; fallback_encoder_->Release(); return false; } @@ -308,12 +305,6 @@ void VideoEncoderSoftwareFallbackWrapper::SetFecControllerOverride( int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( const VideoCodec* codec_settings, const VideoEncoder::Settings& settings) { - RTC_LOG(LS_INFO) << "[VESFW] " << __func__ - << "(codec=" << codec_settings->ToString() - << ", settings={number_of_cores: " - << settings.number_of_cores - << ", max_payload_size: " << settings.max_payload_size - << "})"; // Store settings, in case we need to dynamically switch to the fallback // encoder after a failed Encode call. codec_settings_ = *codec_settings; @@ -336,8 +327,6 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( PrimeEncoder(current_encoder()); return ret; } - RTC_LOG(LS_WARNING) << "[VESFW] Hardware encoder initialization failed with" - << " error code: " << WebRtcVideoCodecErrorToString(ret); // Try to instantiate software codec. if (InitFallbackEncoder(/*is_forced=*/false)) { @@ -346,8 +335,6 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( } // Software encoder failed too, use original return code. - RTC_LOG(LS_WARNING) - << "[VESFW] Software fallback encoder initialization also failed."; encoder_state_ = EncoderState::kUninitialized; return ret; } diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index cb31306a60..4853e68996 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -360,14 +360,8 @@ int SimulcastEncoderAdapter::InitEncode( bool separate_encoders_needed = !encoder_context->encoder().GetEncoderInfo().supports_simulcast || active_streams_count == 1; - RTC_LOG(LS_INFO) << "[SEA] InitEncode: total_streams_count: " - << total_streams_count_ - << ", active_streams_count: " << active_streams_count - << ", separate_encoders_needed: " - << (separate_encoders_needed ? "true" : "false"); // Singlecast or simulcast with simulcast-capable underlaying encoder. if (total_streams_count_ == 1 || !separate_encoders_needed) { - RTC_LOG(LS_INFO) << "[SEA] InitEncode: Single-encoder mode"; int ret = encoder_context->encoder().InitEncode(&codec_, settings); if (ret >= 0) { stream_contexts_.emplace_back( @@ -383,8 +377,7 @@ int SimulcastEncoderAdapter::InitEncode( encoder_context->Release(); if (total_streams_count_ == 1) { - RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: " - << WebRtcVideoCodecErrorToString(ret); + // Failed to initialize singlecast encoder. return ret; } } @@ -412,16 +405,10 @@ int SimulcastEncoderAdapter::InitEncode( /*is_lowest_quality_stream=*/stream_idx == lowest_quality_stream_idx, /*is_highest_quality_stream=*/stream_idx == highest_quality_stream_idx); - RTC_LOG(LS_INFO) << "[SEA] Multi-encoder mode: initializing stream: " - << stream_idx << ", active: " - << (codec_.simulcastStream[stream_idx].active ? "true" - : "false"); int ret = encoder_context->encoder().InitEncode(&stream_codec, settings); if (ret < 0) { encoder_context.reset(); Release(); - RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: " - << WebRtcVideoCodecErrorToString(ret); return ret; } diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 2208b9d967..ce0a9f1e5e 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -286,7 +286,6 @@ rtc_library("video_codec_interface") { "include/video_codec_interface.cc", "include/video_codec_interface.h", "include/video_coding_defines.h", - "include/video_error_codes.cc", "include/video_error_codes.h", "video_coding_defines.cc", ] diff --git a/modules/video_coding/include/video_error_codes.cc b/modules/video_coding/include/video_error_codes.cc deleted file mode 100644 index c806753ea7..0000000000 --- a/modules/video_coding/include/video_error_codes.cc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2024 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 "modules/video_coding/include/video_error_codes.h" - -namespace webrtc { -const char* WebRtcVideoCodecErrorToString(int32_t error_code) { - switch (error_code) { - case WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT: - return "WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT"; - case WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME: - return "WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME"; - case WEBRTC_VIDEO_CODEC_NO_OUTPUT: - return "WEBRTC_VIDEO_CODEC_NO_OUTPUT"; - case WEBRTC_VIDEO_CODEC_ERROR: - return "WEBRTC_VIDEO_CODEC_ERROR"; - case WEBRTC_VIDEO_CODEC_MEMORY: - return "WEBRTC_VIDEO_CODEC_MEMORY"; - case WEBRTC_VIDEO_CODEC_ERR_PARAMETER: - return "WEBRTC_VIDEO_CODEC_ERR_PARAMETER"; - case WEBRTC_VIDEO_CODEC_TIMEOUT: - return "WEBRTC_VIDEO_CODEC_TIMEOUT"; - case WEBRTC_VIDEO_CODEC_UNINITIALIZED: - return "WEBRTC_VIDEO_CODEC_UNINITIALIZED"; - case WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE: - return "WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE"; - case WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED: - return "WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED"; - case WEBRTC_VIDEO_CODEC_ENCODER_FAILURE: - return "WEBRTC_VIDEO_CODEC_ENCODER_FAILURE"; - default: - return "WEBRTC_VIDEO_CODEC_UNKNOWN"; - } -} - -} // namespace webrtc diff --git a/modules/video_coding/include/video_error_codes.h b/modules/video_coding/include/video_error_codes.h index 1634678aeb..17146ce205 100644 --- a/modules/video_coding/include/video_error_codes.h +++ b/modules/video_coding/include/video_error_codes.h @@ -11,7 +11,9 @@ #ifndef MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ #define MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ -#include +// NOTE: in sync with video_coding_module_defines.h + +// Define return values #define WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT 5 #define WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME 4 @@ -26,10 +28,4 @@ #define WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED -15 #define WEBRTC_VIDEO_CODEC_ENCODER_FAILURE -16 -namespace webrtc { - -const char* WebRtcVideoCodecErrorToString(int32_t error_code); - -} // namespace webrtc - #endif // MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index 73cd7826f9..ae55bfda23 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -937,8 +937,6 @@ void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config, void VideoStreamEncoder::ReconfigureEncoder() { // Running on the encoder queue. RTC_DCHECK(pending_encoder_reconfiguration_); - RTC_LOG(LS_INFO) << "[VSE] " << __func__ - << " [encoder_config=" << encoder_config_.ToString() << "]"; bool encoder_reset_required = false; if (pending_encoder_creation_) { @@ -1156,38 +1154,37 @@ void VideoStreamEncoder::ReconfigureEncoder() { char log_stream_buf[4 * 1024]; rtc::SimpleStringBuilder log_stream(log_stream_buf); - log_stream << "ReconfigureEncoder: simulcast streams: "; + log_stream << "ReconfigureEncoder:\n"; + log_stream << "Simulcast streams:\n"; for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) { - log_stream << "{" << i << ": " << codec.simulcastStream[i].width << "x" - << codec.simulcastStream[i].height << " " - << ScalabilityModeToString( - codec.simulcastStream[i].GetScalabilityMode()) - << ", min_kbps: " << codec.simulcastStream[i].minBitrate - << ", target_kbps: " << codec.simulcastStream[i].targetBitrate - << ", max_kbps: " << codec.simulcastStream[i].maxBitrate - << ", max_fps: " << codec.simulcastStream[i].maxFramerate - << ", max_qp: " << codec.simulcastStream[i].qpMax << ", num_tl: " - << codec.simulcastStream[i].numberOfTemporalLayers - << ", active: " - << (codec.simulcastStream[i].active ? "true" : "false") << "}"; + log_stream << i << ": " << codec.simulcastStream[i].width << "x" + << codec.simulcastStream[i].height + << " min_kbps: " << codec.simulcastStream[i].minBitrate + << " target_kbps: " << codec.simulcastStream[i].targetBitrate + << " max_kbps: " << codec.simulcastStream[i].maxBitrate + << " max_fps: " << codec.simulcastStream[i].maxFramerate + << " max_qp: " << codec.simulcastStream[i].qpMax + << " num_tl: " << codec.simulcastStream[i].numberOfTemporalLayers + << " active: " + << (codec.simulcastStream[i].active ? "true" : "false") << "\n"; } if (encoder_config_.codec_type == kVideoCodecVP9 || encoder_config_.codec_type == kVideoCodecAV1) { - log_stream << ", spatial layers: "; + log_stream << "Spatial layers:\n"; for (int i = 0; i < GetNumSpatialLayers(codec); ++i) { - log_stream << "{" << i << ": " << codec.spatialLayers[i].width << "x" + log_stream << i << ": " << codec.spatialLayers[i].width << "x" << codec.spatialLayers[i].height - << ", min_kbps: " << codec.spatialLayers[i].minBitrate - << ", target_kbps: " << codec.spatialLayers[i].targetBitrate - << ", max_kbps: " << codec.spatialLayers[i].maxBitrate - << ", max_fps: " << codec.spatialLayers[i].maxFramerate - << ", max_qp: " << codec.spatialLayers[i].qpMax << ", num_tl: " - << codec.spatialLayers[i].numberOfTemporalLayers - << ", active: " - << (codec.spatialLayers[i].active ? "true" : "false") << "}"; + << " min_kbps: " << codec.spatialLayers[i].minBitrate + << " target_kbps: " << codec.spatialLayers[i].targetBitrate + << " max_kbps: " << codec.spatialLayers[i].maxBitrate + << " max_fps: " << codec.spatialLayers[i].maxFramerate + << " max_qp: " << codec.spatialLayers[i].qpMax + << " num_tl: " << codec.spatialLayers[i].numberOfTemporalLayers + << " active: " + << (codec.spatialLayers[i].active ? "true" : "false") << "\n"; } } - RTC_LOG(LS_INFO) << "[VSE] " << log_stream.str(); + RTC_LOG(LS_INFO) << log_stream.str(); codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000, codec.minBitrate); @@ -1322,7 +1319,7 @@ void VideoStreamEncoder::ReconfigureEncoder() { << " max frame rate " << codec.maxFramerate << " max payload size " << max_data_payload_length_; } else { - RTC_LOG(LS_ERROR) << "[VSE] Failed to configure encoder."; + RTC_LOG(LS_ERROR) << "Failed to configure encoder."; rate_allocator_ = nullptr; } @@ -1920,7 +1917,7 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, stream_resource_manager_.ConfigureQualityScaler(info); stream_resource_manager_.ConfigureBandwidthQualityScaler(info); - RTC_LOG(LS_INFO) << "[VSE] Encoder info changed to " << info.ToString(); + RTC_LOG(LS_INFO) << "Encoder info changed to " << info.ToString(); } if (bitrate_adjuster_) { From 414c94290af044991c7e2d1aadbec9dafb9ee64e Mon Sep 17 00:00:00 2001 From: henrika Date: Wed, 14 Feb 2024 18:08:26 +0100 Subject: [PATCH 140/170] Reland "Extends WebRTC logs for software encoder fallback" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a reland of commit 050ffefd854f8a57071992238723259e9ae0d85a Original change's description: > Extends WebRTC logs for software encoder fallback > > This CL extends logging related to HW->SW fallbacks on the encoder > side in WebRTC. The goal is to make it easier to track down the > different steps taken when setting up the video encoder and why/when > HW encoding fails. > > Current logs are added on several lines which makes regexp searching > difficult. This CL adds all related information on one line instead. > > Three new search tags are also added VSE (VideoStreamEncoder), VESFW > (VideoEncoderSoftwareFallbackWrapper) and SEA (SimulcastEncoderAdapter). The idea is to allow searching for the tags to see correlated logs. > > It has been verified that these added logs also show up in WebRTC > logs in Meet. > > Logs from the GPU process are not included due to the sandboxed > nature which makes it much more complex to add to the native > WebRTC log. I think that these simple logs will provide value as is. > > Example: https://gist.github.com/henrik-and/41946f7f0b10774241bd14d7687f770b > > Bug: b/322132132 > Change-Id: Iec58c9741a9dd6bab3236a88e9a6e45440f5d980 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339260 > Commit-Queue: Henrik Andreassson > Reviewed-by: Ilya Nikolaevskiy > Reviewed-by: Henrik Boström > Cr-Commit-Position: refs/heads/main@{#41733} NOTRY=true Bug: b/322132132 Change-Id: I25dd34b9ba59ea8502e47b4c89cd111430636e08 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339680 Reviewed-by: Mirko Bonadei Commit-Queue: Henrik Andreassson Cr-Commit-Position: refs/heads/main@{#41736} --- api/video_codecs/video_codec.cc | 30 +++++++++++ api/video_codecs/video_codec.h | 4 ++ ...video_encoder_software_fallback_wrapper.cc | 18 ++++++- media/engine/simulcast_encoder_adapter.cc | 16 +++++- modules/video_coding/BUILD.gn | 2 + .../video_coding/include/video_error_codes.h | 4 -- .../include/video_error_codes_utils.cc | 46 ++++++++++++++++ .../include/video_error_codes_utils.h | 22 ++++++++ video/video_stream_encoder.cc | 53 ++++++++++--------- 9 files changed, 163 insertions(+), 32 deletions(-) create mode 100644 modules/video_coding/include/video_error_codes_utils.cc create mode 100644 modules/video_coding/include/video_error_codes_utils.h diff --git a/api/video_codecs/video_codec.cc b/api/video_codecs/video_codec.cc index 39a345d699..82c9bfc8ea 100644 --- a/api/video_codecs/video_codec.cc +++ b/api/video_codecs/video_codec.cc @@ -16,6 +16,7 @@ #include "absl/strings/match.h" #include "rtc_base/checks.h" +#include "rtc_base/strings/string_builder.h" namespace webrtc { namespace { @@ -73,6 +74,35 @@ VideoCodec::VideoCodec() codec_specific_(), complexity_(VideoCodecComplexity::kComplexityNormal) {} +std::string VideoCodec::ToString() const { + char string_buf[2048]; + rtc::SimpleStringBuilder ss(string_buf); + + ss << "VideoCodec {" << "type: " << CodecTypeToPayloadString(codecType) + << ", mode: " + << (mode == VideoCodecMode::kRealtimeVideo ? "RealtimeVideo" + : "Screensharing"); + if (IsSinglecast()) { + absl::optional scalability_mode = GetScalabilityMode(); + if (scalability_mode.has_value()) { + ss << ", Singlecast: {" << width << "x" << height << " " + << ScalabilityModeToString(*scalability_mode) + << (active ? ", active" : ", inactive") << "}"; + } + } else { + ss << ", Simulcast: {"; + for (size_t i = 0; i < numberOfSimulcastStreams; ++i) { + const SimulcastStream stream = simulcastStream[i]; + ss << "[" << stream.width << "x" << stream.height << " " + << ScalabilityModeToString(stream.GetScalabilityMode()) + << (stream.active ? ", active" : ", inactive") << "]"; + } + ss << "}"; + } + ss << "}"; + return ss.str(); +} + VideoCodecVP8* VideoCodec::VP8() { RTC_DCHECK_EQ(codecType, kVideoCodecVP8); return &codec_specific_.VP8; diff --git a/api/video_codecs/video_codec.h b/api/video_codecs/video_codec.h index a596af1528..e48ffd4b5f 100644 --- a/api/video_codecs/video_codec.h +++ b/api/video_codecs/video_codec.h @@ -141,6 +141,9 @@ class RTC_EXPORT VideoCodec { bool GetFrameDropEnabled() const; void SetFrameDropEnabled(bool enabled); + bool IsSinglecast() const { return numberOfSimulcastStreams <= 1; } + bool IsSimulcast() const { return !IsSinglecast(); } + // Public variables. TODO(hta): Make them private with accessors. VideoCodecType codecType; @@ -193,6 +196,7 @@ class RTC_EXPORT VideoCodec { bool operator==(const VideoCodec& other) const = delete; bool operator!=(const VideoCodec& other) const = delete; + std::string ToString() const; // Accessors for codec specific information. // There is a const version of each that returns a reference, diff --git a/api/video_codecs/video_encoder_software_fallback_wrapper.cc b/api/video_codecs/video_encoder_software_fallback_wrapper.cc index d35c9f9950..e50b5086e8 100644 --- a/api/video_codecs/video_encoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_encoder_software_fallback_wrapper.cc @@ -28,6 +28,7 @@ #include "api/video_codecs/video_encoder.h" #include "media/base/video_common.h" #include "modules/video_coding/include/video_error_codes.h" +#include "modules/video_coding/include/video_error_codes_utils.h" #include "modules/video_coding/utility/simulcast_utility.h" #include "rtc_base/checks.h" #include "rtc_base/experiments/field_trial_parser.h" @@ -264,14 +265,17 @@ void VideoEncoderSoftwareFallbackWrapper::PrimeEncoder( } bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder(bool is_forced) { - RTC_LOG(LS_WARNING) << "Encoder falling back to software encoding."; + RTC_LOG(LS_WARNING) << "[VESFW] " << __func__ + << "(is_forced=" << (is_forced ? "true" : "false") << ")"; RTC_DCHECK(encoder_settings_.has_value()); const int ret = fallback_encoder_->InitEncode(&codec_settings_, encoder_settings_.value()); if (ret != WEBRTC_VIDEO_CODEC_OK) { - RTC_LOG(LS_ERROR) << "Failed to initialize software-encoder fallback."; + RTC_LOG(LS_ERROR) + << "[VESFW] software-encoder fallback initialization failed with" + << " error code: " << WebRtcVideoCodecErrorToString(ret); fallback_encoder_->Release(); return false; } @@ -305,6 +309,12 @@ void VideoEncoderSoftwareFallbackWrapper::SetFecControllerOverride( int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( const VideoCodec* codec_settings, const VideoEncoder::Settings& settings) { + RTC_LOG(LS_INFO) << "[VESFW] " << __func__ + << "(codec=" << codec_settings->ToString() + << ", settings={number_of_cores: " + << settings.number_of_cores + << ", max_payload_size: " << settings.max_payload_size + << "})"; // Store settings, in case we need to dynamically switch to the fallback // encoder after a failed Encode call. codec_settings_ = *codec_settings; @@ -327,6 +337,8 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( PrimeEncoder(current_encoder()); return ret; } + RTC_LOG(LS_WARNING) << "[VESFW] Hardware encoder initialization failed with" + << " error code: " << WebRtcVideoCodecErrorToString(ret); // Try to instantiate software codec. if (InitFallbackEncoder(/*is_forced=*/false)) { @@ -335,6 +347,8 @@ int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode( } // Software encoder failed too, use original return code. + RTC_LOG(LS_WARNING) + << "[VESFW] Software fallback encoder initialization also failed."; encoder_state_ = EncoderState::kUninitialized; return ret; } diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index 4853e68996..642fe31e90 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -32,6 +32,7 @@ #include "media/base/media_constants.h" #include "media/base/video_common.h" #include "modules/video_coding/include/video_error_codes.h" +#include "modules/video_coding/include/video_error_codes_utils.h" #include "modules/video_coding/utility/simulcast_rate_allocator.h" #include "rtc_base/checks.h" #include "rtc_base/experiments/rate_control_settings.h" @@ -360,8 +361,14 @@ int SimulcastEncoderAdapter::InitEncode( bool separate_encoders_needed = !encoder_context->encoder().GetEncoderInfo().supports_simulcast || active_streams_count == 1; + RTC_LOG(LS_INFO) << "[SEA] InitEncode: total_streams_count: " + << total_streams_count_ + << ", active_streams_count: " << active_streams_count + << ", separate_encoders_needed: " + << (separate_encoders_needed ? "true" : "false"); // Singlecast or simulcast with simulcast-capable underlaying encoder. if (total_streams_count_ == 1 || !separate_encoders_needed) { + RTC_LOG(LS_INFO) << "[SEA] InitEncode: Single-encoder mode"; int ret = encoder_context->encoder().InitEncode(&codec_, settings); if (ret >= 0) { stream_contexts_.emplace_back( @@ -377,7 +384,8 @@ int SimulcastEncoderAdapter::InitEncode( encoder_context->Release(); if (total_streams_count_ == 1) { - // Failed to initialize singlecast encoder. + RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: " + << WebRtcVideoCodecErrorToString(ret); return ret; } } @@ -405,10 +413,16 @@ int SimulcastEncoderAdapter::InitEncode( /*is_lowest_quality_stream=*/stream_idx == lowest_quality_stream_idx, /*is_highest_quality_stream=*/stream_idx == highest_quality_stream_idx); + RTC_LOG(LS_INFO) << "[SEA] Multi-encoder mode: initializing stream: " + << stream_idx << ", active: " + << (codec_.simulcastStream[stream_idx].active ? "true" + : "false"); int ret = encoder_context->encoder().InitEncode(&stream_codec, settings); if (ret < 0) { encoder_context.reset(); Release(); + RTC_LOG(LS_ERROR) << "[SEA] InitEncode: failed with error code: " + << WebRtcVideoCodecErrorToString(ret); return ret; } diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index ce0a9f1e5e..31de2956f3 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -287,6 +287,8 @@ rtc_library("video_codec_interface") { "include/video_codec_interface.h", "include/video_coding_defines.h", "include/video_error_codes.h", + "include/video_error_codes_utils.cc", + "include/video_error_codes_utils.h", "video_coding_defines.cc", ] deps = [ diff --git a/modules/video_coding/include/video_error_codes.h b/modules/video_coding/include/video_error_codes.h index 17146ce205..d7d54f3989 100644 --- a/modules/video_coding/include/video_error_codes.h +++ b/modules/video_coding/include/video_error_codes.h @@ -11,10 +11,6 @@ #ifndef MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ #define MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_H_ -// NOTE: in sync with video_coding_module_defines.h - -// Define return values - #define WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT 5 #define WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME 4 #define WEBRTC_VIDEO_CODEC_NO_OUTPUT 1 diff --git a/modules/video_coding/include/video_error_codes_utils.cc b/modules/video_coding/include/video_error_codes_utils.cc new file mode 100644 index 0000000000..7e2c08d518 --- /dev/null +++ b/modules/video_coding/include/video_error_codes_utils.cc @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 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 "modules/video_coding/include/video_error_codes_utils.h" + +#include "modules/video_coding/include/video_error_codes.h" + +namespace webrtc { + +const char* WebRtcVideoCodecErrorToString(int32_t error_code) { + switch (error_code) { + case WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT: + return "WEBRTC_VIDEO_CODEC_TARGET_BITRATE_OVERSHOOT"; + case WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME: + return "WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME"; + case WEBRTC_VIDEO_CODEC_NO_OUTPUT: + return "WEBRTC_VIDEO_CODEC_NO_OUTPUT"; + case WEBRTC_VIDEO_CODEC_ERROR: + return "WEBRTC_VIDEO_CODEC_ERROR"; + case WEBRTC_VIDEO_CODEC_MEMORY: + return "WEBRTC_VIDEO_CODEC_MEMORY"; + case WEBRTC_VIDEO_CODEC_ERR_PARAMETER: + return "WEBRTC_VIDEO_CODEC_ERR_PARAMETER"; + case WEBRTC_VIDEO_CODEC_TIMEOUT: + return "WEBRTC_VIDEO_CODEC_TIMEOUT"; + case WEBRTC_VIDEO_CODEC_UNINITIALIZED: + return "WEBRTC_VIDEO_CODEC_UNINITIALIZED"; + case WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE: + return "WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE"; + case WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED: + return "WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED"; + case WEBRTC_VIDEO_CODEC_ENCODER_FAILURE: + return "WEBRTC_VIDEO_CODEC_ENCODER_FAILURE"; + default: + return "WEBRTC_VIDEO_CODEC_UNKNOWN"; + } +} + +} // namespace webrtc diff --git a/modules/video_coding/include/video_error_codes_utils.h b/modules/video_coding/include/video_error_codes_utils.h new file mode 100644 index 0000000000..ae17e29636 --- /dev/null +++ b/modules/video_coding/include/video_error_codes_utils.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 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 MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_UTILS_H_ +#define MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_UTILS_H_ + +#include + +namespace webrtc { + +const char* WebRtcVideoCodecErrorToString(int32_t error_code); + +} // namespace webrtc + +#endif // MODULES_VIDEO_CODING_INCLUDE_VIDEO_ERROR_CODES_UTILS_H_ diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc index ae55bfda23..73cd7826f9 100644 --- a/video/video_stream_encoder.cc +++ b/video/video_stream_encoder.cc @@ -937,6 +937,8 @@ void VideoStreamEncoder::ConfigureEncoder(VideoEncoderConfig config, void VideoStreamEncoder::ReconfigureEncoder() { // Running on the encoder queue. RTC_DCHECK(pending_encoder_reconfiguration_); + RTC_LOG(LS_INFO) << "[VSE] " << __func__ + << " [encoder_config=" << encoder_config_.ToString() << "]"; bool encoder_reset_required = false; if (pending_encoder_creation_) { @@ -1154,37 +1156,38 @@ void VideoStreamEncoder::ReconfigureEncoder() { char log_stream_buf[4 * 1024]; rtc::SimpleStringBuilder log_stream(log_stream_buf); - log_stream << "ReconfigureEncoder:\n"; - log_stream << "Simulcast streams:\n"; + log_stream << "ReconfigureEncoder: simulcast streams: "; for (size_t i = 0; i < codec.numberOfSimulcastStreams; ++i) { - log_stream << i << ": " << codec.simulcastStream[i].width << "x" - << codec.simulcastStream[i].height - << " min_kbps: " << codec.simulcastStream[i].minBitrate - << " target_kbps: " << codec.simulcastStream[i].targetBitrate - << " max_kbps: " << codec.simulcastStream[i].maxBitrate - << " max_fps: " << codec.simulcastStream[i].maxFramerate - << " max_qp: " << codec.simulcastStream[i].qpMax - << " num_tl: " << codec.simulcastStream[i].numberOfTemporalLayers - << " active: " - << (codec.simulcastStream[i].active ? "true" : "false") << "\n"; + log_stream << "{" << i << ": " << codec.simulcastStream[i].width << "x" + << codec.simulcastStream[i].height << " " + << ScalabilityModeToString( + codec.simulcastStream[i].GetScalabilityMode()) + << ", min_kbps: " << codec.simulcastStream[i].minBitrate + << ", target_kbps: " << codec.simulcastStream[i].targetBitrate + << ", max_kbps: " << codec.simulcastStream[i].maxBitrate + << ", max_fps: " << codec.simulcastStream[i].maxFramerate + << ", max_qp: " << codec.simulcastStream[i].qpMax << ", num_tl: " + << codec.simulcastStream[i].numberOfTemporalLayers + << ", active: " + << (codec.simulcastStream[i].active ? "true" : "false") << "}"; } if (encoder_config_.codec_type == kVideoCodecVP9 || encoder_config_.codec_type == kVideoCodecAV1) { - log_stream << "Spatial layers:\n"; + log_stream << ", spatial layers: "; for (int i = 0; i < GetNumSpatialLayers(codec); ++i) { - log_stream << i << ": " << codec.spatialLayers[i].width << "x" + log_stream << "{" << i << ": " << codec.spatialLayers[i].width << "x" << codec.spatialLayers[i].height - << " min_kbps: " << codec.spatialLayers[i].minBitrate - << " target_kbps: " << codec.spatialLayers[i].targetBitrate - << " max_kbps: " << codec.spatialLayers[i].maxBitrate - << " max_fps: " << codec.spatialLayers[i].maxFramerate - << " max_qp: " << codec.spatialLayers[i].qpMax - << " num_tl: " << codec.spatialLayers[i].numberOfTemporalLayers - << " active: " - << (codec.spatialLayers[i].active ? "true" : "false") << "\n"; + << ", min_kbps: " << codec.spatialLayers[i].minBitrate + << ", target_kbps: " << codec.spatialLayers[i].targetBitrate + << ", max_kbps: " << codec.spatialLayers[i].maxBitrate + << ", max_fps: " << codec.spatialLayers[i].maxFramerate + << ", max_qp: " << codec.spatialLayers[i].qpMax << ", num_tl: " + << codec.spatialLayers[i].numberOfTemporalLayers + << ", active: " + << (codec.spatialLayers[i].active ? "true" : "false") << "}"; } } - RTC_LOG(LS_INFO) << log_stream.str(); + RTC_LOG(LS_INFO) << "[VSE] " << log_stream.str(); codec.startBitrate = std::max(encoder_target_bitrate_bps_.value_or(0) / 1000, codec.minBitrate); @@ -1319,7 +1322,7 @@ void VideoStreamEncoder::ReconfigureEncoder() { << " max frame rate " << codec.maxFramerate << " max payload size " << max_data_payload_length_; } else { - RTC_LOG(LS_ERROR) << "Failed to configure encoder."; + RTC_LOG(LS_ERROR) << "[VSE] Failed to configure encoder."; rate_allocator_ = nullptr; } @@ -1917,7 +1920,7 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame, stream_resource_manager_.ConfigureQualityScaler(info); stream_resource_manager_.ConfigureBandwidthQualityScaler(info); - RTC_LOG(LS_INFO) << "Encoder info changed to " << info.ToString(); + RTC_LOG(LS_INFO) << "[VSE] Encoder info changed to " << info.ToString(); } if (bitrate_adjuster_) { From 3e9e4e7c9ce4d0cfe51d393c52a24c023474e761 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Wed, 14 Feb 2024 20:07:10 -0800 Subject: [PATCH 141/170] Update WebRTC code version (2024-02-15T04:07:08). Bug: None Change-Id: I0ee54527ed5e6d8c40249c0a7c0fed159a60287c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339720 Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41737} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index a536a4203a..c61463d3e8 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-14T04:12:34"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-15T04:07:08"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 4efc830e53da5b83eb1f06ac6eac0a0d8a8664a4 Mon Sep 17 00:00:00 2001 From: Dor Hen Date: Wed, 14 Feb 2024 10:07:56 +0200 Subject: [PATCH 142/170] Provide test output path with `OutputPathWithRandomDirectory` 1/n First commit in a series of commits to wire up the test output path utility that adds a random directory in the path, for problematic tests that run in concurrent execution environments. Bug: webrtc:15833 Change-Id: I5e5b3940007be773d77dbbfc953efa810e4e3ea9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339522 Reviewed-by: Artem Titov Commit-Queue: Mirko Bonadei Reviewed-by: Harald Alvestrand Reviewed-by: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41738} --- api/rtc_event_log_output_file_unittest.cc | 3 ++- common_audio/BUILD.gn | 1 - common_audio/wav_file_unittest.cc | 9 ++++---- modules/audio_device/BUILD.gn | 1 - .../include/test_audio_device_unittest.cc | 21 +++++++++---------- rtc_base/system/file_wrapper_unittest.cc | 3 ++- test/testsupport/file_utils.cc | 9 ++++++-- test/testsupport/file_utils_unittest.cc | 17 +++++++++++---- test/testsupport/test_artifacts.cc | 9 +++++--- 9 files changed, 45 insertions(+), 28 deletions(-) diff --git a/api/rtc_event_log_output_file_unittest.cc b/api/rtc_event_log_output_file_unittest.cc index 0aff57fbbc..d2f1e1c6b5 100644 --- a/api/rtc_event_log_output_file_unittest.cc +++ b/api/rtc_event_log_output_file_unittest.cc @@ -34,7 +34,8 @@ class RtcEventLogOutputFileTest : public ::testing::Test { protected: std::string GetOutputFilePath() const { auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - return test::OutputPath() + test_info->test_case_name() + test_info->name(); + return test::OutputPathWithRandomDirectory() + test_info->test_case_name() + + test_info->name(); } std::string GetOutputFileContents() const { diff --git a/common_audio/BUILD.gn b/common_audio/BUILD.gn index 620d01e6d5..2ae6d32710 100644 --- a/common_audio/BUILD.gn +++ b/common_audio/BUILD.gn @@ -375,7 +375,6 @@ if (rtc_include_tests && !build_with_chromium) { "../rtc_base:checks", "../rtc_base:macromagic", "../rtc_base:rtc_base_tests_utils", - "../rtc_base:ssl", "../rtc_base:stringutils", "../rtc_base:timeutils", "../rtc_base/system:arch", diff --git a/common_audio/wav_file_unittest.cc b/common_audio/wav_file_unittest.cc index 6a0cfdc680..71e4fedf94 100644 --- a/common_audio/wav_file_unittest.cc +++ b/common_audio/wav_file_unittest.cc @@ -17,7 +17,6 @@ #include #include "common_audio/wav_header.h" -#include "rtc_base/helpers.h" #include "test/gtest.h" #include "test/testsupport/file_utils.h" @@ -37,7 +36,7 @@ static const float kSamples[] = {0.0, 10.0, 4e4, -1e9}; // Write a tiny WAV file with the C++ interface and verify the result. TEST(WavWriterTest, MAYBE_CPP) { const std::string outfile = - test::OutputPath() + "wavtest1-" + rtc::CreateRandomUuid() + ".wav"; + test::OutputPathWithRandomDirectory() + "wavtest1.wav"; static const size_t kNumSamples = 3; { WavWriter w(outfile, 14099, 1); @@ -114,7 +113,8 @@ TEST(WavWriterTest, LargeFile) { {WavFile::SampleFormat::kInt16, WavFile::SampleFormat::kFloat}) { for (WavFile::SampleFormat read_format : {WavFile::SampleFormat::kInt16, WavFile::SampleFormat::kFloat}) { - std::string outfile = test::OutputPath() + "wavtest3.wav"; + std::string outfile = + test::OutputPathWithRandomDirectory() + "wavtest3.wav"; float samples[kNumSamples]; for (size_t i = 0; i < kNumSamples; i += kNumChannels) { // A nice periodic beeping sound. @@ -179,7 +179,8 @@ TEST(WavWriterTest, LargeFile) { // Write a tiny WAV file with the C++ interface then read-reset-read. TEST(WavReaderTest, MAYBE_CPPReset) { - const std::string outfile = test::OutputPath() + "wavtest4.wav"; + const std::string outfile = + test::OutputPathWithRandomDirectory() + "wavtest4.wav"; static const size_t kNumSamples = 3; { WavWriter w(outfile, 14099, 1); diff --git a/modules/audio_device/BUILD.gn b/modules/audio_device/BUILD.gn index baba0a36d9..2088e74dcd 100644 --- a/modules/audio_device/BUILD.gn +++ b/modules/audio_device/BUILD.gn @@ -488,7 +488,6 @@ if (rtc_include_tests && !build_with_chromium) { "../../rtc_base:race_checker", "../../rtc_base:rtc_event", "../../rtc_base:safe_conversions", - "../../rtc_base:ssl", "../../rtc_base:timeutils", "../../rtc_base/synchronization:mutex", "../../system_wrappers", diff --git a/modules/audio_device/include/test_audio_device_unittest.cc b/modules/audio_device/include/test_audio_device_unittest.cc index d79697bb52..cca82977e8 100644 --- a/modules/audio_device/include/test_audio_device_unittest.cc +++ b/modules/audio_device/include/test_audio_device_unittest.cc @@ -24,7 +24,6 @@ #include "common_audio/wav_header.h" #include "modules/audio_device/include/audio_device_defines.h" #include "rtc_base/checks.h" -#include "rtc_base/helpers.h" #include "rtc_base/logging.h" #include "rtc_base/synchronization/mutex.h" #include "test/gmock.h" @@ -40,9 +39,9 @@ void RunWavTest(const std::vector& input_samples, const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - const std::string output_filename = - test::OutputPath() + "BoundedWavFileWriterTest_" + test_info->name() + - "_" + rtc::CreateRandomUuid() + ".wav"; + const std::string output_filename = test::OutputPathWithRandomDirectory() + + "BoundedWavFileWriterTest_" + + test_info->name() + ".wav"; static const size_t kSamplesPerFrame = 8; static const int kSampleRate = kSamplesPerFrame * 100; @@ -137,9 +136,9 @@ TEST(WavFileReaderTest, RepeatedTrueWithSingleFrameFileReadTwice) { static const rtc::BufferT kExpectedSamples(kInputSamples.data(), kInputSamples.size()); - const std::string output_filename = test::OutputPath() + + const std::string output_filename = test::OutputPathWithRandomDirectory() + "WavFileReaderTest_RepeatedTrue_" + - std::to_string(std::rand()) + ".wav"; + ".wav"; static const size_t kSamplesPerFrame = 8; static const int kSampleRate = kSamplesPerFrame * 100; @@ -176,9 +175,9 @@ void RunRawTestNoRepeat(const std::vector& input_samples, const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - const std::string output_filename = test::OutputPath() + "RawFileTest_" + - test_info->name() + "_" + - std::to_string(std::rand()) + ".raw"; + const std::string output_filename = test::OutputPathWithRandomDirectory() + + "RawFileTest_" + test_info->name() + + ".raw"; static const size_t kSamplesPerFrame = 8; static const int kSampleRate = kSamplesPerFrame * 100; @@ -282,8 +281,8 @@ TEST(RawFileWriterTest, Repeat) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); - const std::string output_filename = test::OutputPath() + "RawFileTest_" + - test_info->name() + "_" + + const std::string output_filename = test::OutputPathWithRandomDirectory() + + "RawFileTest_" + test_info->name() + "_" + std::to_string(std::rand()) + ".raw"; static const size_t kSamplesPerFrame = 8; diff --git a/rtc_base/system/file_wrapper_unittest.cc b/rtc_base/system/file_wrapper_unittest.cc index 980b565c73..b83c1df933 100644 --- a/rtc_base/system/file_wrapper_unittest.cc +++ b/rtc_base/system/file_wrapper_unittest.cc @@ -21,7 +21,8 @@ TEST(FileWrapper, FileSize) { std::string test_name = std::string(test_info->test_case_name()) + "_" + test_info->name(); std::replace(test_name.begin(), test_name.end(), '/', '_'); - const std::string temp_filename = test::OutputPath() + test_name; + const std::string temp_filename = + test::OutputPathWithRandomDirectory() + test_name; // Write { diff --git a/test/testsupport/file_utils.cc b/test/testsupport/file_utils.cc index 58ee16282e..afabbaad3f 100644 --- a/test/testsupport/file_utils.cc +++ b/test/testsupport/file_utils.cc @@ -36,7 +36,7 @@ #include // To check for directory existence. #ifndef S_ISDIR // Not defined in stat.h on Windows. -#define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #endif #include @@ -237,7 +237,12 @@ std::string ResourcePath(absl::string_view name, absl::string_view extension) { std::string JoinFilename(absl::string_view dir, absl::string_view name) { RTC_CHECK(!dir.empty()) << "Special cases not implemented."; rtc::StringBuilder os; - os << dir << kPathDelimiter << name; + os << dir; + // If the directory path already ends with a path delimiter don't append it + if (dir.back() != kPathDelimiter.back()) { + os << kPathDelimiter; + } + os << name; return os.Release(); } diff --git a/test/testsupport/file_utils_unittest.cc b/test/testsupport/file_utils_unittest.cc index 8f91d6db7c..1101a63352 100644 --- a/test/testsupport/file_utils_unittest.cc +++ b/test/testsupport/file_utils_unittest.cc @@ -170,8 +170,8 @@ TEST_F(FileUtilsTest, GenerateTempFilename) { #define MAYBE_CreateDir CreateDir #endif TEST_F(FileUtilsTest, MAYBE_CreateDir) { - std::string directory = test::OutputPath() + "fileutils-unittest-empty-dir" + - rtc::CreateRandomUuid(); + std::string directory = + test::OutputPathWithRandomDirectory() + "fileutils-unittest-empty-dir"; // Make sure it's removed if a previous test has failed: remove(directory.c_str()); ASSERT_TRUE(webrtc::test::CreateDir(directory)); @@ -255,8 +255,7 @@ TEST_F(FileUtilsTest, WriteReadDeleteFilesAndDirs) { // Create an empty temporary directory for this test. const std::string temp_directory = - OutputPath() + - Path("TempFileUtilsTestReadDirectory" + rtc::CreateRandomUuid() + "/"); + OutputPathWithRandomDirectory() + Path("TempFileUtilsTestReadDirectory/"); CreateDir(temp_directory); EXPECT_NO_FATAL_FAILURE(CleanDir(temp_directory, &num_deleted_entries)); EXPECT_TRUE(DirExists(temp_directory)); @@ -298,5 +297,15 @@ TEST_F(FileUtilsTest, DirNameStopsAtRoot) { EXPECT_EQ(Path("/"), DirName(Path("/"))); } +TEST_F(FileUtilsTest, JoinFilenameDoesNotAppendExtraPathDelimiterIfExists) { + EXPECT_EQ(JoinFilename(Path("/some/path/"), "file.txt"), + Path("/some/path/file.txt")); +} + +TEST_F(FileUtilsTest, JoinFilenameAppendsPathDelimiterIfMissing) { + EXPECT_EQ(JoinFilename(Path("/some/path"), "file.txt"), + Path("/some/path/file.txt")); +} + } // namespace test } // namespace webrtc diff --git a/test/testsupport/test_artifacts.cc b/test/testsupport/test_artifacts.cc index 6f062e5fe4..b0ab046e63 100644 --- a/test/testsupport/test_artifacts.cc +++ b/test/testsupport/test_artifacts.cc @@ -20,7 +20,7 @@ namespace { const std::string& DefaultArtifactPath() { - static const std::string path = webrtc::test::OutputPath(); + static const std::string path = webrtc::test::OutputPathWithRandomDirectory(); return path; } } // namespace @@ -55,8 +55,11 @@ bool WriteToTestArtifactsDir(const char* filename, return false; } - FileWrapper output = FileWrapper::OpenWriteOnly( - JoinFilename(absl::GetFlag(FLAGS_test_artifacts_dir), filename)); + std::string full_path = + JoinFilename(absl::GetFlag(FLAGS_test_artifacts_dir), filename); + FileWrapper output = FileWrapper::OpenWriteOnly(full_path); + + RTC_LOG(LS_INFO) << "Writing test artifacts in: " << full_path; return output.is_open() && output.Write(buffer, length); } From a2655449ee310704ee2053fd6d43a5ab7002b755 Mon Sep 17 00:00:00 2001 From: Jianjun Zhu Date: Thu, 8 Feb 2024 16:59:18 +0800 Subject: [PATCH 143/170] Add HEVC support for h264_packet_buffer. Renamed to h26x_packet_buffer as it also supports HEVC now. For HEVC, start code is added by depacktizer, and remote endpoint must send sequence and picture information in-band. Co-authored-by: Qiujiao Wu Bug: webrtc:13485 Change-Id: I321cb223357d8d15da95cec80ec0c3a43c26734e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333863 Reviewed-by: Philip Eliasson Commit-Queue: Philip Eliasson Cr-Commit-Position: refs/heads/main@{#41739} --- modules/video_coding/BUILD.gn | 10 +- .../h264_packet_buffer_unittest.cc | 778 ------------ ...packet_buffer.cc => h26x_packet_buffer.cc} | 122 +- ...4_packet_buffer.h => h26x_packet_buffer.h} | 19 +- .../h26x_packet_buffer_unittest.cc | 1056 +++++++++++++++++ 5 files changed, 1157 insertions(+), 828 deletions(-) delete mode 100644 modules/video_coding/h264_packet_buffer_unittest.cc rename modules/video_coding/{h264_packet_buffer.cc => h26x_packet_buffer.cc} (68%) rename modules/video_coding/{h264_packet_buffer.h => h26x_packet_buffer.h} (73%) create mode 100644 modules/video_coding/h26x_packet_buffer_unittest.cc diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 31de2956f3..6e62b9ace3 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -124,10 +124,10 @@ rtc_library("packet_buffer") { ] } -rtc_library("h264_packet_buffer") { +rtc_library("h26x_packet_buffer") { sources = [ - "h264_packet_buffer.cc", - "h264_packet_buffer.h", + "h26x_packet_buffer.cc", + "h26x_packet_buffer.h", ] deps = [ ":codec_globals_headers", @@ -1164,9 +1164,9 @@ if (rtc_include_tests) { "frame_dependencies_calculator_unittest.cc", "frame_helpers_unittest.cc", "generic_decoder_unittest.cc", - "h264_packet_buffer_unittest.cc", "h264_sprop_parameter_sets_unittest.cc", "h264_sps_pps_tracker_unittest.cc", + "h26x_packet_buffer_unittest.cc", "histogram_unittest.cc", "loss_notification_controller_unittest.cc", "nack_requester_unittest.cc", @@ -1201,7 +1201,7 @@ if (rtc_include_tests) { ":encoded_frame", ":frame_dependencies_calculator", ":frame_helpers", - ":h264_packet_buffer", + ":h26x_packet_buffer", ":nack_requester", ":packet_buffer", ":simulcast_test_fixture_impl", diff --git a/modules/video_coding/h264_packet_buffer_unittest.cc b/modules/video_coding/h264_packet_buffer_unittest.cc deleted file mode 100644 index 4f2331da28..0000000000 --- a/modules/video_coding/h264_packet_buffer_unittest.cc +++ /dev/null @@ -1,778 +0,0 @@ -/* - * Copyright (c) 2021 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 "modules/video_coding/h264_packet_buffer.h" - -#include -#include -#include -#include -#include - -#include "api/array_view.h" -#include "api/video/render_resolution.h" -#include "common_video/h264/h264_common.h" -#include "rtc_base/system/unused.h" -#include "test/gmock.h" -#include "test/gtest.h" - -namespace webrtc { -namespace { - -using ::testing::ElementsAreArray; -using ::testing::Eq; -using ::testing::IsEmpty; -using ::testing::SizeIs; - -using H264::NaluType::kAud; -using H264::NaluType::kFuA; -using H264::NaluType::kIdr; -using H264::NaluType::kPps; -using H264::NaluType::kSlice; -using H264::NaluType::kSps; -using H264::NaluType::kStapA; - -constexpr int kBufferSize = 2048; - -std::vector StartCode() { - return {0, 0, 0, 1}; -} - -NaluInfo MakeNaluInfo(uint8_t type) { - NaluInfo res; - res.type = type; - res.sps_id = -1; - res.pps_id = -1; - return res; -} - -class Packet { - public: - explicit Packet(H264PacketizationTypes type); - - Packet& Idr(std::vector payload = {9, 9, 9}); - Packet& Slice(std::vector payload = {9, 9, 9}); - Packet& Sps(std::vector payload = {9, 9, 9}); - Packet& SpsWithResolution(RenderResolution resolution, - std::vector payload = {9, 9, 9}); - Packet& Pps(std::vector payload = {9, 9, 9}); - Packet& Aud(); - Packet& Marker(); - Packet& AsFirstFragment(); - Packet& Time(uint32_t rtp_timestamp); - Packet& SeqNum(uint16_t rtp_seq_num); - - std::unique_ptr Build(); - - private: - rtc::CopyOnWriteBuffer BuildFuaPayload() const; - rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const; - rtc::CopyOnWriteBuffer BuildStapAPayload() const; - - RTPVideoHeaderH264& H264Header() { - return absl::get(video_header_.video_type_header); - } - const RTPVideoHeaderH264& H264Header() const { - return absl::get(video_header_.video_type_header); - } - - H264PacketizationTypes type_; - RTPVideoHeader video_header_; - bool first_fragment_ = false; - bool marker_bit_ = false; - uint32_t rtp_timestamp_ = 0; - uint16_t rtp_seq_num_ = 0; - std::vector> nalu_payloads_; -}; - -Packet::Packet(H264PacketizationTypes type) : type_(type) { - video_header_.video_type_header.emplace(); -} - -Packet& Packet::Idr(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kIdr); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Slice(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSlice); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Sps(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::SpsWithResolution(RenderResolution resolution, - std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); - video_header_.width = resolution.Width(); - video_header_.height = resolution.Height(); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Pps(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kPps); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Aud() { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kAud); - nalu_payloads_.push_back({}); - return *this; -} - -Packet& Packet::Marker() { - marker_bit_ = true; - return *this; -} - -Packet& Packet::AsFirstFragment() { - first_fragment_ = true; - return *this; -} - -Packet& Packet::Time(uint32_t rtp_timestamp) { - rtp_timestamp_ = rtp_timestamp; - return *this; -} - -Packet& Packet::SeqNum(uint16_t rtp_seq_num) { - rtp_seq_num_ = rtp_seq_num; - return *this; -} - -std::unique_ptr Packet::Build() { - auto res = std::make_unique(); - - auto& h264_header = H264Header(); - switch (type_) { - case kH264FuA: { - RTC_CHECK_EQ(h264_header.nalus_length, 1); - res->video_payload = BuildFuaPayload(); - break; - } - case kH264SingleNalu: { - RTC_CHECK_EQ(h264_header.nalus_length, 1); - res->video_payload = BuildSingleNaluPayload(); - break; - } - case kH264StapA: { - RTC_CHECK_GT(h264_header.nalus_length, 1); - RTC_CHECK_LE(h264_header.nalus_length, kMaxNalusPerPacket); - res->video_payload = BuildStapAPayload(); - break; - } - } - - if (type_ == kH264FuA && !first_fragment_) { - h264_header.nalus_length = 0; - } - - h264_header.packetization_type = type_; - res->marker_bit = marker_bit_; - res->video_header = video_header_; - res->timestamp = rtp_timestamp_; - res->seq_num = rtp_seq_num_; - res->video_header.codec = kVideoCodecH264; - - return res; -} - -rtc::CopyOnWriteBuffer Packet::BuildFuaPayload() const { - return rtc::CopyOnWriteBuffer(nalu_payloads_[0]); -} - -rtc::CopyOnWriteBuffer Packet::BuildSingleNaluPayload() const { - rtc::CopyOnWriteBuffer res; - auto& h264_header = H264Header(); - res.AppendData(&h264_header.nalus[0].type, 1); - res.AppendData(nalu_payloads_[0]); - return res; -} - -rtc::CopyOnWriteBuffer Packet::BuildStapAPayload() const { - rtc::CopyOnWriteBuffer res; - - const uint8_t indicator = H264::NaluType::kStapA; - res.AppendData(&indicator, 1); - - auto& h264_header = H264Header(); - for (size_t i = 0; i < h264_header.nalus_length; ++i) { - // The two first bytes indicates the nalu segment size. - uint8_t length_as_array[2] = { - 0, static_cast(nalu_payloads_[i].size() + 1)}; - res.AppendData(length_as_array); - - res.AppendData(&h264_header.nalus[i].type, 1); - res.AppendData(nalu_payloads_[i]); - } - return res; -} - -rtc::ArrayView PacketPayload( - const std::unique_ptr& packet) { - return packet->video_payload; -} - -std::vector FlatVector( - const std::vector>& elems) { - std::vector res; - for (const auto& elem : elems) { - res.insert(res.end(), elem.begin(), elem.end()); - } - return res; -} - -TEST(H264PacketBufferTest, IdrIsKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true); - - EXPECT_THAT( - packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, IdrIsNotKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true); - - // Not marked as the first fragment - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - IsEmpty()); - - // Marked as first fragment - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Idr() - .SeqNum(2) - .Time(1) - .AsFirstFragment() - .Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build()) - .packets, - SizeIs(2)); -} - -TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(2).Time(0).Marker().Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeStapA) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeStapA) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264StapA).Pps().Idr().SeqNum(0).Time(0).Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeStapA) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264StapA).Sps().Idr().SeqNum(2).Time(2).Marker().Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(3) - .Time(3) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build())); - - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build()) - .packets, - SizeIs(2)); -} - -TEST(H264PacketBufferTest, InsertingMidFuaCompletesFrame) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(1).Time(1).AsFirstFragment().Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, SeqNumJumpDoesNotCompleteFrame) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build()) - .packets, - IsEmpty()); - - // Add `kBufferSize` to make the index of the sequence number wrap and end up - // where the packet with sequence number 2 would have ended up. - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(2 + kBufferSize) - .Time(3) - .Marker() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264SingleNalu) - .Slice() - .SeqNum(1) - .Time(1) - .Marker() - .Build()) - .packets, - IsEmpty()); - - // New keyframe, preceedes packet with sequence number 1 in the buffer. - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, OldPacketsDontBlockNewPackets) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 1) - .Time(kBufferSize + 1) - .AsFirstFragment() - .Build())); - - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 3) - .Time(kBufferSize + 1) - .Marker() - .Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 2) - .Time(kBufferSize + 1) - .Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, OldPacketDoesntCompleteFrame) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 3) - .Time(kBufferSize + 1) - .Marker() - .Build()) - .packets, - IsEmpty()); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 1) - .Time(kBufferSize + 1) - .AsFirstFragment() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, FrameBoundariesAreSet) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - auto key = packet_buffer.InsertPacket( - Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build()); - - ASSERT_THAT(key.packets, SizeIs(1)); - EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame); - EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build())); - auto delta = packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build()); - - ASSERT_THAT(delta.packets, SizeIs(3)); - EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame); - EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame); - - EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame); - EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame); - - EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame); - EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame); -} - -TEST(H264PacketBufferTest, ResolutionSetOnFirstPacket) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); - auto res = packet_buffer.InsertPacket(Packet(kH264StapA) - .SpsWithResolution({320, 240}) - .Pps() - .Idr() - .SeqNum(2) - .Time(1) - .Marker() - .Build()); - - ASSERT_THAT(res.packets, SizeIs(2)); - EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); - EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); -} - -TEST(H264PacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); - auto key = packet_buffer.InsertPacket( - Packet(kH264StapA).Sps().Pps().Idr().SeqNum(2).Time(1).Marker().Build()); - - auto delta = packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build()); - - ASSERT_THAT(key.packets, SizeIs(2)); - EXPECT_THAT(key.packets[0]->video_header.frame_type, - Eq(VideoFrameType::kVideoFrameKey)); - ASSERT_THAT(delta.packets, SizeIs(1)); - EXPECT_THAT(delta.packets[0]->video_header.frame_type, - Eq(VideoFrameType::kVideoFrameDelta)); -} - -TEST(H264PacketBufferTest, RtpSeqNumWrap) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())); - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, StapAFixedBitstream) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - auto packets = packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps({1, 2, 3}) - .Pps({4, 5, 6}) - .Idr({7, 8, 9}) - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(1)); - EXPECT_THAT(PacketPayload(packets[0]), - ElementsAreArray(FlatVector({StartCode(), - {kSps, 1, 2, 3}, - StartCode(), - {kPps, 4, 5, 6}, - StartCode(), - {kIdr, 7, 8, 9}}))); -} - -TEST(H264PacketBufferTest, SingleNaluFixedBitstream) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build())); - auto packets = packet_buffer - .InsertPacket(Packet(kH264SingleNalu) - .Idr({7, 8, 9}) - .SeqNum(2) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(3)); - EXPECT_THAT(PacketPayload(packets[0]), - ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}}))); - EXPECT_THAT(PacketPayload(packets[1]), - ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}}))); - EXPECT_THAT(PacketPayload(packets[2]), - ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}}))); -} - -TEST(H264PacketBufferTest, StapaAndFuaFixedBitstream) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264StapA) - .Sps({1, 2, 3}) - .Pps({4, 5, 6}) - .SeqNum(0) - .Time(0) - .Build())); - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) - .Idr({8, 8, 8}) - .SeqNum(1) - .Time(0) - .AsFirstFragment() - .Build())); - auto packets = packet_buffer - .InsertPacket(Packet(kH264FuA) - .Idr({9, 9, 9}) - .SeqNum(2) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(3)); - EXPECT_THAT( - PacketPayload(packets[0]), - ElementsAreArray(FlatVector( - {StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}}))); - EXPECT_THAT(PacketPayload(packets[1]), - ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}}))); - // Third is a continuation of second, so only the payload is expected. - EXPECT_THAT(PacketPayload(packets[2]), - ElementsAreArray(FlatVector({{9, 9, 9}}))); -} - -TEST(H264PacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - for (int i = 0; i < kBufferSize; ++i) { - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build()) - .packets, - IsEmpty()); - } - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(1) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, TooManyNalusInPacket) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - std::unique_ptr packet( - Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build()); - auto& h264_header = - absl::get(packet->video_header.video_type_header); - h264_header.nalus_length = kMaxNalusPerPacket + 1; - - EXPECT_THAT(packet_buffer.InsertPacket(std::move(packet)).packets, IsEmpty()); -} - -} // namespace -} // namespace webrtc diff --git a/modules/video_coding/h264_packet_buffer.cc b/modules/video_coding/h26x_packet_buffer.cc similarity index 68% rename from modules/video_coding/h264_packet_buffer.cc rename to modules/video_coding/h26x_packet_buffer.cc index 6096665bda..bca2b5ce29 100644 --- a/modules/video_coding/h264_packet_buffer.cc +++ b/modules/video_coding/h26x_packet_buffer.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/video_coding/h264_packet_buffer.h" +#include "modules/video_coding/h26x_packet_buffer.h" #include #include @@ -27,9 +27,13 @@ #include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/sequence_number_util.h" +#ifdef RTC_ENABLE_H265 +#include "common_video/h265/h265_common.h" +#endif namespace webrtc { namespace { + int64_t EuclideanMod(int64_t n, int64_t div) { RTC_DCHECK_GT(div, 0); return (n %= div) < 0 ? n + div : n; @@ -48,7 +52,7 @@ bool IsFirstPacketOfFragment(const RTPVideoHeaderH264& h264_header) { return h264_header.nalus_length > 0; } -bool BeginningOfIdr(const H264PacketBuffer::Packet& packet) { +bool BeginningOfIdr(const H26xPacketBuffer::Packet& packet) { const auto& h264_header = absl::get(packet.video_header.video_type_header); const bool contains_idr_nalu = @@ -66,7 +70,7 @@ bool BeginningOfIdr(const H264PacketBuffer::Packet& packet) { } } -bool HasSps(const H264PacketBuffer::Packet& packet) { +bool HasSps(const H26xPacketBuffer::Packet& packet) { auto& h264_header = absl::get(packet.video_header.video_type_header); return absl::c_any_of(GetNaluInfos(h264_header), [](const auto& nalu_info) { @@ -74,10 +78,24 @@ bool HasSps(const H264PacketBuffer::Packet& packet) { }); } +#ifdef RTC_ENABLE_H265 +bool HasVps(const H26xPacketBuffer::Packet& packet) { + std::vector nalu_indices = H265::FindNaluIndices( + packet.video_payload.cdata(), packet.video_payload.size()); + return absl::c_any_of((nalu_indices), [&packet]( + const H265::NaluIndex& nalu_index) { + return H265::ParseNaluType( + packet.video_payload.cdata()[nalu_index.payload_start_offset]) == + H265::NaluType::kVps; + }); +} +#endif + // TODO(bugs.webrtc.org/13157): Update the H264 depacketizer so we don't have to // fiddle with the payload at this point. -rtc::CopyOnWriteBuffer FixVideoPayload(rtc::ArrayView payload, - const RTPVideoHeader& video_header) { +rtc::CopyOnWriteBuffer FixH264VideoPayload( + rtc::ArrayView payload, + const RTPVideoHeader& video_header) { constexpr uint8_t kStartCode[] = {0, 0, 0, 1}; const auto& h264_header = @@ -124,18 +142,15 @@ rtc::CopyOnWriteBuffer FixVideoPayload(rtc::ArrayView payload, } // namespace -H264PacketBuffer::H264PacketBuffer(bool idr_only_keyframes_allowed) - : idr_only_keyframes_allowed_(idr_only_keyframes_allowed) {} +H26xPacketBuffer::H26xPacketBuffer(bool h264_idr_only_keyframes_allowed) + : h264_idr_only_keyframes_allowed_(h264_idr_only_keyframes_allowed) {} -H264PacketBuffer::InsertResult H264PacketBuffer::InsertPacket( +H26xPacketBuffer::InsertResult H26xPacketBuffer::InsertPacket( std::unique_ptr packet) { - RTC_DCHECK(packet->video_header.codec == kVideoCodecH264); + RTC_DCHECK(packet->video_header.codec == kVideoCodecH264 || + packet->video_header.codec == kVideoCodecH265); InsertResult result; - if (!absl::holds_alternative( - packet->video_header.video_type_header)) { - return result; - } int64_t unwrapped_seq_num = seq_num_unwrapper_.Unwrap(packet->seq_num); auto& packet_slot = GetPacket(unwrapped_seq_num); @@ -151,19 +166,27 @@ H264PacketBuffer::InsertResult H264PacketBuffer::InsertPacket( return result; } -std::unique_ptr& H264PacketBuffer::GetPacket( +std::unique_ptr& H26xPacketBuffer::GetPacket( int64_t unwrapped_seq_num) { return buffer_[EuclideanMod(unwrapped_seq_num, kBufferSize)]; } -bool H264PacketBuffer::BeginningOfStream( - const H264PacketBuffer::Packet& packet) const { - return HasSps(packet) || - (idr_only_keyframes_allowed_ && BeginningOfIdr(packet)); +bool H26xPacketBuffer::BeginningOfStream( + const H26xPacketBuffer::Packet& packet) const { + if (packet.codec() == kVideoCodecH264) { + return HasSps(packet) || + (h264_idr_only_keyframes_allowed_ && BeginningOfIdr(packet)); +#ifdef RTC_ENABLE_H265 + } else if (packet.codec() == kVideoCodecH265) { + return HasVps(packet); +#endif + } + RTC_DCHECK_NOTREACHED(); + return false; } -std::vector> -H264PacketBuffer::FindFrames(int64_t unwrapped_seq_num) { +std::vector> +H26xPacketBuffer::FindFrames(int64_t unwrapped_seq_num) { std::vector> found_frames; Packet* packet = GetPacket(unwrapped_seq_num).get(); @@ -223,13 +246,17 @@ H264PacketBuffer::FindFrames(int64_t unwrapped_seq_num) { return found_frames; } -bool H264PacketBuffer::MaybeAssembleFrame( +bool H26xPacketBuffer::MaybeAssembleFrame( int64_t start_seq_num_unwrapped, int64_t end_sequence_number_unwrapped, std::vector>& frames) { +#ifdef RTC_ENABLE_H265 + bool has_vps = false; +#endif bool has_sps = false; bool has_pps = false; bool has_idr = false; + bool has_irap = false; int width = -1; int height = -1; @@ -237,24 +264,44 @@ bool H264PacketBuffer::MaybeAssembleFrame( for (int64_t seq_num = start_seq_num_unwrapped; seq_num <= end_sequence_number_unwrapped; ++seq_num) { const auto& packet = GetPacket(seq_num); - const auto& h264_header = - absl::get(packet->video_header.video_type_header); - for (const auto& nalu : GetNaluInfos(h264_header)) { - has_idr |= nalu.type == H264::NaluType::kIdr; - has_sps |= nalu.type == H264::NaluType::kSps; - has_pps |= nalu.type == H264::NaluType::kPps; + if (packet->codec() == kVideoCodecH264) { + const auto& h264_header = + absl::get(packet->video_header.video_type_header); + for (const auto& nalu : GetNaluInfos(h264_header)) { + has_idr |= nalu.type == H264::NaluType::kIdr; + has_sps |= nalu.type == H264::NaluType::kSps; + has_pps |= nalu.type == H264::NaluType::kPps; + } + if (has_idr) { + if (!h264_idr_only_keyframes_allowed_ && (!has_sps || !has_pps)) { + return false; + } + } +#ifdef RTC_ENABLE_H265 + } else if (packet->codec() == kVideoCodecH265) { + std::vector nalu_indices = H265::FindNaluIndices( + packet->video_payload.cdata(), packet->video_payload.size()); + for (const auto& nalu_index : nalu_indices) { + uint8_t nalu_type = H265::ParseNaluType( + packet->video_payload.cdata()[nalu_index.payload_start_offset]); + has_irap |= (nalu_type >= H265::NaluType::kBlaWLp && + nalu_type <= H265::NaluType::kRsvIrapVcl23); + has_vps |= nalu_type == H265::NaluType::kVps; + has_sps |= nalu_type == H265::NaluType::kSps; + has_pps |= nalu_type == H265::NaluType::kPps; + } + if (has_irap) { + if (!has_vps || !has_sps || !has_pps) { + return false; + } + } +#endif // RTC_ENABLE_H265 } width = std::max(packet->video_header.width, width); height = std::max(packet->video_header.height, height); } - if (has_idr) { - if (!idr_only_keyframes_allowed_ && (!has_sps || !has_pps)) { - return false; - } - } - for (int64_t seq_num = start_seq_num_unwrapped; seq_num <= end_sequence_number_unwrapped; ++seq_num) { auto& packet = GetPacket(seq_num); @@ -270,13 +317,16 @@ bool H264PacketBuffer::MaybeAssembleFrame( packet->video_header.height = height; } - packet->video_header.frame_type = has_idr + packet->video_header.frame_type = has_idr || has_irap ? VideoFrameType::kVideoFrameKey : VideoFrameType::kVideoFrameDelta; } - packet->video_payload = - FixVideoPayload(packet->video_payload, packet->video_header); + // Start code is inserted by depacktizer for H.265. + if (packet->codec() == kVideoCodecH264) { + packet->video_payload = + FixH264VideoPayload(packet->video_payload, packet->video_header); + } frames.push_back(std::move(packet)); } diff --git a/modules/video_coding/h264_packet_buffer.h b/modules/video_coding/h26x_packet_buffer.h similarity index 73% rename from modules/video_coding/h264_packet_buffer.h rename to modules/video_coding/h26x_packet_buffer.h index a72c240e82..21601562c5 100644 --- a/modules/video_coding/h264_packet_buffer.h +++ b/modules/video_coding/h26x_packet_buffer.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ -#define MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ +#ifndef MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ +#define MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ #include #include @@ -22,15 +22,16 @@ namespace webrtc { -class H264PacketBuffer { +class H26xPacketBuffer { public: - // The H264PacketBuffer does the same job as the PacketBuffer but for H264 - // only. To make it fit in with surronding code the PacketBuffer input/output - // classes are used. + // The H26xPacketBuffer does the same job as the PacketBuffer but for H264 and + // H265 only. To make it fit in with surronding code the PacketBuffer + // input/output classes are used. using Packet = video_coding::PacketBuffer::Packet; using InsertResult = video_coding::PacketBuffer::InsertResult; - explicit H264PacketBuffer(bool idr_only_keyframes_allowed); + // |h264_idr_only_keyframes_allowed| is ignored if H.265 is used. + explicit H26xPacketBuffer(bool h264_idr_only_keyframes_allowed); ABSL_MUST_USE_RESULT InsertResult InsertPacket(std::unique_ptr packet); @@ -45,7 +46,7 @@ class H264PacketBuffer { int64_t end_sequence_number_unwrapped, std::vector>& packets); - const bool idr_only_keyframes_allowed_; + const bool h264_idr_only_keyframes_allowed_; std::array, kBufferSize> buffer_; absl::optional last_continuous_unwrapped_seq_num_; SeqNumUnwrapper seq_num_unwrapper_; @@ -53,4 +54,4 @@ class H264PacketBuffer { } // namespace webrtc -#endif // MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ +#endif // MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ diff --git a/modules/video_coding/h26x_packet_buffer_unittest.cc b/modules/video_coding/h26x_packet_buffer_unittest.cc new file mode 100644 index 0000000000..4a17b4d4cf --- /dev/null +++ b/modules/video_coding/h26x_packet_buffer_unittest.cc @@ -0,0 +1,1056 @@ +/* + * Copyright (c) 2021 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 "modules/video_coding/h26x_packet_buffer.h" + +#include +#include +#include +#include +#include + +#include "api/array_view.h" +#include "api/video/render_resolution.h" +#include "common_video/h264/h264_common.h" +#include "common_video/h265/h265_common.h" +#include "rtc_base/system/unused.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +using ::testing::ElementsAreArray; +using ::testing::Eq; +using ::testing::IsEmpty; +using ::testing::SizeIs; + +using H264::NaluType::kAud; +using H264::NaluType::kFuA; +using H264::NaluType::kIdr; +using H264::NaluType::kPps; +using H264::NaluType::kSlice; +using H264::NaluType::kSps; +using H264::NaluType::kStapA; + +constexpr int kBufferSize = 2048; + +std::vector StartCode() { + return {0, 0, 0, 1}; +} + +NaluInfo MakeNaluInfo(uint8_t type) { + NaluInfo res; + res.type = type; + res.sps_id = -1; + res.pps_id = -1; + return res; +} + +class H264Packet { + public: + explicit H264Packet(H264PacketizationTypes type); + + H264Packet& Idr(std::vector payload = {9, 9, 9}); + H264Packet& Slice(std::vector payload = {9, 9, 9}); + H264Packet& Sps(std::vector payload = {9, 9, 9}); + H264Packet& SpsWithResolution(RenderResolution resolution, + std::vector payload = {9, 9, 9}); + H264Packet& Pps(std::vector payload = {9, 9, 9}); + H264Packet& Aud(); + H264Packet& Marker(); + H264Packet& AsFirstFragment(); + H264Packet& Time(uint32_t rtp_timestamp); + H264Packet& SeqNum(uint16_t rtp_seq_num); + + std::unique_ptr Build(); + + private: + rtc::CopyOnWriteBuffer BuildFuaPayload() const; + rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const; + rtc::CopyOnWriteBuffer BuildStapAPayload() const; + + RTPVideoHeaderH264& H264Header() { + return absl::get(video_header_.video_type_header); + } + const RTPVideoHeaderH264& H264Header() const { + return absl::get(video_header_.video_type_header); + } + + H264PacketizationTypes type_; + RTPVideoHeader video_header_; + bool first_fragment_ = false; + bool marker_bit_ = false; + uint32_t rtp_timestamp_ = 0; + uint16_t rtp_seq_num_ = 0; + std::vector> nalu_payloads_; +}; + +H264Packet::H264Packet(H264PacketizationTypes type) : type_(type) { + video_header_.video_type_header.emplace(); +} + +H264Packet& H264Packet::Idr(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kIdr); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Slice(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSlice); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Sps(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::SpsWithResolution(RenderResolution resolution, + std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); + video_header_.width = resolution.Width(); + video_header_.height = resolution.Height(); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Pps(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kPps); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Aud() { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kAud); + nalu_payloads_.push_back({}); + return *this; +} + +H264Packet& H264Packet::Marker() { + marker_bit_ = true; + return *this; +} + +H264Packet& H264Packet::AsFirstFragment() { + first_fragment_ = true; + return *this; +} + +H264Packet& H264Packet::Time(uint32_t rtp_timestamp) { + rtp_timestamp_ = rtp_timestamp; + return *this; +} + +H264Packet& H264Packet::SeqNum(uint16_t rtp_seq_num) { + rtp_seq_num_ = rtp_seq_num; + return *this; +} + +std::unique_ptr H264Packet::Build() { + auto res = std::make_unique(); + + auto& h264_header = H264Header(); + switch (type_) { + case kH264FuA: { + RTC_CHECK_EQ(h264_header.nalus_length, 1); + res->video_payload = BuildFuaPayload(); + break; + } + case kH264SingleNalu: { + RTC_CHECK_EQ(h264_header.nalus_length, 1); + res->video_payload = BuildSingleNaluPayload(); + break; + } + case kH264StapA: { + RTC_CHECK_GT(h264_header.nalus_length, 1); + RTC_CHECK_LE(h264_header.nalus_length, kMaxNalusPerPacket); + res->video_payload = BuildStapAPayload(); + break; + } + } + + if (type_ == kH264FuA && !first_fragment_) { + h264_header.nalus_length = 0; + } + + h264_header.packetization_type = type_; + res->marker_bit = marker_bit_; + res->video_header = video_header_; + res->timestamp = rtp_timestamp_; + res->seq_num = rtp_seq_num_; + res->video_header.codec = kVideoCodecH264; + + return res; +} + +rtc::CopyOnWriteBuffer H264Packet::BuildFuaPayload() const { + return rtc::CopyOnWriteBuffer(nalu_payloads_[0]); +} + +rtc::CopyOnWriteBuffer H264Packet::BuildSingleNaluPayload() const { + rtc::CopyOnWriteBuffer res; + auto& h264_header = H264Header(); + res.AppendData(&h264_header.nalus[0].type, 1); + res.AppendData(nalu_payloads_[0]); + return res; +} + +rtc::CopyOnWriteBuffer H264Packet::BuildStapAPayload() const { + rtc::CopyOnWriteBuffer res; + + const uint8_t indicator = H264::NaluType::kStapA; + res.AppendData(&indicator, 1); + + auto& h264_header = H264Header(); + for (size_t i = 0; i < h264_header.nalus_length; ++i) { + // The two first bytes indicates the nalu segment size. + uint8_t length_as_array[2] = { + 0, static_cast(nalu_payloads_[i].size() + 1)}; + res.AppendData(length_as_array); + + res.AppendData(&h264_header.nalus[i].type, 1); + res.AppendData(nalu_payloads_[i]); + } + return res; +} + +#ifdef RTC_ENABLE_H265 +class H265Packet { + public: + H265Packet() = default; + + H265Packet& Idr(std::vector payload = {9, 9, 9}); + H265Packet& Slice(H265::NaluType type, + std::vector payload = {9, 9, 9}); + H265Packet& Vps(std::vector payload = {9, 9, 9}); + H265Packet& Sps(std::vector payload = {9, 9, 9}); + H265Packet& SpsWithResolution(RenderResolution resolution, + std::vector payload = {9, 9, 9}); + H265Packet& Pps(std::vector payload = {9, 9, 9}); + H265Packet& Aud(); + H265Packet& Marker(); + H265Packet& AsFirstFragment(); + H265Packet& Time(uint32_t rtp_timestamp); + H265Packet& SeqNum(uint16_t rtp_seq_num); + + std::unique_ptr Build(); + + private: + H265Packet& StartCode(); + + RTPVideoHeader video_header_; + bool first_fragment_ = false; + bool marker_bit_ = false; + uint32_t rtp_timestamp_ = 0; + uint16_t rtp_seq_num_ = 0; + std::vector> nalu_payloads_; +}; + +H265Packet& H265Packet::Idr(std::vector payload) { + return Slice(H265::NaluType::kIdrNLp, std::move(payload)); +} + +H265Packet& H265Packet::Slice(H265::NaluType type, + std::vector payload) { + StartCode(); + // Nalu header. Assume layer ID is 0 and TID is 2. + nalu_payloads_.push_back({static_cast(type << 1), 0x02}); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H265Packet& H265Packet::Vps(std::vector payload) { + return Slice(H265::NaluType::kVps, std::move(payload)); +} + +H265Packet& H265Packet::Sps(std::vector payload) { + return Slice(H265::NaluType::kSps, std::move(payload)); +} + +H265Packet& H265Packet::SpsWithResolution(RenderResolution resolution, + std::vector payload) { + video_header_.width = resolution.Width(); + video_header_.height = resolution.Height(); + return Sps(std::move(payload)); +} + +H265Packet& H265Packet::Pps(std::vector payload) { + return Slice(H265::NaluType::kPps, std::move(payload)); +} + +H265Packet& H265Packet::Aud() { + return Slice(H265::NaluType::kAud, {}); +} + +H265Packet& H265Packet::Marker() { + marker_bit_ = true; + return *this; +} + +H265Packet& H265Packet::StartCode() { + nalu_payloads_.push_back({0x00, 0x00, 0x00, 0x01}); + return *this; +} + +std::unique_ptr H265Packet::Build() { + auto res = std::make_unique(); + res->marker_bit = marker_bit_; + res->video_header = video_header_; + res->timestamp = rtp_timestamp_; + res->seq_num = rtp_seq_num_; + res->video_header.codec = kVideoCodecH265; + res->video_payload = rtc::CopyOnWriteBuffer(); + for (const auto& payload : nalu_payloads_) { + res->video_payload.AppendData(payload); + } + + return res; +} + +H265Packet& H265Packet::AsFirstFragment() { + first_fragment_ = true; + return *this; +} + +H265Packet& H265Packet::Time(uint32_t rtp_timestamp) { + rtp_timestamp_ = rtp_timestamp; + return *this; +} + +H265Packet& H265Packet::SeqNum(uint16_t rtp_seq_num) { + rtp_seq_num_ = rtp_seq_num; + return *this; +} +#endif + +rtc::ArrayView PacketPayload( + const std::unique_ptr& packet) { + return packet->video_payload; +} + +std::vector FlatVector( + const std::vector>& elems) { + std::vector res; + for (const auto& elem : elems) { + res.insert(res.end(), elem.begin(), elem.end()); + } + return res; +} + +TEST(H26xPacketBufferTest, IdrIsKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, IdrIsNotKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); + + // Not marked as the first fragment + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()) + .packets, + IsEmpty()); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + IsEmpty()); + + // Marked as first fragment + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Idr() + .SeqNum(2) + .Time(1) + .AsFirstFragment() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build()) + .packets, + SizeIs(2)); +} + +TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build())); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr() + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build())); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr() + .SeqNum(1) + .Time(0) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr() + .SeqNum(1) + .Time(0) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeStapA) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeStapA) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeStapA) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Idr() + .SeqNum(2) + .Time(2) + .Marker() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(3) + .Time(3) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build())); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build()) + .packets, + SizeIs(2)); +} + +TEST(H26xPacketBufferTest, InsertingMidFuaCompletesFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(1) + .Time(1) + .AsFirstFragment() + .Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, SeqNumJumpDoesNotCompleteFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build()) + .packets, + IsEmpty()); + + // Add `kBufferSize` to make the index of the sequence number wrap and end up + // where the packet with sequence number 2 would have ended up. + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(2 + kBufferSize) + .Time(3) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Slice() + .SeqNum(1) + .Time(1) + .Marker() + .Build()) + .packets, + IsEmpty()); + + // New keyframe, preceedes packet with sequence number 1 in the buffer. + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, OldPacketsDontBlockNewPackets) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 1) + .Time(kBufferSize + 1) + .AsFirstFragment() + .Build())); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 3) + .Time(kBufferSize + 1) + .Marker() + .Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 2) + .Time(kBufferSize + 1) + .Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, OldPacketDoesntCompleteFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 3) + .Time(kBufferSize + 1) + .Marker() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 1) + .Time(kBufferSize + 1) + .AsFirstFragment() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, FrameBoundariesAreSet) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(1) + .Time(1) + .Marker() + .Build()); + + ASSERT_THAT(key.packets, SizeIs(1)); + EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame); + EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build())); + auto delta = packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build()); + + ASSERT_THAT(delta.packets, SizeIs(3)); + EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame); + EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame); + + EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame); + EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame); + + EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame); + EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame); +} + +TEST(H26xPacketBufferTest, ResolutionSetOnFirstPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); + auto res = packet_buffer.InsertPacket(H264Packet(kH264StapA) + .SpsWithResolution({320, 240}) + .Pps() + .Idr() + .SeqNum(2) + .Time(1) + .Marker() + .Build()); + + ASSERT_THAT(res.packets, SizeIs(2)); + EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); + EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); +} + +TEST(H26xPacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); + auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(2) + .Time(1) + .Marker() + .Build()); + + auto delta = packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build()); + + ASSERT_THAT(key.packets, SizeIs(2)); + EXPECT_THAT(key.packets[0]->video_header.frame_type, + Eq(VideoFrameType::kVideoFrameKey)); + ASSERT_THAT(delta.packets, SizeIs(1)); + EXPECT_THAT(delta.packets[0]->video_header.frame_type, + Eq(VideoFrameType::kVideoFrameDelta)); +} + +TEST(H26xPacketBufferTest, RtpSeqNumWrap) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, StapAFixedBitstream) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + auto packets = packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps({1, 2, 3}) + .Pps({4, 5, 6}) + .Idr({7, 8, 9}) + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(1)); + EXPECT_THAT(PacketPayload(packets[0]), + ElementsAreArray(FlatVector({StartCode(), + {kSps, 1, 2, 3}, + StartCode(), + {kPps, 4, 5, 6}, + StartCode(), + {kIdr, 7, 8, 9}}))); +} + +TEST(H26xPacketBufferTest, SingleNaluFixedBitstream) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build())); + auto packets = packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr({7, 8, 9}) + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(3)); + EXPECT_THAT(PacketPayload(packets[0]), + ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}}))); + EXPECT_THAT(PacketPayload(packets[1]), + ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}}))); + EXPECT_THAT(PacketPayload(packets[2]), + ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}}))); +} + +TEST(H26xPacketBufferTest, StapaAndFuaFixedBitstream) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264StapA) + .Sps({1, 2, 3}) + .Pps({4, 5, 6}) + .SeqNum(0) + .Time(0) + .Build())); + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Idr({8, 8, 8}) + .SeqNum(1) + .Time(0) + .AsFirstFragment() + .Build())); + auto packets = packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Idr({9, 9, 9}) + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(3)); + EXPECT_THAT( + PacketPayload(packets[0]), + ElementsAreArray(FlatVector( + {StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}}))); + EXPECT_THAT(PacketPayload(packets[1]), + ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}}))); + // Third is a continuation of second, so only the payload is expected. + EXPECT_THAT(PacketPayload(packets[2]), + ElementsAreArray(FlatVector({{9, 9, 9}}))); +} + +TEST(H26xPacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + for (int i = 0; i < kBufferSize; ++i) { + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build()) + .packets, + IsEmpty()); + } + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(1) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, TooManyNalusInPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + std::unique_ptr packet(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(1) + .Time(1) + .Marker() + .Build()); + auto& h264_header = + absl::get(packet->video_header.video_type_header); + h264_header.nalus_length = kMaxNalusPerPacket + 1; + + EXPECT_THAT(packet_buffer.InsertPacket(std::move(packet)).packets, IsEmpty()); +} + +#ifdef RTC_ENABLE_H265 +TEST(H26xPacketBufferTest, H265VpsSpsPpsIdrIsKeyframe) { + H26xPacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H265Packet().Vps().Sps().Pps().Idr().Marker().Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, H265IrapIsNotKeyframe) { + std::vector irap_types = { + H265::NaluType::kBlaWLp, H265::NaluType::kBlaWRadl, + H265::NaluType::kBlaNLp, H265::NaluType::kIdrWRadl, + H265::NaluType::kIdrNLp, H265::NaluType::kCra, + H265::NaluType::kRsvIrapVcl23}; + for (const H265::NaluType type : irap_types) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Slice(type).Marker().Build()) + .packets, + IsEmpty()); + } +} + +TEST(H26xPacketBufferTest, H265IdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Idr().Marker().Build()).packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265SpsPpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H265Packet().Sps().Pps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265VpsPpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H265Packet().Vps().Pps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265VpsSpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H265Packet().Vps().Sps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265VpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Vps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265SpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Sps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265PpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Pps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265ResolutionSetOnSpsPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED( + packet_buffer.InsertPacket(H265Packet().Aud().SeqNum(1).Time(1).Build())); + auto res = packet_buffer.InsertPacket(H265Packet() + .Vps() + .SpsWithResolution({320, 240}) + .Pps() + .Idr() + .SeqNum(2) + .Time(1) + .Marker() + .Build()); + + ASSERT_THAT(res.packets, SizeIs(2)); + EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); + EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); +} + +TEST(H26xPacketBufferTest, H265InsertingVpsSpsPpsLastCompletesKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H265Packet().Idr().SeqNum(2).Time(1).Marker().Build())); + + EXPECT_THAT(packet_buffer + .InsertPacket( + H265Packet().Vps().Sps().Pps().SeqNum(1).Time(1).Build()) + .packets, + SizeIs(2)); +} +#endif // RTC_ENABLE_H265 + +} // namespace +} // namespace webrtc From f7b22c66ff7ef9ea9f4688812cbbab2fd48cf098 Mon Sep 17 00:00:00 2001 From: Tommi Date: Thu, 15 Feb 2024 09:18:34 +0100 Subject: [PATCH 144/170] Add Candidate::type_name() Candidate::type() is currently how the name of the type is fetched, but that getter returns a non-standard type name. Instead, I'm adding a new getter, type_name(), will follow up with updating dependent code that needs the string, to use type_name (and adapt to potential dependency on "local" or "stun") and then switch type() to be enum based. Also adding a test file for Candidate with a couple of basic tests to start with. Bug: webrtc:15846 Change-Id: I9b78b2405a9f962a3c07eaa8e72a79854c6f5ceb Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339660 Reviewed-by: Harald Alvestrand Commit-Queue: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41740} --- api/BUILD.gn | 4 +++ api/candidate.cc | 12 +++++++++ api/candidate.h | 4 +++ api/candidate_unittest.cc | 54 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 api/candidate_unittest.cc diff --git a/api/BUILD.gn b/api/BUILD.gn index e8d03f0e3e..0c982a2ac6 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -1430,6 +1430,7 @@ if (rtc_include_tests) { sources = [ "array_view_unittest.cc", + "candidate_unittest.cc", "field_trials_unittest.cc", "function_view_unittest.cc", "rtc_error_unittest.cc", @@ -1445,6 +1446,7 @@ if (rtc_include_tests) { deps = [ ":array_view", + ":candidate", ":create_time_controller", ":field_trials", ":field_trials_view", @@ -1458,12 +1460,14 @@ if (rtc_include_tests) { ":scoped_refptr", ":sequence_checker", ":time_controller", + "../p2p:rtc_p2p", "../rtc_base:buffer", "../rtc_base:checks", "../rtc_base:gunit_helpers", "../rtc_base:platform_thread", "../rtc_base:rtc_event", "../rtc_base:rtc_task_queue", + "../rtc_base:ssl", "../rtc_base:task_queue_for_test", "../rtc_base/containers:flat_set", "../rtc_base/task_utils:repeating_task", diff --git a/api/candidate.cc b/api/candidate.cc index 4311556233..8969b06583 100644 --- a/api/candidate.cc +++ b/api/candidate.cc @@ -27,6 +27,7 @@ Candidate::Candidate() : id_(rtc::CreateRandomString(8)), component_(0), priority_(0), + type_(LOCAL_PORT_TYPE), network_type_(rtc::ADAPTER_TYPE_UNKNOWN), underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN), generation_(0), @@ -76,6 +77,17 @@ bool Candidate::is_relay() const { return type_ == RELAY_PORT_TYPE; } +absl::string_view Candidate::type_name() const { + // The LOCAL_PORT_TYPE and STUN_PORT_TYPE constants are not the standard type + // names, so check for those specifically. For other types, `type_` will have + // the correct name. + if (is_local()) + return "host"; + if (is_stun()) + return "srflx"; + return type_; +} + bool Candidate::IsEquivalent(const Candidate& c) const { // We ignore the network name, since that is just debug information, and // the priority and the network cost, since they should be the same if the diff --git a/api/candidate.h b/api/candidate.h index 12b1512e72..101a3bd0a4 100644 --- a/api/candidate.h +++ b/api/candidate.h @@ -93,6 +93,10 @@ class RTC_EXPORT Candidate { const std::string& type() const { return type_; } + // Returns the name of the candidate type as specified in + // https://datatracker.ietf.org/doc/html/rfc5245#section-15.1 + absl::string_view type_name() const; + // Setting the type requires a constant string (e.g. // cricket::LOCAL_PORT_TYPE). The type should really be an enum rather than a // string, but until we make that change the lifetime attribute helps us lock diff --git a/api/candidate_unittest.cc b/api/candidate_unittest.cc new file mode 100644 index 0000000000..fa512d6220 --- /dev/null +++ b/api/candidate_unittest.cc @@ -0,0 +1,54 @@ +/* + * Copyright 2024 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/candidate.h" + +#include + +#include "p2p/base/p2p_constants.h" +#include "rtc_base/gunit.h" + +namespace cricket { + +TEST(CandidateTest, Id) { + Candidate c; + EXPECT_EQ(c.id().size(), 8u); + std::string new_id = "12345678"; + c.set_id(new_id); + EXPECT_EQ(new_id, c.id()); +} + +TEST(CandidateTest, Component) { + Candidate c; + EXPECT_EQ(c.component(), 0); + c.set_component(ICE_CANDIDATE_COMPONENT_DEFAULT); + EXPECT_EQ(c.component(), ICE_CANDIDATE_COMPONENT_DEFAULT); +} + +TEST(CandidateTest, TypeName) { + Candidate c; + // The `type_name()` property defaults to "host". + EXPECT_EQ(c.type_name(), "host"); + EXPECT_EQ(c.type(), LOCAL_PORT_TYPE); + + c.set_type(STUN_PORT_TYPE); + EXPECT_EQ(c.type_name(), "srflx"); + EXPECT_EQ(c.type(), STUN_PORT_TYPE); + + c.set_type(PRFLX_PORT_TYPE); + EXPECT_EQ(c.type_name(), "prflx"); + EXPECT_EQ(c.type(), PRFLX_PORT_TYPE); + + c.set_type(RELAY_PORT_TYPE); + EXPECT_EQ(c.type_name(), "relay"); + EXPECT_EQ(c.type(), RELAY_PORT_TYPE); +} + +} // namespace cricket From b158537a4f3ee38b6e87dd538ecdd3be2fd297e7 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 12 Feb 2024 15:28:35 +0100 Subject: [PATCH 145/170] Allow to propagate field trials into Vp8 Decoder Bug: webrtc:15791 Change-Id: I0cd279006924c7a4859697b26a2271c3dc63ea6d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/337400 Reviewed-by: Philip Eliasson Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41741} --- api/video_codecs/test/BUILD.gn | 3 ++ ...oder_software_fallback_wrapper_unittest.cc | 10 +++++-- modules/video_coding/BUILD.gn | 3 ++ modules/video_coding/codecs/vp8/include/vp8.h | 5 ++++ .../codecs/vp8/libvpx_vp8_decoder.cc | 30 +++++++++++++------ .../codecs/vp8/libvpx_vp8_decoder.h | 6 ++++ .../codecs/vp8/libvpx_vp8_simulcast_test.cc | 4 ++- .../codecs/vp8/test/vp8_impl_unittest.cc | 3 +- 8 files changed, 50 insertions(+), 14 deletions(-) diff --git a/api/video_codecs/test/BUILD.gn b/api/video_codecs/test/BUILD.gn index 7bfe86e9f4..d338406bc4 100644 --- a/api/video_codecs/test/BUILD.gn +++ b/api/video_codecs/test/BUILD.gn @@ -41,8 +41,11 @@ if (rtc_include_tests) { "../../../rtc_base:rtc_base_tests_utils", "../../../test:fake_video_codecs", "../../../test:field_trial", + "../../../test:scoped_key_value_config", "../../../test:test_support", "../../../test:video_test_common", + "../../environment", + "../../environment:environment_factory", "../../video:encoded_image", "../../video:video_bitrate_allocation", "../../video:video_frame", diff --git a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc index 97be6250db..de9293bbe0 100644 --- a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc +++ b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc @@ -13,6 +13,8 @@ #include #include "absl/types/optional.h" +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/video/encoded_image.h" #include "api/video/video_frame.h" #include "api/video_codecs/video_decoder.h" @@ -20,8 +22,8 @@ #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/checks.h" -#include "test/field_trial.h" #include "test/gtest.h" +#include "test/scoped_key_value_config.h" namespace webrtc { @@ -32,9 +34,10 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test { explicit VideoDecoderSoftwareFallbackWrapperTest( const std::string& field_trials) : override_field_trials_(field_trials), + env_(CreateEnvironment(&override_field_trials_)), fake_decoder_(new CountingFakeDecoder()), fallback_wrapper_(CreateVideoDecoderSoftwareFallbackWrapper( - std::unique_ptr(VP8Decoder::Create()), + CreateVp8Decoder(env_), std::unique_ptr(fake_decoder_))) {} class CountingFakeDecoder : public VideoDecoder { @@ -71,7 +74,8 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test { int release_count_ = 0; int reset_count_ = 0; }; - test::ScopedFieldTrials override_field_trials_; + test::ScopedKeyValueConfig override_field_trials_; + const Environment env_; // `fake_decoder_` is owned and released by `fallback_wrapper_`. CountingFakeDecoder* fake_decoder_; std::unique_ptr fallback_wrapper_; diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 6e62b9ace3..35fb2b49bc 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -585,7 +585,10 @@ rtc_library("webrtc_vp8") { ":webrtc_vp8_scalability", ":webrtc_vp8_temporal_layers", "../../api:fec_controller_api", + "../../api:field_trials_view", "../../api:scoped_refptr", + "../../api/environment", + "../../api/transport:field_trial_based_config", "../../api/units:time_delta", "../../api/units:timestamp", "../../api/video:encoded_image", diff --git a/modules/video_coding/codecs/vp8/include/vp8.h b/modules/video_coding/codecs/vp8/include/vp8.h index 2fc647874f..45b7cee00a 100644 --- a/modules/video_coding/codecs/vp8/include/vp8.h +++ b/modules/video_coding/codecs/vp8/include/vp8.h @@ -14,6 +14,7 @@ #include #include +#include "api/environment/environment.h" #include "api/video_codecs/video_encoder.h" #include "api/video_codecs/vp8_frame_buffer_controller.h" #include "modules/video_coding/include/video_codec_interface.h" @@ -40,11 +41,15 @@ class VP8Encoder { static std::unique_ptr Create(Settings settings); }; +// TODO: bugs.webrtc.org/15791 - Deprecate and delete in favor of the +// CreateVp8Decoder function. class VP8Decoder { public: static std::unique_ptr Create(); }; +std::unique_ptr CreateVp8Decoder(const Environment& env); + } // namespace webrtc #endif // MODULES_VIDEO_CODING_CODECS_VP8_INCLUDE_VP8_H_ diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc index 5afd105949..3466080c83 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc @@ -18,7 +18,10 @@ #include #include "absl/types/optional.h" +#include "api/environment/environment.h" +#include "api/field_trials_view.h" #include "api/scoped_refptr.h" +#include "api/transport/field_trial_based_config.h" #include "api/video/i420_buffer.h" #include "api/video/video_frame.h" #include "api/video/video_frame_buffer.h" @@ -28,7 +31,6 @@ #include "rtc_base/checks.h" #include "rtc_base/numerics/exp_filter.h" #include "rtc_base/time_utils.h" -#include "system_wrappers/include/field_trial.h" #include "system_wrappers/include/metrics.h" #include "third_party/libyuv/include/libyuv/convert.h" #include "vpx/vp8.h" @@ -59,9 +61,9 @@ absl::optional DefaultDeblockParams() { } absl::optional -GetPostProcParamsFromFieldTrialGroup() { - std::string group = webrtc::field_trial::FindFullName( - kIsArm ? kVp8PostProcArmFieldTrial : kVp8PostProcFieldTrial); +GetPostProcParamsFromFieldTrialGroup(const FieldTrialsView& field_trials) { + std::string group = field_trials.Lookup(kIsArm ? kVp8PostProcArmFieldTrial + : kVp8PostProcFieldTrial); if (group.empty()) { return DefaultDeblockParams(); } @@ -89,6 +91,10 @@ std::unique_ptr VP8Decoder::Create() { return std::make_unique(); } +std::unique_ptr CreateVp8Decoder(const Environment& env) { + return std::make_unique(env); +} + class LibvpxVp8Decoder::QpSmoother { public: QpSmoother() : last_sample_ms_(rtc::TimeMillis()), smoother_(kAlpha) {} @@ -114,9 +120,14 @@ class LibvpxVp8Decoder::QpSmoother { }; LibvpxVp8Decoder::LibvpxVp8Decoder() - : use_postproc_( - kIsArm ? webrtc::field_trial::IsEnabled(kVp8PostProcArmFieldTrial) - : true), + : LibvpxVp8Decoder(FieldTrialBasedConfig()) {} + +LibvpxVp8Decoder::LibvpxVp8Decoder(const Environment& env) + : LibvpxVp8Decoder(env.field_trials()) {} + +LibvpxVp8Decoder::LibvpxVp8Decoder(const FieldTrialsView& field_trials) + : use_postproc_(kIsArm ? field_trials.IsEnabled(kVp8PostProcArmFieldTrial) + : true), buffer_pool_(false, 300 /* max_number_of_buffers*/), decode_complete_callback_(NULL), inited_(false), @@ -124,8 +135,9 @@ LibvpxVp8Decoder::LibvpxVp8Decoder() last_frame_width_(0), last_frame_height_(0), key_frame_required_(true), - deblock_params_(use_postproc_ ? GetPostProcParamsFromFieldTrialGroup() - : absl::nullopt), + deblock_params_(use_postproc_ + ? GetPostProcParamsFromFieldTrialGroup(field_trials) + : absl::nullopt), qp_smoother_(use_postproc_ ? new QpSmoother() : nullptr) {} LibvpxVp8Decoder::~LibvpxVp8Decoder() { diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h index 74f4dc7c89..8ed8e7ca88 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h @@ -14,6 +14,8 @@ #include #include "absl/types/optional.h" +#include "api/environment/environment.h" +#include "api/field_trials_view.h" #include "api/video/encoded_image.h" #include "api/video_codecs/video_decoder.h" #include "common_video/include/video_frame_buffer_pool.h" @@ -26,7 +28,10 @@ namespace webrtc { class LibvpxVp8Decoder : public VideoDecoder { public: + // TODO: bugs.webrtc.org/15791 - Delete default constructor when + // Environment is always propagated. LibvpxVp8Decoder(); + explicit LibvpxVp8Decoder(const Environment& env); ~LibvpxVp8Decoder() override; bool Configure(const Settings& settings) override; @@ -56,6 +61,7 @@ class LibvpxVp8Decoder : public VideoDecoder { private: class QpSmoother; + explicit LibvpxVp8Decoder(const FieldTrialsView& field_trials); int ReturnFrame(const vpx_image_t* img, uint32_t timeStamp, int qp, diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_simulcast_test.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_simulcast_test.cc index 4ca3de20d5..3f13066892 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_simulcast_test.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_simulcast_test.cc @@ -27,7 +27,9 @@ std::unique_ptr CreateSpecificSimulcastTestFixture() { []() { return VP8Encoder::Create(); }); std::unique_ptr decoder_factory = std::make_unique( - []() { return VP8Decoder::Create(); }); + [](const Environment& env, const SdpVideoFormat& format) { + return CreateVp8Decoder(env); + }); return CreateSimulcastTestFixture(std::move(encoder_factory), std::move(decoder_factory), SdpVideoFormat("VP8")); diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc index a6f570f855..514d3d7e1d 100644 --- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc +++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc @@ -13,6 +13,7 @@ #include #include +#include "api/environment/environment_factory.h" #include "api/test/create_frame_generator.h" #include "api/test/frame_generator_interface.h" #include "api/test/mock_video_decoder.h" @@ -70,7 +71,7 @@ class TestVp8Impl : public VideoCodecUnitTest { } std::unique_ptr CreateDecoder() override { - return VP8Decoder::Create(); + return CreateVp8Decoder(CreateEnvironment()); } void ModifyCodecSettings(VideoCodec* codec_settings) override { From 611f21d0d4c994b791db6ea90f484c83237f63f2 Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Thu, 15 Feb 2024 10:54:20 +0000 Subject: [PATCH 146/170] Revert "Add HEVC support for h264_packet_buffer." This reverts commit a2655449ee310704ee2053fd6d43a5ab7002b755. Reason for revert: H265 tests must be hidden behind RTC_ENABLE_H265. Original change's description: > Add HEVC support for h264_packet_buffer. > > Renamed to h26x_packet_buffer as it also supports HEVC now. For HEVC, > start code is added by depacktizer, and remote endpoint must send > sequence and picture information in-band. > > Co-authored-by: Qiujiao Wu > > Bug: webrtc:13485 > Change-Id: I321cb223357d8d15da95cec80ec0c3a43c26734e > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333863 > Reviewed-by: Philip Eliasson > Commit-Queue: Philip Eliasson > Cr-Commit-Position: refs/heads/main@{#41739} Bug: webrtc:13485 Change-Id: I64660d73ef0d790b25622ce882aab3db63facf26 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339861 Bot-Commit: rubber-stamper@appspot.gserviceaccount.com Commit-Queue: Mirko Bonadei Owners-Override: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41742} --- modules/video_coding/BUILD.gn | 10 +- ...packet_buffer.cc => h264_packet_buffer.cc} | 122 +- ...x_packet_buffer.h => h264_packet_buffer.h} | 19 +- .../h264_packet_buffer_unittest.cc | 778 ++++++++++++ .../h26x_packet_buffer_unittest.cc | 1056 ----------------- 5 files changed, 828 insertions(+), 1157 deletions(-) rename modules/video_coding/{h26x_packet_buffer.cc => h264_packet_buffer.cc} (68%) rename modules/video_coding/{h26x_packet_buffer.h => h264_packet_buffer.h} (73%) create mode 100644 modules/video_coding/h264_packet_buffer_unittest.cc delete mode 100644 modules/video_coding/h26x_packet_buffer_unittest.cc diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 35fb2b49bc..1cdc83662c 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -124,10 +124,10 @@ rtc_library("packet_buffer") { ] } -rtc_library("h26x_packet_buffer") { +rtc_library("h264_packet_buffer") { sources = [ - "h26x_packet_buffer.cc", - "h26x_packet_buffer.h", + "h264_packet_buffer.cc", + "h264_packet_buffer.h", ] deps = [ ":codec_globals_headers", @@ -1167,9 +1167,9 @@ if (rtc_include_tests) { "frame_dependencies_calculator_unittest.cc", "frame_helpers_unittest.cc", "generic_decoder_unittest.cc", + "h264_packet_buffer_unittest.cc", "h264_sprop_parameter_sets_unittest.cc", "h264_sps_pps_tracker_unittest.cc", - "h26x_packet_buffer_unittest.cc", "histogram_unittest.cc", "loss_notification_controller_unittest.cc", "nack_requester_unittest.cc", @@ -1204,7 +1204,7 @@ if (rtc_include_tests) { ":encoded_frame", ":frame_dependencies_calculator", ":frame_helpers", - ":h26x_packet_buffer", + ":h264_packet_buffer", ":nack_requester", ":packet_buffer", ":simulcast_test_fixture_impl", diff --git a/modules/video_coding/h26x_packet_buffer.cc b/modules/video_coding/h264_packet_buffer.cc similarity index 68% rename from modules/video_coding/h26x_packet_buffer.cc rename to modules/video_coding/h264_packet_buffer.cc index bca2b5ce29..6096665bda 100644 --- a/modules/video_coding/h26x_packet_buffer.cc +++ b/modules/video_coding/h264_packet_buffer.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/video_coding/h26x_packet_buffer.h" +#include "modules/video_coding/h264_packet_buffer.h" #include #include @@ -27,13 +27,9 @@ #include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/sequence_number_util.h" -#ifdef RTC_ENABLE_H265 -#include "common_video/h265/h265_common.h" -#endif namespace webrtc { namespace { - int64_t EuclideanMod(int64_t n, int64_t div) { RTC_DCHECK_GT(div, 0); return (n %= div) < 0 ? n + div : n; @@ -52,7 +48,7 @@ bool IsFirstPacketOfFragment(const RTPVideoHeaderH264& h264_header) { return h264_header.nalus_length > 0; } -bool BeginningOfIdr(const H26xPacketBuffer::Packet& packet) { +bool BeginningOfIdr(const H264PacketBuffer::Packet& packet) { const auto& h264_header = absl::get(packet.video_header.video_type_header); const bool contains_idr_nalu = @@ -70,7 +66,7 @@ bool BeginningOfIdr(const H26xPacketBuffer::Packet& packet) { } } -bool HasSps(const H26xPacketBuffer::Packet& packet) { +bool HasSps(const H264PacketBuffer::Packet& packet) { auto& h264_header = absl::get(packet.video_header.video_type_header); return absl::c_any_of(GetNaluInfos(h264_header), [](const auto& nalu_info) { @@ -78,24 +74,10 @@ bool HasSps(const H26xPacketBuffer::Packet& packet) { }); } -#ifdef RTC_ENABLE_H265 -bool HasVps(const H26xPacketBuffer::Packet& packet) { - std::vector nalu_indices = H265::FindNaluIndices( - packet.video_payload.cdata(), packet.video_payload.size()); - return absl::c_any_of((nalu_indices), [&packet]( - const H265::NaluIndex& nalu_index) { - return H265::ParseNaluType( - packet.video_payload.cdata()[nalu_index.payload_start_offset]) == - H265::NaluType::kVps; - }); -} -#endif - // TODO(bugs.webrtc.org/13157): Update the H264 depacketizer so we don't have to // fiddle with the payload at this point. -rtc::CopyOnWriteBuffer FixH264VideoPayload( - rtc::ArrayView payload, - const RTPVideoHeader& video_header) { +rtc::CopyOnWriteBuffer FixVideoPayload(rtc::ArrayView payload, + const RTPVideoHeader& video_header) { constexpr uint8_t kStartCode[] = {0, 0, 0, 1}; const auto& h264_header = @@ -142,15 +124,18 @@ rtc::CopyOnWriteBuffer FixH264VideoPayload( } // namespace -H26xPacketBuffer::H26xPacketBuffer(bool h264_idr_only_keyframes_allowed) - : h264_idr_only_keyframes_allowed_(h264_idr_only_keyframes_allowed) {} +H264PacketBuffer::H264PacketBuffer(bool idr_only_keyframes_allowed) + : idr_only_keyframes_allowed_(idr_only_keyframes_allowed) {} -H26xPacketBuffer::InsertResult H26xPacketBuffer::InsertPacket( +H264PacketBuffer::InsertResult H264PacketBuffer::InsertPacket( std::unique_ptr packet) { - RTC_DCHECK(packet->video_header.codec == kVideoCodecH264 || - packet->video_header.codec == kVideoCodecH265); + RTC_DCHECK(packet->video_header.codec == kVideoCodecH264); InsertResult result; + if (!absl::holds_alternative( + packet->video_header.video_type_header)) { + return result; + } int64_t unwrapped_seq_num = seq_num_unwrapper_.Unwrap(packet->seq_num); auto& packet_slot = GetPacket(unwrapped_seq_num); @@ -166,27 +151,19 @@ H26xPacketBuffer::InsertResult H26xPacketBuffer::InsertPacket( return result; } -std::unique_ptr& H26xPacketBuffer::GetPacket( +std::unique_ptr& H264PacketBuffer::GetPacket( int64_t unwrapped_seq_num) { return buffer_[EuclideanMod(unwrapped_seq_num, kBufferSize)]; } -bool H26xPacketBuffer::BeginningOfStream( - const H26xPacketBuffer::Packet& packet) const { - if (packet.codec() == kVideoCodecH264) { - return HasSps(packet) || - (h264_idr_only_keyframes_allowed_ && BeginningOfIdr(packet)); -#ifdef RTC_ENABLE_H265 - } else if (packet.codec() == kVideoCodecH265) { - return HasVps(packet); -#endif - } - RTC_DCHECK_NOTREACHED(); - return false; +bool H264PacketBuffer::BeginningOfStream( + const H264PacketBuffer::Packet& packet) const { + return HasSps(packet) || + (idr_only_keyframes_allowed_ && BeginningOfIdr(packet)); } -std::vector> -H26xPacketBuffer::FindFrames(int64_t unwrapped_seq_num) { +std::vector> +H264PacketBuffer::FindFrames(int64_t unwrapped_seq_num) { std::vector> found_frames; Packet* packet = GetPacket(unwrapped_seq_num).get(); @@ -246,17 +223,13 @@ H26xPacketBuffer::FindFrames(int64_t unwrapped_seq_num) { return found_frames; } -bool H26xPacketBuffer::MaybeAssembleFrame( +bool H264PacketBuffer::MaybeAssembleFrame( int64_t start_seq_num_unwrapped, int64_t end_sequence_number_unwrapped, std::vector>& frames) { -#ifdef RTC_ENABLE_H265 - bool has_vps = false; -#endif bool has_sps = false; bool has_pps = false; bool has_idr = false; - bool has_irap = false; int width = -1; int height = -1; @@ -264,44 +237,24 @@ bool H26xPacketBuffer::MaybeAssembleFrame( for (int64_t seq_num = start_seq_num_unwrapped; seq_num <= end_sequence_number_unwrapped; ++seq_num) { const auto& packet = GetPacket(seq_num); - if (packet->codec() == kVideoCodecH264) { - const auto& h264_header = - absl::get(packet->video_header.video_type_header); - for (const auto& nalu : GetNaluInfos(h264_header)) { - has_idr |= nalu.type == H264::NaluType::kIdr; - has_sps |= nalu.type == H264::NaluType::kSps; - has_pps |= nalu.type == H264::NaluType::kPps; - } - if (has_idr) { - if (!h264_idr_only_keyframes_allowed_ && (!has_sps || !has_pps)) { - return false; - } - } -#ifdef RTC_ENABLE_H265 - } else if (packet->codec() == kVideoCodecH265) { - std::vector nalu_indices = H265::FindNaluIndices( - packet->video_payload.cdata(), packet->video_payload.size()); - for (const auto& nalu_index : nalu_indices) { - uint8_t nalu_type = H265::ParseNaluType( - packet->video_payload.cdata()[nalu_index.payload_start_offset]); - has_irap |= (nalu_type >= H265::NaluType::kBlaWLp && - nalu_type <= H265::NaluType::kRsvIrapVcl23); - has_vps |= nalu_type == H265::NaluType::kVps; - has_sps |= nalu_type == H265::NaluType::kSps; - has_pps |= nalu_type == H265::NaluType::kPps; - } - if (has_irap) { - if (!has_vps || !has_sps || !has_pps) { - return false; - } - } -#endif // RTC_ENABLE_H265 + const auto& h264_header = + absl::get(packet->video_header.video_type_header); + for (const auto& nalu : GetNaluInfos(h264_header)) { + has_idr |= nalu.type == H264::NaluType::kIdr; + has_sps |= nalu.type == H264::NaluType::kSps; + has_pps |= nalu.type == H264::NaluType::kPps; } width = std::max(packet->video_header.width, width); height = std::max(packet->video_header.height, height); } + if (has_idr) { + if (!idr_only_keyframes_allowed_ && (!has_sps || !has_pps)) { + return false; + } + } + for (int64_t seq_num = start_seq_num_unwrapped; seq_num <= end_sequence_number_unwrapped; ++seq_num) { auto& packet = GetPacket(seq_num); @@ -317,16 +270,13 @@ bool H26xPacketBuffer::MaybeAssembleFrame( packet->video_header.height = height; } - packet->video_header.frame_type = has_idr || has_irap + packet->video_header.frame_type = has_idr ? VideoFrameType::kVideoFrameKey : VideoFrameType::kVideoFrameDelta; } - // Start code is inserted by depacktizer for H.265. - if (packet->codec() == kVideoCodecH264) { - packet->video_payload = - FixH264VideoPayload(packet->video_payload, packet->video_header); - } + packet->video_payload = + FixVideoPayload(packet->video_payload, packet->video_header); frames.push_back(std::move(packet)); } diff --git a/modules/video_coding/h26x_packet_buffer.h b/modules/video_coding/h264_packet_buffer.h similarity index 73% rename from modules/video_coding/h26x_packet_buffer.h rename to modules/video_coding/h264_packet_buffer.h index 21601562c5..a72c240e82 100644 --- a/modules/video_coding/h26x_packet_buffer.h +++ b/modules/video_coding/h264_packet_buffer.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ -#define MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ +#ifndef MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ +#define MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ #include #include @@ -22,16 +22,15 @@ namespace webrtc { -class H26xPacketBuffer { +class H264PacketBuffer { public: - // The H26xPacketBuffer does the same job as the PacketBuffer but for H264 and - // H265 only. To make it fit in with surronding code the PacketBuffer - // input/output classes are used. + // The H264PacketBuffer does the same job as the PacketBuffer but for H264 + // only. To make it fit in with surronding code the PacketBuffer input/output + // classes are used. using Packet = video_coding::PacketBuffer::Packet; using InsertResult = video_coding::PacketBuffer::InsertResult; - // |h264_idr_only_keyframes_allowed| is ignored if H.265 is used. - explicit H26xPacketBuffer(bool h264_idr_only_keyframes_allowed); + explicit H264PacketBuffer(bool idr_only_keyframes_allowed); ABSL_MUST_USE_RESULT InsertResult InsertPacket(std::unique_ptr packet); @@ -46,7 +45,7 @@ class H26xPacketBuffer { int64_t end_sequence_number_unwrapped, std::vector>& packets); - const bool h264_idr_only_keyframes_allowed_; + const bool idr_only_keyframes_allowed_; std::array, kBufferSize> buffer_; absl::optional last_continuous_unwrapped_seq_num_; SeqNumUnwrapper seq_num_unwrapper_; @@ -54,4 +53,4 @@ class H26xPacketBuffer { } // namespace webrtc -#endif // MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ +#endif // MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ diff --git a/modules/video_coding/h264_packet_buffer_unittest.cc b/modules/video_coding/h264_packet_buffer_unittest.cc new file mode 100644 index 0000000000..4f2331da28 --- /dev/null +++ b/modules/video_coding/h264_packet_buffer_unittest.cc @@ -0,0 +1,778 @@ +/* + * Copyright (c) 2021 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 "modules/video_coding/h264_packet_buffer.h" + +#include +#include +#include +#include +#include + +#include "api/array_view.h" +#include "api/video/render_resolution.h" +#include "common_video/h264/h264_common.h" +#include "rtc_base/system/unused.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +using ::testing::ElementsAreArray; +using ::testing::Eq; +using ::testing::IsEmpty; +using ::testing::SizeIs; + +using H264::NaluType::kAud; +using H264::NaluType::kFuA; +using H264::NaluType::kIdr; +using H264::NaluType::kPps; +using H264::NaluType::kSlice; +using H264::NaluType::kSps; +using H264::NaluType::kStapA; + +constexpr int kBufferSize = 2048; + +std::vector StartCode() { + return {0, 0, 0, 1}; +} + +NaluInfo MakeNaluInfo(uint8_t type) { + NaluInfo res; + res.type = type; + res.sps_id = -1; + res.pps_id = -1; + return res; +} + +class Packet { + public: + explicit Packet(H264PacketizationTypes type); + + Packet& Idr(std::vector payload = {9, 9, 9}); + Packet& Slice(std::vector payload = {9, 9, 9}); + Packet& Sps(std::vector payload = {9, 9, 9}); + Packet& SpsWithResolution(RenderResolution resolution, + std::vector payload = {9, 9, 9}); + Packet& Pps(std::vector payload = {9, 9, 9}); + Packet& Aud(); + Packet& Marker(); + Packet& AsFirstFragment(); + Packet& Time(uint32_t rtp_timestamp); + Packet& SeqNum(uint16_t rtp_seq_num); + + std::unique_ptr Build(); + + private: + rtc::CopyOnWriteBuffer BuildFuaPayload() const; + rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const; + rtc::CopyOnWriteBuffer BuildStapAPayload() const; + + RTPVideoHeaderH264& H264Header() { + return absl::get(video_header_.video_type_header); + } + const RTPVideoHeaderH264& H264Header() const { + return absl::get(video_header_.video_type_header); + } + + H264PacketizationTypes type_; + RTPVideoHeader video_header_; + bool first_fragment_ = false; + bool marker_bit_ = false; + uint32_t rtp_timestamp_ = 0; + uint16_t rtp_seq_num_ = 0; + std::vector> nalu_payloads_; +}; + +Packet::Packet(H264PacketizationTypes type) : type_(type) { + video_header_.video_type_header.emplace(); +} + +Packet& Packet::Idr(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kIdr); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +Packet& Packet::Slice(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSlice); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +Packet& Packet::Sps(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +Packet& Packet::SpsWithResolution(RenderResolution resolution, + std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); + video_header_.width = resolution.Width(); + video_header_.height = resolution.Height(); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +Packet& Packet::Pps(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kPps); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +Packet& Packet::Aud() { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kAud); + nalu_payloads_.push_back({}); + return *this; +} + +Packet& Packet::Marker() { + marker_bit_ = true; + return *this; +} + +Packet& Packet::AsFirstFragment() { + first_fragment_ = true; + return *this; +} + +Packet& Packet::Time(uint32_t rtp_timestamp) { + rtp_timestamp_ = rtp_timestamp; + return *this; +} + +Packet& Packet::SeqNum(uint16_t rtp_seq_num) { + rtp_seq_num_ = rtp_seq_num; + return *this; +} + +std::unique_ptr Packet::Build() { + auto res = std::make_unique(); + + auto& h264_header = H264Header(); + switch (type_) { + case kH264FuA: { + RTC_CHECK_EQ(h264_header.nalus_length, 1); + res->video_payload = BuildFuaPayload(); + break; + } + case kH264SingleNalu: { + RTC_CHECK_EQ(h264_header.nalus_length, 1); + res->video_payload = BuildSingleNaluPayload(); + break; + } + case kH264StapA: { + RTC_CHECK_GT(h264_header.nalus_length, 1); + RTC_CHECK_LE(h264_header.nalus_length, kMaxNalusPerPacket); + res->video_payload = BuildStapAPayload(); + break; + } + } + + if (type_ == kH264FuA && !first_fragment_) { + h264_header.nalus_length = 0; + } + + h264_header.packetization_type = type_; + res->marker_bit = marker_bit_; + res->video_header = video_header_; + res->timestamp = rtp_timestamp_; + res->seq_num = rtp_seq_num_; + res->video_header.codec = kVideoCodecH264; + + return res; +} + +rtc::CopyOnWriteBuffer Packet::BuildFuaPayload() const { + return rtc::CopyOnWriteBuffer(nalu_payloads_[0]); +} + +rtc::CopyOnWriteBuffer Packet::BuildSingleNaluPayload() const { + rtc::CopyOnWriteBuffer res; + auto& h264_header = H264Header(); + res.AppendData(&h264_header.nalus[0].type, 1); + res.AppendData(nalu_payloads_[0]); + return res; +} + +rtc::CopyOnWriteBuffer Packet::BuildStapAPayload() const { + rtc::CopyOnWriteBuffer res; + + const uint8_t indicator = H264::NaluType::kStapA; + res.AppendData(&indicator, 1); + + auto& h264_header = H264Header(); + for (size_t i = 0; i < h264_header.nalus_length; ++i) { + // The two first bytes indicates the nalu segment size. + uint8_t length_as_array[2] = { + 0, static_cast(nalu_payloads_[i].size() + 1)}; + res.AppendData(length_as_array); + + res.AppendData(&h264_header.nalus[i].type, 1); + res.AppendData(nalu_payloads_[i]); + } + return res; +} + +rtc::ArrayView PacketPayload( + const std::unique_ptr& packet) { + return packet->video_payload; +} + +std::vector FlatVector( + const std::vector>& elems) { + std::vector res; + for (const auto& elem : elems) { + res.insert(res.end(), elem.begin(), elem.end()); + } + return res; +} + +TEST(H264PacketBufferTest, IdrIsKeyframe) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true); + + EXPECT_THAT( + packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build()) + .packets, + SizeIs(1)); +} + +TEST(H264PacketBufferTest, IdrIsNotKeyframe) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H264PacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true); + + // Not marked as the first fragment + EXPECT_THAT( + packet_buffer + .InsertPacket(Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket( + Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + IsEmpty()); + + // Marked as first fragment + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264FuA) + .Idr() + .SeqNum(2) + .Time(1) + .AsFirstFragment() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket( + Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build()) + .packets, + SizeIs(2)); +} + +TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket( + Packet(kH264SingleNalu).Idr().SeqNum(2).Time(0).Marker().Build()) + .packets, + SizeIs(3)); +} + +TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket( + Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket( + Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeStapA) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeStapA) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + Packet(kH264StapA).Pps().Idr().SeqNum(0).Time(0).Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeStapA) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + Packet(kH264StapA).Sps().Idr().SeqNum(2).Time(2).Marker().Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(3) + .Time(3) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H264PacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build())); + + EXPECT_THAT(packet_buffer + .InsertPacket( + Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build()) + .packets, + SizeIs(2)); +} + +TEST(H264PacketBufferTest, InsertingMidFuaCompletesFrame) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264FuA).Slice().SeqNum(1).Time(1).AsFirstFragment().Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build()) + .packets, + SizeIs(3)); +} + +TEST(H264PacketBufferTest, SeqNumJumpDoesNotCompleteFrame) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + EXPECT_THAT( + packet_buffer + .InsertPacket(Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build()) + .packets, + IsEmpty()); + + // Add `kBufferSize` to make the index of the sequence number wrap and end up + // where the packet with sequence number 2 would have ended up. + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264FuA) + .Slice() + .SeqNum(2 + kBufferSize) + .Time(3) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H264PacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264SingleNalu) + .Slice() + .SeqNum(1) + .Time(1) + .Marker() + .Build()) + .packets, + IsEmpty()); + + // New keyframe, preceedes packet with sequence number 1 in the buffer. + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H264PacketBufferTest, OldPacketsDontBlockNewPackets) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 1) + .Time(kBufferSize + 1) + .AsFirstFragment() + .Build())); + + RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 3) + .Time(kBufferSize + 1) + .Marker() + .Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 2) + .Time(kBufferSize + 1) + .Build()) + .packets, + SizeIs(3)); +} + +TEST(H264PacketBufferTest, OldPacketDoesntCompleteFrame) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 3) + .Time(kBufferSize + 1) + .Marker() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 1) + .Time(kBufferSize + 1) + .AsFirstFragment() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H264PacketBufferTest, FrameBoundariesAreSet) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + auto key = packet_buffer.InsertPacket( + Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build()); + + ASSERT_THAT(key.packets, SizeIs(1)); + EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame); + EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build())); + auto delta = packet_buffer.InsertPacket( + Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build()); + + ASSERT_THAT(delta.packets, SizeIs(3)); + EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame); + EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame); + + EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame); + EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame); + + EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame); + EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame); +} + +TEST(H264PacketBufferTest, ResolutionSetOnFirstPacket) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); + auto res = packet_buffer.InsertPacket(Packet(kH264StapA) + .SpsWithResolution({320, 240}) + .Pps() + .Idr() + .SeqNum(2) + .Time(1) + .Marker() + .Build()); + + ASSERT_THAT(res.packets, SizeIs(2)); + EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); + EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); +} + +TEST(H264PacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); + auto key = packet_buffer.InsertPacket( + Packet(kH264StapA).Sps().Pps().Idr().SeqNum(2).Time(1).Marker().Build()); + + auto delta = packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build()); + + ASSERT_THAT(key.packets, SizeIs(2)); + EXPECT_THAT(key.packets[0]->video_header.frame_type, + Eq(VideoFrameType::kVideoFrameKey)); + ASSERT_THAT(delta.packets, SizeIs(1)); + EXPECT_THAT(delta.packets[0]->video_header.frame_type, + Eq(VideoFrameType::kVideoFrameDelta)); +} + +TEST(H264PacketBufferTest, RtpSeqNumWrap) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())); + EXPECT_THAT(packet_buffer + .InsertPacket( + Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + SizeIs(3)); +} + +TEST(H264PacketBufferTest, StapAFixedBitstream) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + auto packets = packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps({1, 2, 3}) + .Pps({4, 5, 6}) + .Idr({7, 8, 9}) + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(1)); + EXPECT_THAT(PacketPayload(packets[0]), + ElementsAreArray(FlatVector({StartCode(), + {kSps, 1, 2, 3}, + StartCode(), + {kPps, 4, 5, 6}, + StartCode(), + {kIdr, 7, 8, 9}}))); +} + +TEST(H264PacketBufferTest, SingleNaluFixedBitstream) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build())); + auto packets = packet_buffer + .InsertPacket(Packet(kH264SingleNalu) + .Idr({7, 8, 9}) + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(3)); + EXPECT_THAT(PacketPayload(packets[0]), + ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}}))); + EXPECT_THAT(PacketPayload(packets[1]), + ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}}))); + EXPECT_THAT(PacketPayload(packets[2]), + ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}}))); +} + +TEST(H264PacketBufferTest, StapaAndFuaFixedBitstream) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264StapA) + .Sps({1, 2, 3}) + .Pps({4, 5, 6}) + .SeqNum(0) + .Time(0) + .Build())); + RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) + .Idr({8, 8, 8}) + .SeqNum(1) + .Time(0) + .AsFirstFragment() + .Build())); + auto packets = packet_buffer + .InsertPacket(Packet(kH264FuA) + .Idr({9, 9, 9}) + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(3)); + EXPECT_THAT( + PacketPayload(packets[0]), + ElementsAreArray(FlatVector( + {StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}}))); + EXPECT_THAT(PacketPayload(packets[1]), + ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}}))); + // Third is a continuation of second, so only the payload is expected. + EXPECT_THAT(PacketPayload(packets[2]), + ElementsAreArray(FlatVector({{9, 9, 9}}))); +} + +TEST(H264PacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + for (int i = 0; i < kBufferSize; ++i) { + EXPECT_THAT( + packet_buffer + .InsertPacket( + Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build()) + .packets, + IsEmpty()); + } + + EXPECT_THAT(packet_buffer + .InsertPacket(Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(1) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H264PacketBufferTest, TooManyNalusInPacket) { + H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + std::unique_ptr packet( + Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build()); + auto& h264_header = + absl::get(packet->video_header.video_type_header); + h264_header.nalus_length = kMaxNalusPerPacket + 1; + + EXPECT_THAT(packet_buffer.InsertPacket(std::move(packet)).packets, IsEmpty()); +} + +} // namespace +} // namespace webrtc diff --git a/modules/video_coding/h26x_packet_buffer_unittest.cc b/modules/video_coding/h26x_packet_buffer_unittest.cc deleted file mode 100644 index 4a17b4d4cf..0000000000 --- a/modules/video_coding/h26x_packet_buffer_unittest.cc +++ /dev/null @@ -1,1056 +0,0 @@ -/* - * Copyright (c) 2021 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 "modules/video_coding/h26x_packet_buffer.h" - -#include -#include -#include -#include -#include - -#include "api/array_view.h" -#include "api/video/render_resolution.h" -#include "common_video/h264/h264_common.h" -#include "common_video/h265/h265_common.h" -#include "rtc_base/system/unused.h" -#include "test/gmock.h" -#include "test/gtest.h" - -namespace webrtc { -namespace { - -using ::testing::ElementsAreArray; -using ::testing::Eq; -using ::testing::IsEmpty; -using ::testing::SizeIs; - -using H264::NaluType::kAud; -using H264::NaluType::kFuA; -using H264::NaluType::kIdr; -using H264::NaluType::kPps; -using H264::NaluType::kSlice; -using H264::NaluType::kSps; -using H264::NaluType::kStapA; - -constexpr int kBufferSize = 2048; - -std::vector StartCode() { - return {0, 0, 0, 1}; -} - -NaluInfo MakeNaluInfo(uint8_t type) { - NaluInfo res; - res.type = type; - res.sps_id = -1; - res.pps_id = -1; - return res; -} - -class H264Packet { - public: - explicit H264Packet(H264PacketizationTypes type); - - H264Packet& Idr(std::vector payload = {9, 9, 9}); - H264Packet& Slice(std::vector payload = {9, 9, 9}); - H264Packet& Sps(std::vector payload = {9, 9, 9}); - H264Packet& SpsWithResolution(RenderResolution resolution, - std::vector payload = {9, 9, 9}); - H264Packet& Pps(std::vector payload = {9, 9, 9}); - H264Packet& Aud(); - H264Packet& Marker(); - H264Packet& AsFirstFragment(); - H264Packet& Time(uint32_t rtp_timestamp); - H264Packet& SeqNum(uint16_t rtp_seq_num); - - std::unique_ptr Build(); - - private: - rtc::CopyOnWriteBuffer BuildFuaPayload() const; - rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const; - rtc::CopyOnWriteBuffer BuildStapAPayload() const; - - RTPVideoHeaderH264& H264Header() { - return absl::get(video_header_.video_type_header); - } - const RTPVideoHeaderH264& H264Header() const { - return absl::get(video_header_.video_type_header); - } - - H264PacketizationTypes type_; - RTPVideoHeader video_header_; - bool first_fragment_ = false; - bool marker_bit_ = false; - uint32_t rtp_timestamp_ = 0; - uint16_t rtp_seq_num_ = 0; - std::vector> nalu_payloads_; -}; - -H264Packet::H264Packet(H264PacketizationTypes type) : type_(type) { - video_header_.video_type_header.emplace(); -} - -H264Packet& H264Packet::Idr(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kIdr); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -H264Packet& H264Packet::Slice(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSlice); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -H264Packet& H264Packet::Sps(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -H264Packet& H264Packet::SpsWithResolution(RenderResolution resolution, - std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); - video_header_.width = resolution.Width(); - video_header_.height = resolution.Height(); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -H264Packet& H264Packet::Pps(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kPps); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -H264Packet& H264Packet::Aud() { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kAud); - nalu_payloads_.push_back({}); - return *this; -} - -H264Packet& H264Packet::Marker() { - marker_bit_ = true; - return *this; -} - -H264Packet& H264Packet::AsFirstFragment() { - first_fragment_ = true; - return *this; -} - -H264Packet& H264Packet::Time(uint32_t rtp_timestamp) { - rtp_timestamp_ = rtp_timestamp; - return *this; -} - -H264Packet& H264Packet::SeqNum(uint16_t rtp_seq_num) { - rtp_seq_num_ = rtp_seq_num; - return *this; -} - -std::unique_ptr H264Packet::Build() { - auto res = std::make_unique(); - - auto& h264_header = H264Header(); - switch (type_) { - case kH264FuA: { - RTC_CHECK_EQ(h264_header.nalus_length, 1); - res->video_payload = BuildFuaPayload(); - break; - } - case kH264SingleNalu: { - RTC_CHECK_EQ(h264_header.nalus_length, 1); - res->video_payload = BuildSingleNaluPayload(); - break; - } - case kH264StapA: { - RTC_CHECK_GT(h264_header.nalus_length, 1); - RTC_CHECK_LE(h264_header.nalus_length, kMaxNalusPerPacket); - res->video_payload = BuildStapAPayload(); - break; - } - } - - if (type_ == kH264FuA && !first_fragment_) { - h264_header.nalus_length = 0; - } - - h264_header.packetization_type = type_; - res->marker_bit = marker_bit_; - res->video_header = video_header_; - res->timestamp = rtp_timestamp_; - res->seq_num = rtp_seq_num_; - res->video_header.codec = kVideoCodecH264; - - return res; -} - -rtc::CopyOnWriteBuffer H264Packet::BuildFuaPayload() const { - return rtc::CopyOnWriteBuffer(nalu_payloads_[0]); -} - -rtc::CopyOnWriteBuffer H264Packet::BuildSingleNaluPayload() const { - rtc::CopyOnWriteBuffer res; - auto& h264_header = H264Header(); - res.AppendData(&h264_header.nalus[0].type, 1); - res.AppendData(nalu_payloads_[0]); - return res; -} - -rtc::CopyOnWriteBuffer H264Packet::BuildStapAPayload() const { - rtc::CopyOnWriteBuffer res; - - const uint8_t indicator = H264::NaluType::kStapA; - res.AppendData(&indicator, 1); - - auto& h264_header = H264Header(); - for (size_t i = 0; i < h264_header.nalus_length; ++i) { - // The two first bytes indicates the nalu segment size. - uint8_t length_as_array[2] = { - 0, static_cast(nalu_payloads_[i].size() + 1)}; - res.AppendData(length_as_array); - - res.AppendData(&h264_header.nalus[i].type, 1); - res.AppendData(nalu_payloads_[i]); - } - return res; -} - -#ifdef RTC_ENABLE_H265 -class H265Packet { - public: - H265Packet() = default; - - H265Packet& Idr(std::vector payload = {9, 9, 9}); - H265Packet& Slice(H265::NaluType type, - std::vector payload = {9, 9, 9}); - H265Packet& Vps(std::vector payload = {9, 9, 9}); - H265Packet& Sps(std::vector payload = {9, 9, 9}); - H265Packet& SpsWithResolution(RenderResolution resolution, - std::vector payload = {9, 9, 9}); - H265Packet& Pps(std::vector payload = {9, 9, 9}); - H265Packet& Aud(); - H265Packet& Marker(); - H265Packet& AsFirstFragment(); - H265Packet& Time(uint32_t rtp_timestamp); - H265Packet& SeqNum(uint16_t rtp_seq_num); - - std::unique_ptr Build(); - - private: - H265Packet& StartCode(); - - RTPVideoHeader video_header_; - bool first_fragment_ = false; - bool marker_bit_ = false; - uint32_t rtp_timestamp_ = 0; - uint16_t rtp_seq_num_ = 0; - std::vector> nalu_payloads_; -}; - -H265Packet& H265Packet::Idr(std::vector payload) { - return Slice(H265::NaluType::kIdrNLp, std::move(payload)); -} - -H265Packet& H265Packet::Slice(H265::NaluType type, - std::vector payload) { - StartCode(); - // Nalu header. Assume layer ID is 0 and TID is 2. - nalu_payloads_.push_back({static_cast(type << 1), 0x02}); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -H265Packet& H265Packet::Vps(std::vector payload) { - return Slice(H265::NaluType::kVps, std::move(payload)); -} - -H265Packet& H265Packet::Sps(std::vector payload) { - return Slice(H265::NaluType::kSps, std::move(payload)); -} - -H265Packet& H265Packet::SpsWithResolution(RenderResolution resolution, - std::vector payload) { - video_header_.width = resolution.Width(); - video_header_.height = resolution.Height(); - return Sps(std::move(payload)); -} - -H265Packet& H265Packet::Pps(std::vector payload) { - return Slice(H265::NaluType::kPps, std::move(payload)); -} - -H265Packet& H265Packet::Aud() { - return Slice(H265::NaluType::kAud, {}); -} - -H265Packet& H265Packet::Marker() { - marker_bit_ = true; - return *this; -} - -H265Packet& H265Packet::StartCode() { - nalu_payloads_.push_back({0x00, 0x00, 0x00, 0x01}); - return *this; -} - -std::unique_ptr H265Packet::Build() { - auto res = std::make_unique(); - res->marker_bit = marker_bit_; - res->video_header = video_header_; - res->timestamp = rtp_timestamp_; - res->seq_num = rtp_seq_num_; - res->video_header.codec = kVideoCodecH265; - res->video_payload = rtc::CopyOnWriteBuffer(); - for (const auto& payload : nalu_payloads_) { - res->video_payload.AppendData(payload); - } - - return res; -} - -H265Packet& H265Packet::AsFirstFragment() { - first_fragment_ = true; - return *this; -} - -H265Packet& H265Packet::Time(uint32_t rtp_timestamp) { - rtp_timestamp_ = rtp_timestamp; - return *this; -} - -H265Packet& H265Packet::SeqNum(uint16_t rtp_seq_num) { - rtp_seq_num_ = rtp_seq_num; - return *this; -} -#endif - -rtc::ArrayView PacketPayload( - const std::unique_ptr& packet) { - return packet->video_payload; -} - -std::vector FlatVector( - const std::vector>& elems) { - std::vector res; - for (const auto& elem : elems) { - res.insert(res.end(), elem.begin(), elem.end()); - } - return res; -} - -TEST(H26xPacketBufferTest, IdrIsKeyframe) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); - - EXPECT_THAT( - packet_buffer - .InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build()) - .packets, - SizeIs(1)); -} - -TEST(H26xPacketBufferTest, IdrIsNotKeyframe) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer - .InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); - - // Not marked as the first fragment - EXPECT_THAT( - packet_buffer - .InsertPacket(H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()) - .packets, - IsEmpty()); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - IsEmpty()); - - // Marked as first fragment - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264FuA) - .Idr() - .SeqNum(2) - .Time(1) - .AsFirstFragment() - .Build()) - .packets, - IsEmpty()); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - H264Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build()) - .packets, - SizeIs(2)); -} - -TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build())); - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264SingleNalu) - .Idr() - .SeqNum(2) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(3)); -} - -TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build())); - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264SingleNalu) - .Idr() - .SeqNum(1) - .Time(0) - .Marker() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264SingleNalu) - .Idr() - .SeqNum(1) - .Time(0) - .Marker() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeStapA) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeStapA) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeStapA) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Idr() - .SeqNum(2) - .Time(2) - .Marker() - .Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(3) - .Time(3) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H26xPacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build())); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - H264Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build()) - .packets, - SizeIs(2)); -} - -TEST(H26xPacketBufferTest, InsertingMidFuaCompletesFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) - .Slice() - .SeqNum(1) - .Time(1) - .AsFirstFragment() - .Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build()) - .packets, - SizeIs(3)); -} - -TEST(H26xPacketBufferTest, SeqNumJumpDoesNotCompleteFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - EXPECT_THAT( - packet_buffer - .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build()) - .packets, - IsEmpty()); - - // Add `kBufferSize` to make the index of the sequence number wrap and end up - // where the packet with sequence number 2 would have ended up. - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264FuA) - .Slice() - .SeqNum(2 + kBufferSize) - .Time(3) - .Marker() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264SingleNalu) - .Slice() - .SeqNum(1) - .Time(1) - .Marker() - .Build()) - .packets, - IsEmpty()); - - // New keyframe, preceedes packet with sequence number 1 in the buffer. - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H26xPacketBufferTest, OldPacketsDontBlockNewPackets) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 1) - .Time(kBufferSize + 1) - .AsFirstFragment() - .Build())); - - RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 3) - .Time(kBufferSize + 1) - .Marker() - .Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 2) - .Time(kBufferSize + 1) - .Build()) - .packets, - SizeIs(3)); -} - -TEST(H26xPacketBufferTest, OldPacketDoesntCompleteFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 3) - .Time(kBufferSize + 1) - .Marker() - .Build()) - .packets, - IsEmpty()); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 1) - .Time(kBufferSize + 1) - .AsFirstFragment() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, FrameBoundariesAreSet) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(1) - .Time(1) - .Marker() - .Build()); - - ASSERT_THAT(key.packets, SizeIs(1)); - EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame); - EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build())); - auto delta = packet_buffer.InsertPacket( - H264Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build()); - - ASSERT_THAT(delta.packets, SizeIs(3)); - EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame); - EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame); - - EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame); - EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame); - - EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame); - EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame); -} - -TEST(H26xPacketBufferTest, ResolutionSetOnFirstPacket) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); - auto res = packet_buffer.InsertPacket(H264Packet(kH264StapA) - .SpsWithResolution({320, 240}) - .Pps() - .Idr() - .SeqNum(2) - .Time(1) - .Marker() - .Build()); - - ASSERT_THAT(res.packets, SizeIs(2)); - EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); - EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); -} - -TEST(H26xPacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); - auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(2) - .Time(1) - .Marker() - .Build()); - - auto delta = packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build()); - - ASSERT_THAT(key.packets, SizeIs(2)); - EXPECT_THAT(key.packets[0]->video_header.frame_type, - Eq(VideoFrameType::kVideoFrameKey)); - ASSERT_THAT(delta.packets, SizeIs(1)); - EXPECT_THAT(delta.packets[0]->video_header.frame_type, - Eq(VideoFrameType::kVideoFrameDelta)); -} - -TEST(H26xPacketBufferTest, RtpSeqNumWrap) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket( - H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - SizeIs(3)); -} - -TEST(H26xPacketBufferTest, StapAFixedBitstream) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - auto packets = packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps({1, 2, 3}) - .Pps({4, 5, 6}) - .Idr({7, 8, 9}) - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(1)); - EXPECT_THAT(PacketPayload(packets[0]), - ElementsAreArray(FlatVector({StartCode(), - {kSps, 1, 2, 3}, - StartCode(), - {kPps, 4, 5, 6}, - StartCode(), - {kIdr, 7, 8, 9}}))); -} - -TEST(H26xPacketBufferTest, SingleNaluFixedBitstream) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - H264Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build())); - auto packets = packet_buffer - .InsertPacket(H264Packet(kH264SingleNalu) - .Idr({7, 8, 9}) - .SeqNum(2) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(3)); - EXPECT_THAT(PacketPayload(packets[0]), - ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}}))); - EXPECT_THAT(PacketPayload(packets[1]), - ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}}))); - EXPECT_THAT(PacketPayload(packets[2]), - ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}}))); -} - -TEST(H26xPacketBufferTest, StapaAndFuaFixedBitstream) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264StapA) - .Sps({1, 2, 3}) - .Pps({4, 5, 6}) - .SeqNum(0) - .Time(0) - .Build())); - RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) - .Idr({8, 8, 8}) - .SeqNum(1) - .Time(0) - .AsFirstFragment() - .Build())); - auto packets = packet_buffer - .InsertPacket(H264Packet(kH264FuA) - .Idr({9, 9, 9}) - .SeqNum(2) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(3)); - EXPECT_THAT( - PacketPayload(packets[0]), - ElementsAreArray(FlatVector( - {StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}}))); - EXPECT_THAT(PacketPayload(packets[1]), - ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}}))); - // Third is a continuation of second, so only the payload is expected. - EXPECT_THAT(PacketPayload(packets[2]), - ElementsAreArray(FlatVector({{9, 9, 9}}))); -} - -TEST(H26xPacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - for (int i = 0; i < kBufferSize; ++i) { - EXPECT_THAT( - packet_buffer - .InsertPacket( - H264Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build()) - .packets, - IsEmpty()); - } - - EXPECT_THAT(packet_buffer - .InsertPacket(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(1) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H26xPacketBufferTest, TooManyNalusInPacket) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - std::unique_ptr packet(H264Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(1) - .Time(1) - .Marker() - .Build()); - auto& h264_header = - absl::get(packet->video_header.video_type_header); - h264_header.nalus_length = kMaxNalusPerPacket + 1; - - EXPECT_THAT(packet_buffer.InsertPacket(std::move(packet)).packets, IsEmpty()); -} - -#ifdef RTC_ENABLE_H265 -TEST(H26xPacketBufferTest, H265VpsSpsPpsIdrIsKeyframe) { - H26xPacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer - .InsertPacket(H265Packet().Vps().Sps().Pps().Idr().Marker().Build()) - .packets, - SizeIs(1)); -} - -TEST(H26xPacketBufferTest, H265IrapIsNotKeyframe) { - std::vector irap_types = { - H265::NaluType::kBlaWLp, H265::NaluType::kBlaWRadl, - H265::NaluType::kBlaNLp, H265::NaluType::kIdrWRadl, - H265::NaluType::kIdrNLp, H265::NaluType::kCra, - H265::NaluType::kRsvIrapVcl23}; - for (const H265::NaluType type : irap_types) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer.InsertPacket(H265Packet().Slice(type).Marker().Build()) - .packets, - IsEmpty()); - } -} - -TEST(H26xPacketBufferTest, H265IdrIsNotKeyFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer.InsertPacket(H265Packet().Idr().Marker().Build()).packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, H265SpsPpsIdrIsNotKeyFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H265Packet().Sps().Pps().Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, H265VpsPpsIdrIsNotKeyFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H265Packet().Vps().Pps().Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, H265VpsSpsIdrIsNotKeyFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(H265Packet().Vps().Sps().Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, H265VpsIdrIsNotKeyFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer.InsertPacket(H265Packet().Vps().Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, H265SpsIdrIsNotKeyFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer.InsertPacket(H265Packet().Sps().Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, H265PpsIdrIsNotKeyFrame) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer.InsertPacket(H265Packet().Pps().Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H26xPacketBufferTest, H265ResolutionSetOnSpsPacket) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED( - packet_buffer.InsertPacket(H265Packet().Aud().SeqNum(1).Time(1).Build())); - auto res = packet_buffer.InsertPacket(H265Packet() - .Vps() - .SpsWithResolution({320, 240}) - .Pps() - .Idr() - .SeqNum(2) - .Time(1) - .Marker() - .Build()); - - ASSERT_THAT(res.packets, SizeIs(2)); - EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); - EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); -} - -TEST(H26xPacketBufferTest, H265InsertingVpsSpsPpsLastCompletesKeyframe) { - H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - H265Packet().Idr().SeqNum(2).Time(1).Marker().Build())); - - EXPECT_THAT(packet_buffer - .InsertPacket( - H265Packet().Vps().Sps().Pps().SeqNum(1).Time(1).Build()) - .packets, - SizeIs(2)); -} -#endif // RTC_ENABLE_H265 - -} // namespace -} // namespace webrtc From 6a8236617dd9416ea0fe7767166cc8e8c729d5e6 Mon Sep 17 00:00:00 2001 From: Harald Alvestrand Date: Wed, 14 Feb 2024 18:08:47 +0000 Subject: [PATCH 147/170] Reject SDP with duplicate msid lines This is an obscure error that was found by a fuzzer. Bug: webrtc:15845 Change-Id: I3509fa264a3af6f0f5e8e6b75a8b7dcd8fb0da1a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339681 Reviewed-by: Florent Castelli Commit-Queue: Harald Alvestrand Cr-Commit-Position: refs/heads/main@{#41743} --- pc/webrtc_sdp.cc | 21 +++++++++++++++++++++ pc/webrtc_sdp_unittest.cc | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc index ea433583ab..1069a18391 100644 --- a/pc/webrtc_sdp.cc +++ b/pc/webrtc_sdp.cc @@ -2341,6 +2341,7 @@ static bool ParseMsidAttribute(absl::string_view line, // Note that JSEP stipulates not sending msid-appdata so // a=msid: // is supported for backward compability reasons only. + // RFC 8830 section 2 states that duplicate a=msid:stream track is illegal. std::vector fields; size_t num_fields = rtc::tokenize(line.substr(kLinePrefixLength), kSdpDelimiterSpaceChar, &fields); @@ -2670,6 +2671,21 @@ static std::unique_ptr ParseContentDescription( return media_desc; } +bool HasDuplicateMsidLines(cricket::SessionDescription* desc) { + std::set> seen_msids; + for (const cricket::ContentInfo& content : desc->contents()) { + for (const cricket::StreamParams& stream : + content.media_description()->streams()) { + auto msid = std::pair(stream.first_stream_id(), stream.id); + if (seen_msids.find(msid) != seen_msids.end()) { + return true; + } + seen_msids.insert(std::move(msid)); + } + } + return false; +} + bool ParseMediaDescription( absl::string_view message, const TransportDescription& session_td, @@ -2852,6 +2868,11 @@ bool ParseMediaDescription( // Create TransportInfo with the media level "ice-pwd" and "ice-ufrag". desc->AddTransportInfo(TransportInfo(content_name, transport)); } + // Apply whole-description sanity checks + if (HasDuplicateMsidLines(desc)) { + ParseFailed(message, *pos, "Duplicate a=msid lines detected", error); + return false; + } desc->set_msid_signaling(msid_signaling); diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc index a31aa2adef..999f0b6b26 100644 --- a/pc/webrtc_sdp_unittest.cc +++ b/pc/webrtc_sdp_unittest.cc @@ -4271,6 +4271,27 @@ TEST_F(WebRtcSdpTest, DeserializeMsidAttributeWithMissingStreamId) { EXPECT_FALSE(SdpDeserialize(sdp, &jdesc_output)); } +TEST_F(WebRtcSdpTest, DeserializeMsidAttributeWithDuplicateStreamIdAndTrackId) { + std::string sdp = + "v=0\r\n" + "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n" + "s=-\r\n" + "t=0 0\r\n" + "m=audio 9 RTP/SAVPF 111\r\n" + "a=mid:0\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtpmap:111 opus/48000/2\r\n" + "a=msid:stream_id track_id\r\n" + "m=audio 9 RTP/SAVPF 111\r\n" + "a=mid:1\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=rtpmap:111 opus/48000/2\r\n" + "a=msid:stream_id track_id\r\n"; + + JsepSessionDescription jdesc_output(kDummyType); + EXPECT_FALSE(SdpDeserialize(sdp, &jdesc_output)); +} + // Tests that if both session-level address and media-level address exist, use // the media-level address. TEST_F(WebRtcSdpTest, ParseConnectionData) { From 45242adc4cbda3e56d949d92727122abaa3d6fd0 Mon Sep 17 00:00:00 2001 From: Per K Date: Thu, 15 Feb 2024 11:28:23 +0100 Subject: [PATCH 148/170] Add field trial property alloc_current_bwe_limit The new field trial can be used to ensure probes are limited by the current BWE and does not automatically send a probe at the new max rate. Also removes unused FieldTrialFlag allocation_allow_further_probing; FieldTrialParameter allocation_probe_max; Bug: webrtc:14928 Change-Id: I0d5c350c0231ca0600033ad8211dca0574104201 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339840 Commit-Queue: Per Kjellander Reviewed-by: Diep Bui Cr-Commit-Position: refs/heads/main@{#41744} --- .../goog_cc/probe_controller.cc | 31 ++++++++++------ .../goog_cc/probe_controller.h | 3 +- .../goog_cc/probe_controller_unittest.cc | 36 +++++++++++++++++++ 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc index 32b1b93c0b..31727051a8 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.cc +++ b/modules/congestion_controller/goog_cc/probe_controller.cc @@ -105,8 +105,7 @@ ProbeControllerConfig::ProbeControllerConfig( probe_on_max_allocated_bitrate_change("probe_max_allocation", true), first_allocation_probe_scale("alloc_p1", 1), second_allocation_probe_scale("alloc_p2", 2), - allocation_allow_further_probing("alloc_probe_further", false), - allocation_probe_max("alloc_probe_max", DataRate::PlusInfinity()), + allocation_probe_limit_by_current_scale("alloc_current_bwe_limit"), min_probe_packets_sent("min_probe_packets_sent", 5), min_probe_duration("min_probe_duration", TimeDelta::Millis(15)), loss_limited_probe_scale("loss_limited_scale", 1.5), @@ -118,7 +117,7 @@ ProbeControllerConfig::ProbeControllerConfig( &further_exponential_probe_scale, &further_probe_threshold, &alr_probing_interval, &alr_probe_scale, &probe_on_max_allocated_bitrate_change, &first_allocation_probe_scale, - &second_allocation_probe_scale, &allocation_allow_further_probing, + &second_allocation_probe_scale, &allocation_probe_limit_by_current_scale, &min_probe_duration, &network_state_estimate_probing_interval, &probe_if_estimate_lower_than_network_state_estimate_ratio, &estimate_lower_than_network_state_estimate_probing_interval, @@ -138,7 +137,7 @@ ProbeControllerConfig::ProbeControllerConfig( key_value_config->Lookup("WebRTC-Bwe-AlrProbing")); ParseFieldTrial( {&first_allocation_probe_scale, &second_allocation_probe_scale, - &allocation_allow_further_probing, &allocation_probe_max}, + &allocation_probe_limit_by_current_scale}, key_value_config->Lookup("WebRTC-Bwe-AllocationProbing")); ParseFieldTrial({&min_probe_packets_sent, &min_probe_duration}, key_value_config->Lookup("WebRTC-Bwe-ProbingBehavior")); @@ -220,19 +219,31 @@ std::vector ProbeController::OnMaxTotalAllocatedBitrate( DataRate first_probe_rate = max_total_allocated_bitrate * config_.first_allocation_probe_scale.Value(); - DataRate probe_cap = config_.allocation_probe_max.Get(); - first_probe_rate = std::min(first_probe_rate, probe_cap); + DataRate current_bwe_limit = + !config_.allocation_probe_limit_by_current_scale + ? DataRate::PlusInfinity() + : estimated_bitrate_ * + config_.allocation_probe_limit_by_current_scale.Value(); + bool limited_by_current_bwe = current_bwe_limit < first_probe_rate; + if (limited_by_current_bwe) { + first_probe_rate = current_bwe_limit; + } + std::vector probes = {first_probe_rate}; - if (config_.second_allocation_probe_scale) { + if (!limited_by_current_bwe && config_.second_allocation_probe_scale) { DataRate second_probe_rate = max_total_allocated_bitrate * config_.second_allocation_probe_scale.Value(); - second_probe_rate = std::min(second_probe_rate, probe_cap); + limited_by_current_bwe = current_bwe_limit < second_probe_rate; + if (limited_by_current_bwe) { + second_probe_rate = current_bwe_limit; + } if (second_probe_rate > first_probe_rate) probes.push_back(second_probe_rate); } - return InitiateProbing(at_time, probes, - config_.allocation_allow_further_probing.Get()); + bool allow_further_probing = limited_by_current_bwe; + + return InitiateProbing(at_time, probes, allow_further_probing); } max_total_allocated_bitrate_ = max_total_allocated_bitrate; return std::vector(); diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h index feec81f2dc..25f02aee69 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.h +++ b/modules/congestion_controller/goog_cc/probe_controller.h @@ -64,8 +64,7 @@ struct ProbeControllerConfig { FieldTrialParameter probe_on_max_allocated_bitrate_change; FieldTrialOptional first_allocation_probe_scale; FieldTrialOptional second_allocation_probe_scale; - FieldTrialFlag allocation_allow_further_probing; - FieldTrialParameter allocation_probe_max; + FieldTrialOptional allocation_probe_limit_by_current_scale; // The minimum number probing packets used. FieldTrialParameter min_probe_packets_sent; diff --git a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc index 94025b30ea..6e34a2962d 100644 --- a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc +++ b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc @@ -213,6 +213,42 @@ TEST(ProbeControllerTest, ProbesOnMaxAllocatedBitrateIncreaseOnlyWhenInAlr) { EXPECT_TRUE(probes.empty()); } +TEST(ProbeControllerTest, ProbesOnMaxAllocatedBitrateLimitedByCurrentBwe) { + ProbeControllerFixture fixture( + "WebRTC-Bwe-ProbingConfiguration/" + "alloc_current_bwe_limit:1.5/"); + ASSERT_TRUE(kMaxBitrate > 1.5 * kStartBitrate); + std::unique_ptr probe_controller = + fixture.CreateController(); + ASSERT_THAT( + probe_controller->OnNetworkAvailability({.network_available = true}), + IsEmpty()); + auto probes = probe_controller->SetBitrates( + kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime()); + probes = probe_controller->SetEstimatedBitrate( + kStartBitrate, BandwidthLimitedCause::kDelayBasedLimited, + fixture.CurrentTime()); + + // Wait long enough to time out exponential probing. + fixture.AdvanceTime(kExponentialProbingTimeout); + probes = probe_controller->Process(fixture.CurrentTime()); + EXPECT_TRUE(probes.empty()); + + // Probe when in alr. + probe_controller->SetAlrStartTimeMs(fixture.CurrentTime().ms()); + probes = probe_controller->OnMaxTotalAllocatedBitrate(kMaxBitrate, + fixture.CurrentTime()); + EXPECT_EQ(probes.size(), 1u); + EXPECT_EQ(probes.at(0).target_data_rate, 1.5 * kStartBitrate); + + // Continue probing if probe succeeds. + probes = probe_controller->SetEstimatedBitrate( + 1.5 * kStartBitrate, BandwidthLimitedCause::kDelayBasedLimited, + fixture.CurrentTime()); + EXPECT_EQ(probes.size(), 1u); + EXPECT_GT(probes.at(0).target_data_rate, 1.5 * kStartBitrate); +} + TEST(ProbeControllerTest, CanDisableProbingOnMaxTotalAllocatedBitrateIncrease) { ProbeControllerFixture fixture( "WebRTC-Bwe-ProbingConfiguration/" From 2eee89e9044f51263a9635febbb923af73925439 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Wed, 7 Feb 2024 13:17:19 +0100 Subject: [PATCH 149/170] Cleanup webrtc::Environment propagation through java wrappers Force and thus guarantee VideoDecoder created through java wrappers get access to the webrtc::Environment Bug: webrtc:15791 Change-Id: I3f145937c0b914c8e34b24e1ecc55da756551069 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338441 Reviewed-by: Sergey Silkin Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41745} --- sdk/android/api/org/webrtc/Dav1dDecoder.java | 2 +- .../api/org/webrtc/LibvpxVp8Decoder.java | 2 +- .../api/org/webrtc/LibvpxVp9Decoder.java | 2 +- .../org/webrtc/SoftwareVideoDecoderFactory.java | 7 ------- sdk/android/api/org/webrtc/VideoDecoder.java | 6 ------ .../api/org/webrtc/VideoDecoderFallback.java | 7 ------- .../org/webrtc/WrappedNativeVideoDecoder.java | 4 +--- .../src/jni/software_video_decoder_factory.cc | 16 ---------------- sdk/android/src/jni/video_decoder_fallback.cc | 17 ----------------- sdk/android/src/jni/video_decoder_wrapper.cc | 14 -------------- sdk/android/src/jni/video_decoder_wrapper.h | 6 ------ 11 files changed, 4 insertions(+), 79 deletions(-) diff --git a/sdk/android/api/org/webrtc/Dav1dDecoder.java b/sdk/android/api/org/webrtc/Dav1dDecoder.java index ecb16bc3a1..2a79988470 100644 --- a/sdk/android/api/org/webrtc/Dav1dDecoder.java +++ b/sdk/android/api/org/webrtc/Dav1dDecoder.java @@ -12,7 +12,7 @@ package org.webrtc; public class Dav1dDecoder extends WrappedNativeVideoDecoder { @Override - public long createNativeVideoDecoder() { + public long createNative(long webrtcEnvRef) { return nativeCreateDecoder(); } diff --git a/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java b/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java index 54ad0aa137..b3846f20fb 100644 --- a/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java +++ b/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java @@ -12,7 +12,7 @@ package org.webrtc; public class LibvpxVp8Decoder extends WrappedNativeVideoDecoder { @Override - public long createNativeVideoDecoder() { + public long createNative(long webrtcEnvRef) { return nativeCreateDecoder(); } diff --git a/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java b/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java index 90a24433a3..34718cfa8c 100644 --- a/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java +++ b/sdk/android/api/org/webrtc/LibvpxVp9Decoder.java @@ -12,7 +12,7 @@ package org.webrtc; public class LibvpxVp9Decoder extends WrappedNativeVideoDecoder { @Override - public long createNativeVideoDecoder() { + public long createNative(long webrtcEnvRef) { return nativeCreateDecoder(); } diff --git a/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java b/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java index ac815d395b..1b1cd44a92 100644 --- a/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java +++ b/sdk/android/api/org/webrtc/SoftwareVideoDecoderFactory.java @@ -30,11 +30,6 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { return null; } return new WrappedNativeVideoDecoder() { - @Override - public long createNativeVideoDecoder() { - return nativeCreateDecoder(nativeFactory, info); - } - @Override public long createNative(long webrtcEnvRef) { return nativeCreate(nativeFactory, webrtcEnvRef, info); @@ -49,8 +44,6 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory { private static native long nativeCreateFactory(); - private static native long nativeCreateDecoder(long factory, VideoCodecInfo videoCodecInfo); - private static native boolean nativeIsSupported(long factory, VideoCodecInfo info); private static native long nativeCreate( diff --git a/sdk/android/api/org/webrtc/VideoDecoder.java b/sdk/android/api/org/webrtc/VideoDecoder.java index f44672da08..195daf5260 100644 --- a/sdk/android/api/org/webrtc/VideoDecoder.java +++ b/sdk/android/api/org/webrtc/VideoDecoder.java @@ -70,12 +70,6 @@ public interface VideoDecoder { */ @CalledByNative default long createNative(long webrtcEnvRef) { - return createNativeVideoDecoder(); - } - - @CalledByNative - @Deprecated - default long createNativeVideoDecoder() { return 0; } diff --git a/sdk/android/api/org/webrtc/VideoDecoderFallback.java b/sdk/android/api/org/webrtc/VideoDecoderFallback.java index dc2e2eeabe..1e7bae9b27 100644 --- a/sdk/android/api/org/webrtc/VideoDecoderFallback.java +++ b/sdk/android/api/org/webrtc/VideoDecoderFallback.java @@ -22,18 +22,11 @@ public class VideoDecoderFallback extends WrappedNativeVideoDecoder { this.primary = primary; } - @Override - public long createNativeVideoDecoder() { - return nativeCreateDecoder(fallback, primary); - } - @Override public long createNative(long webrtcEnvRef) { return nativeCreate(webrtcEnvRef, fallback, primary); } - private static native long nativeCreateDecoder(VideoDecoder fallback, VideoDecoder primary); - private static native long nativeCreate( long webrtcEnvRef, VideoDecoder fallback, VideoDecoder primary); } diff --git a/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java b/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java index ac9886e6a3..d762e757e4 100644 --- a/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java +++ b/sdk/android/api/org/webrtc/WrappedNativeVideoDecoder.java @@ -14,9 +14,7 @@ package org.webrtc; * Wraps a native webrtc::VideoDecoder. */ public abstract class WrappedNativeVideoDecoder implements VideoDecoder { - // TODO: bugs.webrtc.org/15791 - uncomment when implemented by all - // derived classes instead of the createNativeVideoDecoder - // @Override public abstract long createNative(long webrtcEnvRef); + @Override public abstract long createNative(long webrtcEnvRef); @Override public final VideoCodecStatus initDecode(Settings settings, Callback decodeCallback) { diff --git a/sdk/android/src/jni/software_video_decoder_factory.cc b/sdk/android/src/jni/software_video_decoder_factory.cc index 46b67b88eb..6e711e813d 100644 --- a/sdk/android/src/jni/software_video_decoder_factory.cc +++ b/sdk/android/src/jni/software_video_decoder_factory.cc @@ -27,22 +27,6 @@ static jlong JNI_SoftwareVideoDecoderFactory_CreateFactory(JNIEnv* env) { CreateBuiltinVideoDecoderFactory().release()); } -static jlong JNI_SoftwareVideoDecoderFactory_CreateDecoder( - JNIEnv* env, - jlong j_factory, - const webrtc::JavaParamRef& j_video_codec_info) { - auto* const native_factory = - reinterpret_cast(j_factory); - const auto video_format = - webrtc::jni::VideoCodecInfoToSdpVideoFormat(env, j_video_codec_info); - - auto decoder = native_factory->CreateVideoDecoder(video_format); - if (decoder == nullptr) { - return 0; - } - return webrtc::NativeToJavaPointer(decoder.release()); -} - jboolean JNI_SoftwareVideoDecoderFactory_IsSupported( JNIEnv* env, jlong j_factory, diff --git a/sdk/android/src/jni/video_decoder_fallback.cc b/sdk/android/src/jni/video_decoder_fallback.cc index 8b521c8f2f..2688c59d0f 100644 --- a/sdk/android/src/jni/video_decoder_fallback.cc +++ b/sdk/android/src/jni/video_decoder_fallback.cc @@ -18,23 +18,6 @@ namespace webrtc { namespace jni { -static jlong JNI_VideoDecoderFallback_CreateDecoder( - JNIEnv* jni, - const JavaParamRef& j_fallback_decoder, - const JavaParamRef& j_primary_decoder) { - std::unique_ptr fallback_decoder = - JavaToNativeVideoDecoder(jni, j_fallback_decoder); - std::unique_ptr primary_decoder = - JavaToNativeVideoDecoder(jni, j_primary_decoder); - - VideoDecoder* nativeWrapper = - CreateVideoDecoderSoftwareFallbackWrapper(std::move(fallback_decoder), - std::move(primary_decoder)) - .release(); - - return jlongFromPointer(nativeWrapper); -} - static jlong JNI_VideoDecoderFallback_Create( JNIEnv* jni, jlong j_webrtc_env_ref, diff --git a/sdk/android/src/jni/video_decoder_wrapper.cc b/sdk/android/src/jni/video_decoder_wrapper.cc index c96961879c..eaeeb2d298 100644 --- a/sdk/android/src/jni/video_decoder_wrapper.cc +++ b/sdk/android/src/jni/video_decoder_wrapper.cc @@ -269,20 +269,6 @@ absl::optional VideoDecoderWrapper::ParseQP( return qp; } -std::unique_ptr JavaToNativeVideoDecoder( - JNIEnv* jni, - const JavaRef& j_decoder) { - const jlong native_decoder = - Java_VideoDecoder_createNativeVideoDecoder(jni, j_decoder); - VideoDecoder* decoder; - if (native_decoder == 0) { - decoder = new VideoDecoderWrapper(jni, j_decoder); - } else { - decoder = reinterpret_cast(native_decoder); - } - return std::unique_ptr(decoder); -} - std::unique_ptr JavaToNativeVideoDecoder( JNIEnv* jni, const JavaRef& j_decoder, diff --git a/sdk/android/src/jni/video_decoder_wrapper.h b/sdk/android/src/jni/video_decoder_wrapper.h index 80638a7b61..5e397f1ae1 100644 --- a/sdk/android/src/jni/video_decoder_wrapper.h +++ b/sdk/android/src/jni/video_decoder_wrapper.h @@ -116,12 +116,6 @@ class VideoDecoderWrapper : public VideoDecoder { /* If the j_decoder is a wrapped native decoder, unwrap it. If it is not, * wrap it in a VideoDecoderWrapper. */ -// TODO: bugs.webrtc.org/15791 - delete variant without the webrtcEnvRef -// parameter when unused. -std::unique_ptr JavaToNativeVideoDecoder( - JNIEnv* jni, - const JavaRef& j_decoder); - std::unique_ptr JavaToNativeVideoDecoder( JNIEnv* jni, const JavaRef& j_decoder, From ce1271af8fabfbb0c13abf28180095def22552c1 Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Thu, 15 Feb 2024 10:33:40 +0100 Subject: [PATCH 150/170] Do not guard AV1 SVC tests on VP9 define BUG=None Change-Id: Id10bb49c266319eb387f0dd2e9c4327b8a5eb944 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339800 Reviewed-by: Florent Castelli Commit-Queue: Philipp Hancke Cr-Commit-Position: refs/heads/main@{#41746} --- pc/test/svc_e2e_tests.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pc/test/svc_e2e_tests.cc b/pc/test/svc_e2e_tests.cc index b2382d700f..678c36b586 100644 --- a/pc/test/svc_e2e_tests.cc +++ b/pc/test/svc_e2e_tests.cc @@ -454,6 +454,7 @@ INSTANTIATE_TEST_SUITE_P( Values(UseDependencyDescriptor::Disabled, UseDependencyDescriptor::Enabled)), SvcTestNameGenerator); +#endif INSTANTIATE_TEST_SUITE_P( SvcTestAV1, @@ -503,6 +504,4 @@ INSTANTIATE_TEST_SUITE_P( Values(UseDependencyDescriptor::Enabled)), SvcTestNameGenerator); -#endif - } // namespace webrtc From 46364195d35c7e56af7fb876e04ff9afd7409c44 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Fri, 9 Feb 2024 12:43:15 +0100 Subject: [PATCH 151/170] Propagate webrtc::Environment through MultiplexDecoderAdapter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: webrtc:15791 Change-Id: Ibe8fdc45722409b2cf6608ea6d8da2ea7e3472c2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/338621 Reviewed-by: Erik Språng Commit-Queue: Danil Chapovalov Cr-Commit-Position: refs/heads/main@{#41747} --- media/BUILD.gn | 1 + media/engine/multiplex_codec_factory.cc | 17 ++++++++++------- media/engine/multiplex_codec_factory.h | 5 +++-- .../engine/multiplex_codec_factory_unittest.cc | 13 ++++++++----- modules/video_coding/BUILD.gn | 1 + .../include/multiplex_decoder_adapter.h | 5 ++++- .../multiplex/multiplex_decoder_adapter.cc | 7 +++++-- .../test/multiplex_adapter_unittest.cc | 12 ++++++++---- video/end_to_end_tests/codec_tests.cc | 12 ++++++++---- video/video_quality_test.cc | 2 +- 10 files changed, 49 insertions(+), 26 deletions(-) diff --git a/media/BUILD.gn b/media/BUILD.gn index 93d104cdd0..2530e5ab4d 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -376,6 +376,7 @@ rtc_library("rtc_internal_video_codecs") { ":media_constants", ":rtc_media_base", ":rtc_simulcast_encoder_adapter", + "../api/environment", "../api/video:encoded_image", "../api/video:video_bitrate_allocation", "../api/video:video_frame", diff --git a/media/engine/multiplex_codec_factory.cc b/media/engine/multiplex_codec_factory.cc index 90df02a77e..cf17b46d7d 100644 --- a/media/engine/multiplex_codec_factory.cc +++ b/media/engine/multiplex_codec_factory.cc @@ -11,10 +11,12 @@ #include "media/engine/multiplex_codec_factory.h" #include +#include #include #include #include "absl/strings/match.h" +#include "api/environment/environment.h" #include "api/video_codecs/sdp_video_format.h" #include "media/base/codec.h" #include "media/base/media_constants.h" @@ -95,20 +97,21 @@ std::vector MultiplexDecoderFactory::GetSupportedFormats() return augmented_formats; } -std::unique_ptr MultiplexDecoderFactory::CreateVideoDecoder( +std::unique_ptr MultiplexDecoderFactory::Create( + const Environment& env, const SdpVideoFormat& format) { - if (!IsMultiplexCodec(cricket::CreateVideoCodec(format))) - return factory_->CreateVideoDecoder(format); - const auto& it = - format.parameters.find(cricket::kCodecParamAssociatedCodecName); + if (!IsMultiplexCodec(cricket::CreateVideoCodec(format))) { + return factory_->Create(env, format); + } + auto it = format.parameters.find(cricket::kCodecParamAssociatedCodecName); if (it == format.parameters.end()) { RTC_LOG(LS_ERROR) << "No assicated codec for multiplex."; return nullptr; } SdpVideoFormat associated_format = format; associated_format.name = it->second; - return std::unique_ptr(new MultiplexDecoderAdapter( - factory_.get(), associated_format, supports_augmenting_data_)); + return std::make_unique( + env, factory_.get(), associated_format, supports_augmenting_data_); } } // namespace webrtc diff --git a/media/engine/multiplex_codec_factory.h b/media/engine/multiplex_codec_factory.h index a4272a2eb2..164164f3ee 100644 --- a/media/engine/multiplex_codec_factory.h +++ b/media/engine/multiplex_codec_factory.h @@ -14,6 +14,7 @@ #include #include +#include "api/environment/environment.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder_factory.h" @@ -66,8 +67,8 @@ class RTC_EXPORT MultiplexDecoderFactory : public VideoDecoderFactory { bool supports_augmenting_data = false); std::vector GetSupportedFormats() const override; - std::unique_ptr CreateVideoDecoder( - const SdpVideoFormat& format) override; + std::unique_ptr Create(const Environment& env, + const SdpVideoFormat& format) override; private: std::unique_ptr factory_; diff --git a/media/engine/multiplex_codec_factory_unittest.cc b/media/engine/multiplex_codec_factory_unittest.cc index 1cde2f37d8..7f0a418d4d 100644 --- a/media/engine/multiplex_codec_factory_unittest.cc +++ b/media/engine/multiplex_codec_factory_unittest.cc @@ -10,8 +10,10 @@ #include "media/engine/multiplex_codec_factory.h" +#include #include +#include "api/environment/environment_factory.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_encoder.h" @@ -22,12 +24,13 @@ namespace webrtc { -TEST(MultiplexDecoderFactory, CreateVideoDecoder) { - std::unique_ptr internal_factory( - new InternalDecoderFactory()); +TEST(MultiplexDecoderFactoryTest, CreateVideoDecoder) { + std::unique_ptr internal_factory = + std::make_unique(); MultiplexDecoderFactory factory(std::move(internal_factory)); - std::unique_ptr decoder = - factory.CreateVideoDecoder(SdpVideoFormat( + std::unique_ptr decoder = factory.Create( + CreateEnvironment(), + SdpVideoFormat( cricket::kMultiplexCodecName, {{cricket::kCodecParamAssociatedCodecName, cricket::kVp9CodecName}})); EXPECT_TRUE(decoder); diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 1cdc83662c..8358995c45 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -529,6 +529,7 @@ rtc_library("webrtc_multiplex") { ":video_coding_utility", "../../api:fec_controller_api", "../../api:scoped_refptr", + "../../api/environment", "../../api/video:encoded_image", "../../api/video:video_frame", "../../api/video:video_rtp_headers", diff --git a/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h b/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h index d58981e4b2..ed02f2d72b 100644 --- a/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h +++ b/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h @@ -15,6 +15,7 @@ #include #include +#include "api/environment/environment.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder_factory.h" @@ -25,7 +26,8 @@ namespace webrtc { class MultiplexDecoderAdapter : public VideoDecoder { public: // `factory` is not owned and expected to outlive this class. - MultiplexDecoderAdapter(VideoDecoderFactory* factory, + MultiplexDecoderAdapter(const Environment& env, + VideoDecoderFactory* factory, const SdpVideoFormat& associated_format, bool supports_augmenting_data = false); virtual ~MultiplexDecoderAdapter(); @@ -62,6 +64,7 @@ class MultiplexDecoderAdapter : public VideoDecoder { std::unique_ptr augmenting_data, uint16_t augmenting_data_length); + const Environment env_; VideoDecoderFactory* const factory_; const SdpVideoFormat associated_format_; std::vector> decoders_; diff --git a/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc b/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc index 551a9490b0..7cebbe14d0 100644 --- a/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc +++ b/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc @@ -10,6 +10,7 @@ #include "modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h" +#include "api/environment/environment.h" #include "api/video/encoded_image.h" #include "api/video/i420_buffer.h" #include "api/video/video_frame_buffer.h" @@ -93,10 +94,12 @@ struct MultiplexDecoderAdapter::AugmentingData { }; MultiplexDecoderAdapter::MultiplexDecoderAdapter( + const Environment& env, VideoDecoderFactory* factory, const SdpVideoFormat& associated_format, bool supports_augmenting_data) - : factory_(factory), + : env_(env), + factory_(factory), associated_format_(associated_format), supports_augmenting_data_(supports_augmenting_data) {} @@ -111,7 +114,7 @@ bool MultiplexDecoderAdapter::Configure(const Settings& settings) { PayloadStringToCodecType(associated_format_.name)); for (size_t i = 0; i < kAlphaCodecStreams; ++i) { std::unique_ptr decoder = - factory_->CreateVideoDecoder(associated_format_); + factory_->Create(env_, associated_format_); if (!decoder->Configure(associated_settings)) { return false; } diff --git a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc index a2f36a306d..9c6300e368 100644 --- a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc +++ b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc @@ -16,6 +16,8 @@ #include #include "absl/types/optional.h" +#include "api/environment/environment.h" +#include "api/environment/environment_factory.h" #include "api/scoped_refptr.h" #include "api/test/mock_video_decoder_factory.h" #include "api/test/mock_video_encoder_factory.h" @@ -63,7 +65,8 @@ class TestMultiplexAdapter : public VideoCodecUnitTest, protected: std::unique_ptr CreateDecoder() override { return std::make_unique( - decoder_factory_.get(), SdpVideoFormat(kMultiplexAssociatedCodecName), + env_, decoder_factory_.get(), + SdpVideoFormat(kMultiplexAssociatedCodecName), supports_augmenting_data_); } @@ -182,9 +185,9 @@ class TestMultiplexAdapter : public VideoCodecUnitTest, EXPECT_CALL(*decoder_factory_, Die); // The decoders/encoders will be owned by the caller of // CreateVideoDecoder()/CreateVideoEncoder(). - EXPECT_CALL(*decoder_factory_, CreateVideoDecoder) - .Times(2) - .WillRepeatedly([] { return VP9Decoder::Create(); }); + EXPECT_CALL(*decoder_factory_, Create).Times(2).WillRepeatedly([] { + return VP9Decoder::Create(); + }); EXPECT_CALL(*encoder_factory_, Die); EXPECT_CALL(*encoder_factory_, CreateVideoEncoder) @@ -194,6 +197,7 @@ class TestMultiplexAdapter : public VideoCodecUnitTest, VideoCodecUnitTest::SetUp(); } + const Environment env_ = CreateEnvironment(); const std::unique_ptr decoder_factory_; const std::unique_ptr encoder_factory_; const bool supports_augmenting_data_; diff --git a/video/end_to_end_tests/codec_tests.cc b/video/end_to_end_tests/codec_tests.cc index 60a0bc8a15..e9ec7d541f 100644 --- a/video/end_to_end_tests/codec_tests.cc +++ b/video/end_to_end_tests/codec_tests.cc @@ -196,9 +196,11 @@ TEST_F(CodecEndToEndTest, SendsAndReceivesMultiplex) { &internal_encoder_factory, SdpVideoFormat(cricket::kVp9CodecName)); }); test::FunctionVideoDecoderFactory decoder_factory( - [&internal_decoder_factory]() { + [&internal_decoder_factory](const Environment& env, + const SdpVideoFormat& /*format*/) { return std::make_unique( - &internal_decoder_factory, SdpVideoFormat(cricket::kVp9CodecName)); + env, &internal_decoder_factory, + SdpVideoFormat(cricket::kVp9CodecName)); }); CodecObserver test(5, kVideoRotation_0, absl::nullopt, "multiplex", @@ -215,9 +217,11 @@ TEST_F(CodecEndToEndTest, SendsAndReceivesMultiplexVideoRotation90) { &internal_encoder_factory, SdpVideoFormat(cricket::kVp9CodecName)); }); test::FunctionVideoDecoderFactory decoder_factory( - [&internal_decoder_factory]() { + [&internal_decoder_factory](const Environment& env, + const SdpVideoFormat& /*format*/) { return std::make_unique( - &internal_decoder_factory, SdpVideoFormat(cricket::kVp9CodecName)); + env, &internal_decoder_factory, + SdpVideoFormat(cricket::kVp9CodecName)); }); CodecObserver test(5, kVideoRotation_90, absl::nullopt, "multiplex", &encoder_factory, &decoder_factory); diff --git a/video/video_quality_test.cc b/video/video_quality_test.cc index ebfc24130e..c8331bffec 100644 --- a/video/video_quality_test.cc +++ b/video/video_quality_test.cc @@ -299,7 +299,7 @@ std::unique_ptr VideoQualityTest::CreateVideoDecoder( std::unique_ptr decoder; if (format.name == "multiplex") { decoder = std::make_unique( - decoder_factory_.get(), SdpVideoFormat(cricket::kVp9CodecName)); + env, decoder_factory_.get(), SdpVideoFormat(cricket::kVp9CodecName)); } else if (format.name == "FakeCodec") { decoder = webrtc::FakeVideoDecoderFactory::CreateVideoDecoder(); } else { From 7e0bd7aaaf52a6a4bd6c3f84c107071cd2827299 Mon Sep 17 00:00:00 2001 From: Jianjun Zhu Date: Thu, 15 Feb 2024 23:21:24 +0800 Subject: [PATCH 152/170] Reland "Add HEVC support for h264_packet_buffer." This is a reland of commit a2655449ee310704ee2053fd6d43a5ab7002b755 This CL guards H265 header behind RTC_ENABLE_H265. Original change's description: > Add HEVC support for h264_packet_buffer. > > Renamed to h26x_packet_buffer as it also supports HEVC now. For HEVC, > start code is added by depacktizer, and remote endpoint must send > sequence and picture information in-band. > > Co-authored-by: Qiujiao Wu > > Bug: webrtc:13485 > Change-Id: I321cb223357d8d15da95cec80ec0c3a43c26734e > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333863 > Reviewed-by: Philip Eliasson > Commit-Queue: Philip Eliasson > Cr-Commit-Position: refs/heads/main@{#41739} Bug: webrtc:13485 Change-Id: I478e0ab88adcef34100670a90b12251ab3c9b623 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339822 Reviewed-by: Philip Eliasson Reviewed-by: Mirko Bonadei Commit-Queue: Philip Eliasson Cr-Commit-Position: refs/heads/main@{#41748} --- modules/video_coding/BUILD.gn | 10 +- .../h264_packet_buffer_unittest.cc | 778 ------------ ...packet_buffer.cc => h26x_packet_buffer.cc} | 122 +- ...4_packet_buffer.h => h26x_packet_buffer.h} | 19 +- .../h26x_packet_buffer_unittest.cc | 1058 +++++++++++++++++ 5 files changed, 1159 insertions(+), 828 deletions(-) delete mode 100644 modules/video_coding/h264_packet_buffer_unittest.cc rename modules/video_coding/{h264_packet_buffer.cc => h26x_packet_buffer.cc} (68%) rename modules/video_coding/{h264_packet_buffer.h => h26x_packet_buffer.h} (73%) create mode 100644 modules/video_coding/h26x_packet_buffer_unittest.cc diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 8358995c45..db5b57dff4 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -124,10 +124,10 @@ rtc_library("packet_buffer") { ] } -rtc_library("h264_packet_buffer") { +rtc_library("h26x_packet_buffer") { sources = [ - "h264_packet_buffer.cc", - "h264_packet_buffer.h", + "h26x_packet_buffer.cc", + "h26x_packet_buffer.h", ] deps = [ ":codec_globals_headers", @@ -1168,9 +1168,9 @@ if (rtc_include_tests) { "frame_dependencies_calculator_unittest.cc", "frame_helpers_unittest.cc", "generic_decoder_unittest.cc", - "h264_packet_buffer_unittest.cc", "h264_sprop_parameter_sets_unittest.cc", "h264_sps_pps_tracker_unittest.cc", + "h26x_packet_buffer_unittest.cc", "histogram_unittest.cc", "loss_notification_controller_unittest.cc", "nack_requester_unittest.cc", @@ -1205,7 +1205,7 @@ if (rtc_include_tests) { ":encoded_frame", ":frame_dependencies_calculator", ":frame_helpers", - ":h264_packet_buffer", + ":h26x_packet_buffer", ":nack_requester", ":packet_buffer", ":simulcast_test_fixture_impl", diff --git a/modules/video_coding/h264_packet_buffer_unittest.cc b/modules/video_coding/h264_packet_buffer_unittest.cc deleted file mode 100644 index 4f2331da28..0000000000 --- a/modules/video_coding/h264_packet_buffer_unittest.cc +++ /dev/null @@ -1,778 +0,0 @@ -/* - * Copyright (c) 2021 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 "modules/video_coding/h264_packet_buffer.h" - -#include -#include -#include -#include -#include - -#include "api/array_view.h" -#include "api/video/render_resolution.h" -#include "common_video/h264/h264_common.h" -#include "rtc_base/system/unused.h" -#include "test/gmock.h" -#include "test/gtest.h" - -namespace webrtc { -namespace { - -using ::testing::ElementsAreArray; -using ::testing::Eq; -using ::testing::IsEmpty; -using ::testing::SizeIs; - -using H264::NaluType::kAud; -using H264::NaluType::kFuA; -using H264::NaluType::kIdr; -using H264::NaluType::kPps; -using H264::NaluType::kSlice; -using H264::NaluType::kSps; -using H264::NaluType::kStapA; - -constexpr int kBufferSize = 2048; - -std::vector StartCode() { - return {0, 0, 0, 1}; -} - -NaluInfo MakeNaluInfo(uint8_t type) { - NaluInfo res; - res.type = type; - res.sps_id = -1; - res.pps_id = -1; - return res; -} - -class Packet { - public: - explicit Packet(H264PacketizationTypes type); - - Packet& Idr(std::vector payload = {9, 9, 9}); - Packet& Slice(std::vector payload = {9, 9, 9}); - Packet& Sps(std::vector payload = {9, 9, 9}); - Packet& SpsWithResolution(RenderResolution resolution, - std::vector payload = {9, 9, 9}); - Packet& Pps(std::vector payload = {9, 9, 9}); - Packet& Aud(); - Packet& Marker(); - Packet& AsFirstFragment(); - Packet& Time(uint32_t rtp_timestamp); - Packet& SeqNum(uint16_t rtp_seq_num); - - std::unique_ptr Build(); - - private: - rtc::CopyOnWriteBuffer BuildFuaPayload() const; - rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const; - rtc::CopyOnWriteBuffer BuildStapAPayload() const; - - RTPVideoHeaderH264& H264Header() { - return absl::get(video_header_.video_type_header); - } - const RTPVideoHeaderH264& H264Header() const { - return absl::get(video_header_.video_type_header); - } - - H264PacketizationTypes type_; - RTPVideoHeader video_header_; - bool first_fragment_ = false; - bool marker_bit_ = false; - uint32_t rtp_timestamp_ = 0; - uint16_t rtp_seq_num_ = 0; - std::vector> nalu_payloads_; -}; - -Packet::Packet(H264PacketizationTypes type) : type_(type) { - video_header_.video_type_header.emplace(); -} - -Packet& Packet::Idr(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kIdr); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Slice(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSlice); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Sps(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::SpsWithResolution(RenderResolution resolution, - std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); - video_header_.width = resolution.Width(); - video_header_.height = resolution.Height(); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Pps(std::vector payload) { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kPps); - nalu_payloads_.push_back(std::move(payload)); - return *this; -} - -Packet& Packet::Aud() { - auto& h264_header = H264Header(); - h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kAud); - nalu_payloads_.push_back({}); - return *this; -} - -Packet& Packet::Marker() { - marker_bit_ = true; - return *this; -} - -Packet& Packet::AsFirstFragment() { - first_fragment_ = true; - return *this; -} - -Packet& Packet::Time(uint32_t rtp_timestamp) { - rtp_timestamp_ = rtp_timestamp; - return *this; -} - -Packet& Packet::SeqNum(uint16_t rtp_seq_num) { - rtp_seq_num_ = rtp_seq_num; - return *this; -} - -std::unique_ptr Packet::Build() { - auto res = std::make_unique(); - - auto& h264_header = H264Header(); - switch (type_) { - case kH264FuA: { - RTC_CHECK_EQ(h264_header.nalus_length, 1); - res->video_payload = BuildFuaPayload(); - break; - } - case kH264SingleNalu: { - RTC_CHECK_EQ(h264_header.nalus_length, 1); - res->video_payload = BuildSingleNaluPayload(); - break; - } - case kH264StapA: { - RTC_CHECK_GT(h264_header.nalus_length, 1); - RTC_CHECK_LE(h264_header.nalus_length, kMaxNalusPerPacket); - res->video_payload = BuildStapAPayload(); - break; - } - } - - if (type_ == kH264FuA && !first_fragment_) { - h264_header.nalus_length = 0; - } - - h264_header.packetization_type = type_; - res->marker_bit = marker_bit_; - res->video_header = video_header_; - res->timestamp = rtp_timestamp_; - res->seq_num = rtp_seq_num_; - res->video_header.codec = kVideoCodecH264; - - return res; -} - -rtc::CopyOnWriteBuffer Packet::BuildFuaPayload() const { - return rtc::CopyOnWriteBuffer(nalu_payloads_[0]); -} - -rtc::CopyOnWriteBuffer Packet::BuildSingleNaluPayload() const { - rtc::CopyOnWriteBuffer res; - auto& h264_header = H264Header(); - res.AppendData(&h264_header.nalus[0].type, 1); - res.AppendData(nalu_payloads_[0]); - return res; -} - -rtc::CopyOnWriteBuffer Packet::BuildStapAPayload() const { - rtc::CopyOnWriteBuffer res; - - const uint8_t indicator = H264::NaluType::kStapA; - res.AppendData(&indicator, 1); - - auto& h264_header = H264Header(); - for (size_t i = 0; i < h264_header.nalus_length; ++i) { - // The two first bytes indicates the nalu segment size. - uint8_t length_as_array[2] = { - 0, static_cast(nalu_payloads_[i].size() + 1)}; - res.AppendData(length_as_array); - - res.AppendData(&h264_header.nalus[i].type, 1); - res.AppendData(nalu_payloads_[i]); - } - return res; -} - -rtc::ArrayView PacketPayload( - const std::unique_ptr& packet) { - return packet->video_payload; -} - -std::vector FlatVector( - const std::vector>& elems) { - std::vector res; - for (const auto& elem : elems) { - res.insert(res.end(), elem.begin(), elem.end()); - } - return res; -} - -TEST(H264PacketBufferTest, IdrIsKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true); - - EXPECT_THAT( - packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, IdrIsNotKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer.InsertPacket(Packet(kH264SingleNalu).Idr().Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/true); - - // Not marked as the first fragment - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - IsEmpty()); - - // Marked as first fragment - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Idr() - .SeqNum(2) - .Time(1) - .AsFirstFragment() - .Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build()) - .packets, - SizeIs(2)); -} - -TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(2).Time(0).Marker().Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, SpsPpsIdrIsKeyframeStapA) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, PpsIdrIsNotKeyframeStapA) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264StapA).Pps().Idr().SeqNum(0).Time(0).Marker().Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, SpsIdrIsNotKeyframeStapA) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264StapA).Sps().Idr().SeqNum(2).Time(2).Marker().Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(3) - .Time(3) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build())); - - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build()) - .packets, - SizeIs(2)); -} - -TEST(H264PacketBufferTest, InsertingMidFuaCompletesFrame) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(1).Time(1).AsFirstFragment().Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, SeqNumJumpDoesNotCompleteFrame) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build()) - .packets, - IsEmpty()); - - // Add `kBufferSize` to make the index of the sequence number wrap and end up - // where the packet with sequence number 2 would have ended up. - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(2 + kBufferSize) - .Time(3) - .Marker() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264SingleNalu) - .Slice() - .SeqNum(1) - .Time(1) - .Marker() - .Build()) - .packets, - IsEmpty()); - - // New keyframe, preceedes packet with sequence number 1 in the buffer. - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, OldPacketsDontBlockNewPackets) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 1) - .Time(kBufferSize + 1) - .AsFirstFragment() - .Build())); - - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 3) - .Time(kBufferSize + 1) - .Marker() - .Build())); - EXPECT_THAT( - packet_buffer - .InsertPacket(Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 2) - .Time(kBufferSize + 1) - .Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, OldPacketDoesntCompleteFrame) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(kBufferSize) - .Marker() - .Build()) - .packets, - SizeIs(1)); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 3) - .Time(kBufferSize + 1) - .Marker() - .Build()) - .packets, - IsEmpty()); - - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build()) - .packets, - IsEmpty()); - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264FuA) - .Slice() - .SeqNum(kBufferSize + 1) - .Time(kBufferSize + 1) - .AsFirstFragment() - .Build()) - .packets, - IsEmpty()); -} - -TEST(H264PacketBufferTest, FrameBoundariesAreSet) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - auto key = packet_buffer.InsertPacket( - Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build()); - - ASSERT_THAT(key.packets, SizeIs(1)); - EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame); - EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build())); - auto delta = packet_buffer.InsertPacket( - Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build()); - - ASSERT_THAT(delta.packets, SizeIs(3)); - EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame); - EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame); - - EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame); - EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame); - - EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame); - EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame); -} - -TEST(H264PacketBufferTest, ResolutionSetOnFirstPacket) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); - auto res = packet_buffer.InsertPacket(Packet(kH264StapA) - .SpsWithResolution({320, 240}) - .Pps() - .Idr() - .SeqNum(2) - .Time(1) - .Marker() - .Build()); - - ASSERT_THAT(res.packets, SizeIs(2)); - EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); - EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); -} - -TEST(H264PacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); - auto key = packet_buffer.InsertPacket( - Packet(kH264StapA).Sps().Pps().Idr().SeqNum(2).Time(1).Marker().Build()); - - auto delta = packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build()); - - ASSERT_THAT(key.packets, SizeIs(2)); - EXPECT_THAT(key.packets[0]->video_header.frame_type, - Eq(VideoFrameType::kVideoFrameKey)); - ASSERT_THAT(delta.packets, SizeIs(1)); - EXPECT_THAT(delta.packets[0]->video_header.frame_type, - Eq(VideoFrameType::kVideoFrameDelta)); -} - -TEST(H264PacketBufferTest, RtpSeqNumWrap) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())); - EXPECT_THAT(packet_buffer - .InsertPacket( - Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) - .packets, - SizeIs(3)); -} - -TEST(H264PacketBufferTest, StapAFixedBitstream) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - auto packets = packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps({1, 2, 3}) - .Pps({4, 5, 6}) - .Idr({7, 8, 9}) - .SeqNum(0) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(1)); - EXPECT_THAT(PacketPayload(packets[0]), - ElementsAreArray(FlatVector({StartCode(), - {kSps, 1, 2, 3}, - StartCode(), - {kPps, 4, 5, 6}, - StartCode(), - {kIdr, 7, 8, 9}}))); -} - -TEST(H264PacketBufferTest, SingleNaluFixedBitstream) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build())); - RTC_UNUSED(packet_buffer.InsertPacket( - Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build())); - auto packets = packet_buffer - .InsertPacket(Packet(kH264SingleNalu) - .Idr({7, 8, 9}) - .SeqNum(2) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(3)); - EXPECT_THAT(PacketPayload(packets[0]), - ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}}))); - EXPECT_THAT(PacketPayload(packets[1]), - ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}}))); - EXPECT_THAT(PacketPayload(packets[2]), - ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}}))); -} - -TEST(H264PacketBufferTest, StapaAndFuaFixedBitstream) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264StapA) - .Sps({1, 2, 3}) - .Pps({4, 5, 6}) - .SeqNum(0) - .Time(0) - .Build())); - RTC_UNUSED(packet_buffer.InsertPacket(Packet(kH264FuA) - .Idr({8, 8, 8}) - .SeqNum(1) - .Time(0) - .AsFirstFragment() - .Build())); - auto packets = packet_buffer - .InsertPacket(Packet(kH264FuA) - .Idr({9, 9, 9}) - .SeqNum(2) - .Time(0) - .Marker() - .Build()) - .packets; - - ASSERT_THAT(packets, SizeIs(3)); - EXPECT_THAT( - PacketPayload(packets[0]), - ElementsAreArray(FlatVector( - {StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}}))); - EXPECT_THAT(PacketPayload(packets[1]), - ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}}))); - // Third is a continuation of second, so only the payload is expected. - EXPECT_THAT(PacketPayload(packets[2]), - ElementsAreArray(FlatVector({{9, 9, 9}}))); -} - -TEST(H264PacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - for (int i = 0; i < kBufferSize; ++i) { - EXPECT_THAT( - packet_buffer - .InsertPacket( - Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build()) - .packets, - IsEmpty()); - } - - EXPECT_THAT(packet_buffer - .InsertPacket(Packet(kH264StapA) - .Sps() - .Pps() - .Idr() - .SeqNum(kBufferSize) - .Time(1) - .Marker() - .Build()) - .packets, - SizeIs(1)); -} - -TEST(H264PacketBufferTest, TooManyNalusInPacket) { - H264PacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); - - std::unique_ptr packet( - Packet(kH264StapA).Sps().Pps().Idr().SeqNum(1).Time(1).Marker().Build()); - auto& h264_header = - absl::get(packet->video_header.video_type_header); - h264_header.nalus_length = kMaxNalusPerPacket + 1; - - EXPECT_THAT(packet_buffer.InsertPacket(std::move(packet)).packets, IsEmpty()); -} - -} // namespace -} // namespace webrtc diff --git a/modules/video_coding/h264_packet_buffer.cc b/modules/video_coding/h26x_packet_buffer.cc similarity index 68% rename from modules/video_coding/h264_packet_buffer.cc rename to modules/video_coding/h26x_packet_buffer.cc index 6096665bda..bca2b5ce29 100644 --- a/modules/video_coding/h264_packet_buffer.cc +++ b/modules/video_coding/h26x_packet_buffer.cc @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/video_coding/h264_packet_buffer.h" +#include "modules/video_coding/h26x_packet_buffer.h" #include #include @@ -27,9 +27,13 @@ #include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/logging.h" #include "rtc_base/numerics/sequence_number_util.h" +#ifdef RTC_ENABLE_H265 +#include "common_video/h265/h265_common.h" +#endif namespace webrtc { namespace { + int64_t EuclideanMod(int64_t n, int64_t div) { RTC_DCHECK_GT(div, 0); return (n %= div) < 0 ? n + div : n; @@ -48,7 +52,7 @@ bool IsFirstPacketOfFragment(const RTPVideoHeaderH264& h264_header) { return h264_header.nalus_length > 0; } -bool BeginningOfIdr(const H264PacketBuffer::Packet& packet) { +bool BeginningOfIdr(const H26xPacketBuffer::Packet& packet) { const auto& h264_header = absl::get(packet.video_header.video_type_header); const bool contains_idr_nalu = @@ -66,7 +70,7 @@ bool BeginningOfIdr(const H264PacketBuffer::Packet& packet) { } } -bool HasSps(const H264PacketBuffer::Packet& packet) { +bool HasSps(const H26xPacketBuffer::Packet& packet) { auto& h264_header = absl::get(packet.video_header.video_type_header); return absl::c_any_of(GetNaluInfos(h264_header), [](const auto& nalu_info) { @@ -74,10 +78,24 @@ bool HasSps(const H264PacketBuffer::Packet& packet) { }); } +#ifdef RTC_ENABLE_H265 +bool HasVps(const H26xPacketBuffer::Packet& packet) { + std::vector nalu_indices = H265::FindNaluIndices( + packet.video_payload.cdata(), packet.video_payload.size()); + return absl::c_any_of((nalu_indices), [&packet]( + const H265::NaluIndex& nalu_index) { + return H265::ParseNaluType( + packet.video_payload.cdata()[nalu_index.payload_start_offset]) == + H265::NaluType::kVps; + }); +} +#endif + // TODO(bugs.webrtc.org/13157): Update the H264 depacketizer so we don't have to // fiddle with the payload at this point. -rtc::CopyOnWriteBuffer FixVideoPayload(rtc::ArrayView payload, - const RTPVideoHeader& video_header) { +rtc::CopyOnWriteBuffer FixH264VideoPayload( + rtc::ArrayView payload, + const RTPVideoHeader& video_header) { constexpr uint8_t kStartCode[] = {0, 0, 0, 1}; const auto& h264_header = @@ -124,18 +142,15 @@ rtc::CopyOnWriteBuffer FixVideoPayload(rtc::ArrayView payload, } // namespace -H264PacketBuffer::H264PacketBuffer(bool idr_only_keyframes_allowed) - : idr_only_keyframes_allowed_(idr_only_keyframes_allowed) {} +H26xPacketBuffer::H26xPacketBuffer(bool h264_idr_only_keyframes_allowed) + : h264_idr_only_keyframes_allowed_(h264_idr_only_keyframes_allowed) {} -H264PacketBuffer::InsertResult H264PacketBuffer::InsertPacket( +H26xPacketBuffer::InsertResult H26xPacketBuffer::InsertPacket( std::unique_ptr packet) { - RTC_DCHECK(packet->video_header.codec == kVideoCodecH264); + RTC_DCHECK(packet->video_header.codec == kVideoCodecH264 || + packet->video_header.codec == kVideoCodecH265); InsertResult result; - if (!absl::holds_alternative( - packet->video_header.video_type_header)) { - return result; - } int64_t unwrapped_seq_num = seq_num_unwrapper_.Unwrap(packet->seq_num); auto& packet_slot = GetPacket(unwrapped_seq_num); @@ -151,19 +166,27 @@ H264PacketBuffer::InsertResult H264PacketBuffer::InsertPacket( return result; } -std::unique_ptr& H264PacketBuffer::GetPacket( +std::unique_ptr& H26xPacketBuffer::GetPacket( int64_t unwrapped_seq_num) { return buffer_[EuclideanMod(unwrapped_seq_num, kBufferSize)]; } -bool H264PacketBuffer::BeginningOfStream( - const H264PacketBuffer::Packet& packet) const { - return HasSps(packet) || - (idr_only_keyframes_allowed_ && BeginningOfIdr(packet)); +bool H26xPacketBuffer::BeginningOfStream( + const H26xPacketBuffer::Packet& packet) const { + if (packet.codec() == kVideoCodecH264) { + return HasSps(packet) || + (h264_idr_only_keyframes_allowed_ && BeginningOfIdr(packet)); +#ifdef RTC_ENABLE_H265 + } else if (packet.codec() == kVideoCodecH265) { + return HasVps(packet); +#endif + } + RTC_DCHECK_NOTREACHED(); + return false; } -std::vector> -H264PacketBuffer::FindFrames(int64_t unwrapped_seq_num) { +std::vector> +H26xPacketBuffer::FindFrames(int64_t unwrapped_seq_num) { std::vector> found_frames; Packet* packet = GetPacket(unwrapped_seq_num).get(); @@ -223,13 +246,17 @@ H264PacketBuffer::FindFrames(int64_t unwrapped_seq_num) { return found_frames; } -bool H264PacketBuffer::MaybeAssembleFrame( +bool H26xPacketBuffer::MaybeAssembleFrame( int64_t start_seq_num_unwrapped, int64_t end_sequence_number_unwrapped, std::vector>& frames) { +#ifdef RTC_ENABLE_H265 + bool has_vps = false; +#endif bool has_sps = false; bool has_pps = false; bool has_idr = false; + bool has_irap = false; int width = -1; int height = -1; @@ -237,24 +264,44 @@ bool H264PacketBuffer::MaybeAssembleFrame( for (int64_t seq_num = start_seq_num_unwrapped; seq_num <= end_sequence_number_unwrapped; ++seq_num) { const auto& packet = GetPacket(seq_num); - const auto& h264_header = - absl::get(packet->video_header.video_type_header); - for (const auto& nalu : GetNaluInfos(h264_header)) { - has_idr |= nalu.type == H264::NaluType::kIdr; - has_sps |= nalu.type == H264::NaluType::kSps; - has_pps |= nalu.type == H264::NaluType::kPps; + if (packet->codec() == kVideoCodecH264) { + const auto& h264_header = + absl::get(packet->video_header.video_type_header); + for (const auto& nalu : GetNaluInfos(h264_header)) { + has_idr |= nalu.type == H264::NaluType::kIdr; + has_sps |= nalu.type == H264::NaluType::kSps; + has_pps |= nalu.type == H264::NaluType::kPps; + } + if (has_idr) { + if (!h264_idr_only_keyframes_allowed_ && (!has_sps || !has_pps)) { + return false; + } + } +#ifdef RTC_ENABLE_H265 + } else if (packet->codec() == kVideoCodecH265) { + std::vector nalu_indices = H265::FindNaluIndices( + packet->video_payload.cdata(), packet->video_payload.size()); + for (const auto& nalu_index : nalu_indices) { + uint8_t nalu_type = H265::ParseNaluType( + packet->video_payload.cdata()[nalu_index.payload_start_offset]); + has_irap |= (nalu_type >= H265::NaluType::kBlaWLp && + nalu_type <= H265::NaluType::kRsvIrapVcl23); + has_vps |= nalu_type == H265::NaluType::kVps; + has_sps |= nalu_type == H265::NaluType::kSps; + has_pps |= nalu_type == H265::NaluType::kPps; + } + if (has_irap) { + if (!has_vps || !has_sps || !has_pps) { + return false; + } + } +#endif // RTC_ENABLE_H265 } width = std::max(packet->video_header.width, width); height = std::max(packet->video_header.height, height); } - if (has_idr) { - if (!idr_only_keyframes_allowed_ && (!has_sps || !has_pps)) { - return false; - } - } - for (int64_t seq_num = start_seq_num_unwrapped; seq_num <= end_sequence_number_unwrapped; ++seq_num) { auto& packet = GetPacket(seq_num); @@ -270,13 +317,16 @@ bool H264PacketBuffer::MaybeAssembleFrame( packet->video_header.height = height; } - packet->video_header.frame_type = has_idr + packet->video_header.frame_type = has_idr || has_irap ? VideoFrameType::kVideoFrameKey : VideoFrameType::kVideoFrameDelta; } - packet->video_payload = - FixVideoPayload(packet->video_payload, packet->video_header); + // Start code is inserted by depacktizer for H.265. + if (packet->codec() == kVideoCodecH264) { + packet->video_payload = + FixH264VideoPayload(packet->video_payload, packet->video_header); + } frames.push_back(std::move(packet)); } diff --git a/modules/video_coding/h264_packet_buffer.h b/modules/video_coding/h26x_packet_buffer.h similarity index 73% rename from modules/video_coding/h264_packet_buffer.h rename to modules/video_coding/h26x_packet_buffer.h index a72c240e82..21601562c5 100644 --- a/modules/video_coding/h264_packet_buffer.h +++ b/modules/video_coding/h26x_packet_buffer.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ -#define MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ +#ifndef MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ +#define MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ #include #include @@ -22,15 +22,16 @@ namespace webrtc { -class H264PacketBuffer { +class H26xPacketBuffer { public: - // The H264PacketBuffer does the same job as the PacketBuffer but for H264 - // only. To make it fit in with surronding code the PacketBuffer input/output - // classes are used. + // The H26xPacketBuffer does the same job as the PacketBuffer but for H264 and + // H265 only. To make it fit in with surronding code the PacketBuffer + // input/output classes are used. using Packet = video_coding::PacketBuffer::Packet; using InsertResult = video_coding::PacketBuffer::InsertResult; - explicit H264PacketBuffer(bool idr_only_keyframes_allowed); + // |h264_idr_only_keyframes_allowed| is ignored if H.265 is used. + explicit H26xPacketBuffer(bool h264_idr_only_keyframes_allowed); ABSL_MUST_USE_RESULT InsertResult InsertPacket(std::unique_ptr packet); @@ -45,7 +46,7 @@ class H264PacketBuffer { int64_t end_sequence_number_unwrapped, std::vector>& packets); - const bool idr_only_keyframes_allowed_; + const bool h264_idr_only_keyframes_allowed_; std::array, kBufferSize> buffer_; absl::optional last_continuous_unwrapped_seq_num_; SeqNumUnwrapper seq_num_unwrapper_; @@ -53,4 +54,4 @@ class H264PacketBuffer { } // namespace webrtc -#endif // MODULES_VIDEO_CODING_H264_PACKET_BUFFER_H_ +#endif // MODULES_VIDEO_CODING_H26X_PACKET_BUFFER_H_ diff --git a/modules/video_coding/h26x_packet_buffer_unittest.cc b/modules/video_coding/h26x_packet_buffer_unittest.cc new file mode 100644 index 0000000000..ac5bcb735b --- /dev/null +++ b/modules/video_coding/h26x_packet_buffer_unittest.cc @@ -0,0 +1,1058 @@ +/* + * Copyright (c) 2021 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 "modules/video_coding/h26x_packet_buffer.h" + +#include +#include +#include +#include +#include + +#include "api/array_view.h" +#include "api/video/render_resolution.h" +#include "common_video/h264/h264_common.h" +#include "rtc_base/system/unused.h" +#include "test/gmock.h" +#include "test/gtest.h" +#ifdef RTC_ENABLE_H265 +#include "common_video/h265/h265_common.h" +#endif + +namespace webrtc { +namespace { + +using ::testing::ElementsAreArray; +using ::testing::Eq; +using ::testing::IsEmpty; +using ::testing::SizeIs; + +using H264::NaluType::kAud; +using H264::NaluType::kFuA; +using H264::NaluType::kIdr; +using H264::NaluType::kPps; +using H264::NaluType::kSlice; +using H264::NaluType::kSps; +using H264::NaluType::kStapA; + +constexpr int kBufferSize = 2048; + +std::vector StartCode() { + return {0, 0, 0, 1}; +} + +NaluInfo MakeNaluInfo(uint8_t type) { + NaluInfo res; + res.type = type; + res.sps_id = -1; + res.pps_id = -1; + return res; +} + +class H264Packet { + public: + explicit H264Packet(H264PacketizationTypes type); + + H264Packet& Idr(std::vector payload = {9, 9, 9}); + H264Packet& Slice(std::vector payload = {9, 9, 9}); + H264Packet& Sps(std::vector payload = {9, 9, 9}); + H264Packet& SpsWithResolution(RenderResolution resolution, + std::vector payload = {9, 9, 9}); + H264Packet& Pps(std::vector payload = {9, 9, 9}); + H264Packet& Aud(); + H264Packet& Marker(); + H264Packet& AsFirstFragment(); + H264Packet& Time(uint32_t rtp_timestamp); + H264Packet& SeqNum(uint16_t rtp_seq_num); + + std::unique_ptr Build(); + + private: + rtc::CopyOnWriteBuffer BuildFuaPayload() const; + rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const; + rtc::CopyOnWriteBuffer BuildStapAPayload() const; + + RTPVideoHeaderH264& H264Header() { + return absl::get(video_header_.video_type_header); + } + const RTPVideoHeaderH264& H264Header() const { + return absl::get(video_header_.video_type_header); + } + + H264PacketizationTypes type_; + RTPVideoHeader video_header_; + bool first_fragment_ = false; + bool marker_bit_ = false; + uint32_t rtp_timestamp_ = 0; + uint16_t rtp_seq_num_ = 0; + std::vector> nalu_payloads_; +}; + +H264Packet::H264Packet(H264PacketizationTypes type) : type_(type) { + video_header_.video_type_header.emplace(); +} + +H264Packet& H264Packet::Idr(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kIdr); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Slice(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSlice); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Sps(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::SpsWithResolution(RenderResolution resolution, + std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kSps); + video_header_.width = resolution.Width(); + video_header_.height = resolution.Height(); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Pps(std::vector payload) { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kPps); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H264Packet& H264Packet::Aud() { + auto& h264_header = H264Header(); + h264_header.nalus[h264_header.nalus_length++] = MakeNaluInfo(kAud); + nalu_payloads_.push_back({}); + return *this; +} + +H264Packet& H264Packet::Marker() { + marker_bit_ = true; + return *this; +} + +H264Packet& H264Packet::AsFirstFragment() { + first_fragment_ = true; + return *this; +} + +H264Packet& H264Packet::Time(uint32_t rtp_timestamp) { + rtp_timestamp_ = rtp_timestamp; + return *this; +} + +H264Packet& H264Packet::SeqNum(uint16_t rtp_seq_num) { + rtp_seq_num_ = rtp_seq_num; + return *this; +} + +std::unique_ptr H264Packet::Build() { + auto res = std::make_unique(); + + auto& h264_header = H264Header(); + switch (type_) { + case kH264FuA: { + RTC_CHECK_EQ(h264_header.nalus_length, 1); + res->video_payload = BuildFuaPayload(); + break; + } + case kH264SingleNalu: { + RTC_CHECK_EQ(h264_header.nalus_length, 1); + res->video_payload = BuildSingleNaluPayload(); + break; + } + case kH264StapA: { + RTC_CHECK_GT(h264_header.nalus_length, 1); + RTC_CHECK_LE(h264_header.nalus_length, kMaxNalusPerPacket); + res->video_payload = BuildStapAPayload(); + break; + } + } + + if (type_ == kH264FuA && !first_fragment_) { + h264_header.nalus_length = 0; + } + + h264_header.packetization_type = type_; + res->marker_bit = marker_bit_; + res->video_header = video_header_; + res->timestamp = rtp_timestamp_; + res->seq_num = rtp_seq_num_; + res->video_header.codec = kVideoCodecH264; + + return res; +} + +rtc::CopyOnWriteBuffer H264Packet::BuildFuaPayload() const { + return rtc::CopyOnWriteBuffer(nalu_payloads_[0]); +} + +rtc::CopyOnWriteBuffer H264Packet::BuildSingleNaluPayload() const { + rtc::CopyOnWriteBuffer res; + auto& h264_header = H264Header(); + res.AppendData(&h264_header.nalus[0].type, 1); + res.AppendData(nalu_payloads_[0]); + return res; +} + +rtc::CopyOnWriteBuffer H264Packet::BuildStapAPayload() const { + rtc::CopyOnWriteBuffer res; + + const uint8_t indicator = H264::NaluType::kStapA; + res.AppendData(&indicator, 1); + + auto& h264_header = H264Header(); + for (size_t i = 0; i < h264_header.nalus_length; ++i) { + // The two first bytes indicates the nalu segment size. + uint8_t length_as_array[2] = { + 0, static_cast(nalu_payloads_[i].size() + 1)}; + res.AppendData(length_as_array); + + res.AppendData(&h264_header.nalus[i].type, 1); + res.AppendData(nalu_payloads_[i]); + } + return res; +} + +#ifdef RTC_ENABLE_H265 +class H265Packet { + public: + H265Packet() = default; + + H265Packet& Idr(std::vector payload = {9, 9, 9}); + H265Packet& Slice(H265::NaluType type, + std::vector payload = {9, 9, 9}); + H265Packet& Vps(std::vector payload = {9, 9, 9}); + H265Packet& Sps(std::vector payload = {9, 9, 9}); + H265Packet& SpsWithResolution(RenderResolution resolution, + std::vector payload = {9, 9, 9}); + H265Packet& Pps(std::vector payload = {9, 9, 9}); + H265Packet& Aud(); + H265Packet& Marker(); + H265Packet& AsFirstFragment(); + H265Packet& Time(uint32_t rtp_timestamp); + H265Packet& SeqNum(uint16_t rtp_seq_num); + + std::unique_ptr Build(); + + private: + H265Packet& StartCode(); + + RTPVideoHeader video_header_; + bool first_fragment_ = false; + bool marker_bit_ = false; + uint32_t rtp_timestamp_ = 0; + uint16_t rtp_seq_num_ = 0; + std::vector> nalu_payloads_; +}; + +H265Packet& H265Packet::Idr(std::vector payload) { + return Slice(H265::NaluType::kIdrNLp, std::move(payload)); +} + +H265Packet& H265Packet::Slice(H265::NaluType type, + std::vector payload) { + StartCode(); + // Nalu header. Assume layer ID is 0 and TID is 2. + nalu_payloads_.push_back({static_cast(type << 1), 0x02}); + nalu_payloads_.push_back(std::move(payload)); + return *this; +} + +H265Packet& H265Packet::Vps(std::vector payload) { + return Slice(H265::NaluType::kVps, std::move(payload)); +} + +H265Packet& H265Packet::Sps(std::vector payload) { + return Slice(H265::NaluType::kSps, std::move(payload)); +} + +H265Packet& H265Packet::SpsWithResolution(RenderResolution resolution, + std::vector payload) { + video_header_.width = resolution.Width(); + video_header_.height = resolution.Height(); + return Sps(std::move(payload)); +} + +H265Packet& H265Packet::Pps(std::vector payload) { + return Slice(H265::NaluType::kPps, std::move(payload)); +} + +H265Packet& H265Packet::Aud() { + return Slice(H265::NaluType::kAud, {}); +} + +H265Packet& H265Packet::Marker() { + marker_bit_ = true; + return *this; +} + +H265Packet& H265Packet::StartCode() { + nalu_payloads_.push_back({0x00, 0x00, 0x00, 0x01}); + return *this; +} + +std::unique_ptr H265Packet::Build() { + auto res = std::make_unique(); + res->marker_bit = marker_bit_; + res->video_header = video_header_; + res->timestamp = rtp_timestamp_; + res->seq_num = rtp_seq_num_; + res->video_header.codec = kVideoCodecH265; + res->video_payload = rtc::CopyOnWriteBuffer(); + for (const auto& payload : nalu_payloads_) { + res->video_payload.AppendData(payload); + } + + return res; +} + +H265Packet& H265Packet::AsFirstFragment() { + first_fragment_ = true; + return *this; +} + +H265Packet& H265Packet::Time(uint32_t rtp_timestamp) { + rtp_timestamp_ = rtp_timestamp; + return *this; +} + +H265Packet& H265Packet::SeqNum(uint16_t rtp_seq_num) { + rtp_seq_num_ = rtp_seq_num; + return *this; +} +#endif + +rtc::ArrayView PacketPayload( + const std::unique_ptr& packet) { + return packet->video_payload; +} + +std::vector FlatVector( + const std::vector>& elems) { + std::vector res; + for (const auto& elem : elems) { + res.insert(res.end(), elem.begin(), elem.end()); + } + return res; +} + +TEST(H26xPacketBufferTest, IdrIsKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, IdrIsNotKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true); + + // Not marked as the first fragment + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build()) + .packets, + IsEmpty()); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + IsEmpty()); + + // Marked as first fragment + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Idr() + .SeqNum(2) + .Time(1) + .AsFirstFragment() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build()) + .packets, + SizeIs(2)); +} + +TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build())); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr() + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build())); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr() + .SeqNum(1) + .Time(0) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build())); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr() + .SeqNum(1) + .Time(0) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeStapA) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeStapA) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeStapA) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Idr() + .SeqNum(2) + .Time(2) + .Marker() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(3) + .Time(3) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build())); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build()) + .packets, + SizeIs(2)); +} + +TEST(H26xPacketBufferTest, InsertingMidFuaCompletesFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(1) + .Time(1) + .AsFirstFragment() + .Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, SeqNumJumpDoesNotCompleteFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build()) + .packets, + IsEmpty()); + + // Add `kBufferSize` to make the index of the sequence number wrap and end up + // where the packet with sequence number 2 would have ended up. + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(2 + kBufferSize) + .Time(3) + .Marker() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Slice() + .SeqNum(1) + .Time(1) + .Marker() + .Build()) + .packets, + IsEmpty()); + + // New keyframe, preceedes packet with sequence number 1 in the buffer. + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, OldPacketsDontBlockNewPackets) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 1) + .Time(kBufferSize + 1) + .AsFirstFragment() + .Build())); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 3) + .Time(kBufferSize + 1) + .Marker() + .Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 2) + .Time(kBufferSize + 1) + .Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, OldPacketDoesntCompleteFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(kBufferSize) + .Marker() + .Build()) + .packets, + SizeIs(1)); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 3) + .Time(kBufferSize + 1) + .Marker() + .Build()) + .packets, + IsEmpty()); + + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build()) + .packets, + IsEmpty()); + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Slice() + .SeqNum(kBufferSize + 1) + .Time(kBufferSize + 1) + .AsFirstFragment() + .Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, FrameBoundariesAreSet) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(1) + .Time(1) + .Marker() + .Build()); + + ASSERT_THAT(key.packets, SizeIs(1)); + EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame); + EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build())); + auto delta = packet_buffer.InsertPacket( + H264Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build()); + + ASSERT_THAT(delta.packets, SizeIs(3)); + EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame); + EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame); + + EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame); + EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame); + + EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame); + EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame); +} + +TEST(H26xPacketBufferTest, ResolutionSetOnFirstPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); + auto res = packet_buffer.InsertPacket(H264Packet(kH264StapA) + .SpsWithResolution({320, 240}) + .Pps() + .Idr() + .SeqNum(2) + .Time(1) + .Marker() + .Build()); + + ASSERT_THAT(res.packets, SizeIs(2)); + EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); + EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); +} + +TEST(H26xPacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build())); + auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(2) + .Time(1) + .Marker() + .Build()); + + auto delta = packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build()); + + ASSERT_THAT(key.packets, SizeIs(2)); + EXPECT_THAT(key.packets[0]->video_header.frame_type, + Eq(VideoFrameType::kVideoFrameKey)); + ASSERT_THAT(delta.packets, SizeIs(1)); + EXPECT_THAT(delta.packets[0]->video_header.frame_type, + Eq(VideoFrameType::kVideoFrameDelta)); +} + +TEST(H26xPacketBufferTest, RtpSeqNumWrap) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build())); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())); + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build()) + .packets, + SizeIs(3)); +} + +TEST(H26xPacketBufferTest, StapAFixedBitstream) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + auto packets = packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps({1, 2, 3}) + .Pps({4, 5, 6}) + .Idr({7, 8, 9}) + .SeqNum(0) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(1)); + EXPECT_THAT(PacketPayload(packets[0]), + ElementsAreArray(FlatVector({StartCode(), + {kSps, 1, 2, 3}, + StartCode(), + {kPps, 4, 5, 6}, + StartCode(), + {kIdr, 7, 8, 9}}))); +} + +TEST(H26xPacketBufferTest, SingleNaluFixedBitstream) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build())); + RTC_UNUSED(packet_buffer.InsertPacket( + H264Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build())); + auto packets = packet_buffer + .InsertPacket(H264Packet(kH264SingleNalu) + .Idr({7, 8, 9}) + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(3)); + EXPECT_THAT(PacketPayload(packets[0]), + ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}}))); + EXPECT_THAT(PacketPayload(packets[1]), + ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}}))); + EXPECT_THAT(PacketPayload(packets[2]), + ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}}))); +} + +TEST(H26xPacketBufferTest, StapaAndFuaFixedBitstream) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264StapA) + .Sps({1, 2, 3}) + .Pps({4, 5, 6}) + .SeqNum(0) + .Time(0) + .Build())); + RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA) + .Idr({8, 8, 8}) + .SeqNum(1) + .Time(0) + .AsFirstFragment() + .Build())); + auto packets = packet_buffer + .InsertPacket(H264Packet(kH264FuA) + .Idr({9, 9, 9}) + .SeqNum(2) + .Time(0) + .Marker() + .Build()) + .packets; + + ASSERT_THAT(packets, SizeIs(3)); + EXPECT_THAT( + PacketPayload(packets[0]), + ElementsAreArray(FlatVector( + {StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}}))); + EXPECT_THAT(PacketPayload(packets[1]), + ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}}))); + // Third is a continuation of second, so only the payload is expected. + EXPECT_THAT(PacketPayload(packets[2]), + ElementsAreArray(FlatVector({{9, 9, 9}}))); +} + +TEST(H26xPacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + for (int i = 0; i < kBufferSize; ++i) { + EXPECT_THAT( + packet_buffer + .InsertPacket( + H264Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build()) + .packets, + IsEmpty()); + } + + EXPECT_THAT(packet_buffer + .InsertPacket(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(kBufferSize) + .Time(1) + .Marker() + .Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, TooManyNalusInPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + std::unique_ptr packet(H264Packet(kH264StapA) + .Sps() + .Pps() + .Idr() + .SeqNum(1) + .Time(1) + .Marker() + .Build()); + auto& h264_header = + absl::get(packet->video_header.video_type_header); + h264_header.nalus_length = kMaxNalusPerPacket + 1; + + EXPECT_THAT(packet_buffer.InsertPacket(std::move(packet)).packets, IsEmpty()); +} + +#ifdef RTC_ENABLE_H265 +TEST(H26xPacketBufferTest, H265VpsSpsPpsIdrIsKeyframe) { + H26xPacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer + .InsertPacket(H265Packet().Vps().Sps().Pps().Idr().Marker().Build()) + .packets, + SizeIs(1)); +} + +TEST(H26xPacketBufferTest, H265IrapIsNotKeyframe) { + std::vector irap_types = { + H265::NaluType::kBlaWLp, H265::NaluType::kBlaWRadl, + H265::NaluType::kBlaNLp, H265::NaluType::kIdrWRadl, + H265::NaluType::kIdrNLp, H265::NaluType::kCra, + H265::NaluType::kRsvIrapVcl23}; + for (const H265::NaluType type : irap_types) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Slice(type).Marker().Build()) + .packets, + IsEmpty()); + } +} + +TEST(H26xPacketBufferTest, H265IdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Idr().Marker().Build()).packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265SpsPpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H265Packet().Sps().Pps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265VpsPpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H265Packet().Vps().Pps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265VpsSpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT(packet_buffer + .InsertPacket(H265Packet().Vps().Sps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265VpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Vps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265SpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Sps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265PpsIdrIsNotKeyFrame) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + EXPECT_THAT( + packet_buffer.InsertPacket(H265Packet().Pps().Idr().Marker().Build()) + .packets, + IsEmpty()); +} + +TEST(H26xPacketBufferTest, H265ResolutionSetOnSpsPacket) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED( + packet_buffer.InsertPacket(H265Packet().Aud().SeqNum(1).Time(1).Build())); + auto res = packet_buffer.InsertPacket(H265Packet() + .Vps() + .SpsWithResolution({320, 240}) + .Pps() + .Idr() + .SeqNum(2) + .Time(1) + .Marker() + .Build()); + + ASSERT_THAT(res.packets, SizeIs(2)); + EXPECT_THAT(res.packets[0]->video_header.width, Eq(320)); + EXPECT_THAT(res.packets[0]->video_header.height, Eq(240)); +} + +TEST(H26xPacketBufferTest, H265InsertingVpsSpsPpsLastCompletesKeyframe) { + H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false); + + RTC_UNUSED(packet_buffer.InsertPacket( + H265Packet().Idr().SeqNum(2).Time(1).Marker().Build())); + + EXPECT_THAT(packet_buffer + .InsertPacket( + H265Packet().Vps().Sps().Pps().SeqNum(1).Time(1).Build()) + .packets, + SizeIs(2)); +} +#endif // RTC_ENABLE_H265 + +} // namespace +} // namespace webrtc From 62cbdcea050529a5cd18d5e82dc3c8f6997b09fc Mon Sep 17 00:00:00 2001 From: Sunggook Chue Date: Tue, 13 Feb 2024 15:52:28 -0800 Subject: [PATCH 153/170] Allow getDisplayMedia capture HDR monitor. The code uses IDXGIOutput1::DuplicateOutput for screen capture and it allows only DXGI_FORMAT_B8G8R8A8_UNORM texture format, which works on most monitor cases except HDR monitor. HDR mointor returns type of DXGI_FORMAT_R16G16B16A16_FLOAT. These two types of DXGI_FORMAT_B8G8R8A8_UNORM and DXGI_FORMAT_R16G16B16A16_FLOAT are all formats that DuplicateOutput returns based on Windows OS team. The fix is to add allowed format of DXGI_FORMAT_R16G16B16A16_FLOAT. Manually repro the issue and validated the fix. Bug: chromium:40787684 Change-Id: I0a7be38b14a06261d631d2db172f12725edbbf1f Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339621 Reviewed-by: Mark Foltz Reviewed-by: Alexander Cooper Commit-Queue: Alexander Cooper Cr-Commit-Position: refs/heads/main@{#41749} --- modules/desktop_capture/win/dxgi_output_duplicator.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/desktop_capture/win/dxgi_output_duplicator.cc b/modules/desktop_capture/win/dxgi_output_duplicator.cc index 9c64125b4e..ac028ce38b 100644 --- a/modules/desktop_capture/win/dxgi_output_duplicator.cc +++ b/modules/desktop_capture/win/dxgi_output_duplicator.cc @@ -112,9 +112,13 @@ bool DxgiOutputDuplicator::DuplicateOutput() { memset(&desc_, 0, sizeof(desc_)); duplication_->GetDesc(&desc_); - if (desc_.ModeDesc.Format != DXGI_FORMAT_B8G8R8A8_UNORM) { - RTC_LOG(LS_ERROR) << "IDXGIDuplicateOutput does not use RGBA (8 bit) " - << "format, which is required by downstream components, " + + // DXGI_FORMAT_R16G16B16A16_FLOAT is returned for HDR monitor, + // DXGI_FORMAT_B8G8R8A8_UNORM for others. + if ((desc_.ModeDesc.Format != DXGI_FORMAT_B8G8R8A8_UNORM) && + (desc_.ModeDesc.Format != DXGI_FORMAT_R16G16B16A16_FLOAT)) { + RTC_LOG(LS_ERROR) << "IDXGIDuplicateOutput does not use RGBA (8, 16 bit)" + << "which is required by downstream components" << "format is " << desc_.ModeDesc.Format; return false; } From 6596134fade8d52750fff13fdf1b217f41992904 Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Thu, 15 Feb 2024 20:14:47 -0800 Subject: [PATCH 154/170] Update WebRTC code version (2024-02-16T04:14:44). Bug: None Change-Id: I736a684aae87f4b745520787cf2891787250061c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339829 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41750} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index c61463d3e8..a30166bb11 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-15T04:07:08"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-16T04:14:44"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 1b52d5641e062bf56f1f7b40fd980b8b9e9f2679 Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Fri, 16 Feb 2024 08:09:20 +0000 Subject: [PATCH 155/170] Fix generate_buildbot_json and switch to ios_runtime_cache_17_4. When running it, even without changes at HEAD I got: ``` KeyError: 'ios_runtime_cache_17_0' ``` Bug: b/325441006 Change-Id: I7ea236ccc1f7439d7750208260b01d7636db4ae5 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339842 Commit-Queue: Mirko Bonadei Reviewed-by: Jeremy Leconte Cr-Commit-Position: refs/heads/main@{#41751} --- infra/specs/client.webrtc.json | 320 ++++++++++++------------ infra/specs/internal.client.webrtc.json | 80 +++--- infra/specs/mixins.pyl | 10 +- infra/specs/tryserver.webrtc.json | 320 ++++++++++++------------ infra/specs/variants.pyl | 2 +- 5 files changed, 366 insertions(+), 366 deletions(-) diff --git a/infra/specs/client.webrtc.json b/infra/specs/client.webrtc.json index 4d53f6de9d..53b75da569 100644 --- a/infra/specs/client.webrtc.json +++ b/infra/specs/client.webrtc.json @@ -7965,7 +7965,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -7989,12 +7989,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -8014,7 +8014,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8038,7 +8038,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8063,7 +8063,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8087,7 +8087,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8111,7 +8111,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8135,12 +8135,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -8159,7 +8159,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8183,7 +8183,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8207,7 +8207,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8231,7 +8231,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8255,7 +8255,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8279,12 +8279,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -8303,7 +8303,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8327,7 +8327,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8351,7 +8351,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8375,7 +8375,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8399,7 +8399,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8423,12 +8423,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -8447,7 +8447,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8471,7 +8471,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8495,7 +8495,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8519,7 +8519,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8543,7 +8543,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8567,12 +8567,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -8591,7 +8591,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8615,7 +8615,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8639,7 +8639,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8663,7 +8663,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8687,7 +8687,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8711,12 +8711,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -8736,7 +8736,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8760,7 +8760,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8785,7 +8785,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8809,7 +8809,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8834,7 +8834,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8859,12 +8859,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -8884,7 +8884,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8909,7 +8909,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8934,7 +8934,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -8959,7 +8959,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -8984,7 +8984,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9008,12 +9008,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -9032,7 +9032,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9056,7 +9056,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9080,7 +9080,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9104,7 +9104,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9128,7 +9128,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9152,12 +9152,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -9176,7 +9176,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9200,7 +9200,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9224,7 +9224,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9248,7 +9248,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9272,7 +9272,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9296,12 +9296,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -9320,7 +9320,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9344,7 +9344,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9368,7 +9368,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9392,7 +9392,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9416,7 +9416,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9440,12 +9440,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -9465,7 +9465,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9489,7 +9489,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9514,7 +9514,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9538,7 +9538,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9564,7 +9564,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9588,12 +9588,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -9613,7 +9613,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9637,7 +9637,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9662,7 +9662,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9686,7 +9686,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9711,7 +9711,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9735,12 +9735,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -9760,7 +9760,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9784,7 +9784,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9809,7 +9809,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9833,7 +9833,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9857,7 +9857,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9882,12 +9882,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -9907,7 +9907,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9932,7 +9932,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -9957,7 +9957,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -9982,7 +9982,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10007,7 +10007,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10031,12 +10031,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -10055,7 +10055,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10079,7 +10079,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10103,7 +10103,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10127,7 +10127,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10151,7 +10151,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10175,12 +10175,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -10199,7 +10199,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10223,7 +10223,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10247,7 +10247,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10271,7 +10271,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10295,7 +10295,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10319,12 +10319,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -10343,7 +10343,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10367,7 +10367,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10391,7 +10391,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10415,7 +10415,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10439,7 +10439,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10463,12 +10463,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -10488,7 +10488,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10512,7 +10512,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10537,7 +10537,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10561,7 +10561,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10586,7 +10586,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10610,12 +10610,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -10634,7 +10634,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10658,7 +10658,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10682,7 +10682,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10706,7 +10706,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10730,7 +10730,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10754,12 +10754,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -10778,7 +10778,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10802,7 +10802,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -10826,7 +10826,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -10850,7 +10850,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { diff --git a/infra/specs/internal.client.webrtc.json b/infra/specs/internal.client.webrtc.json index b6dbd5c2c3..3560abfacf 100644 --- a/infra/specs/internal.client.webrtc.json +++ b/infra/specs/internal.client.webrtc.json @@ -7,7 +7,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -34,7 +34,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -47,7 +47,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -74,7 +74,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -88,7 +88,7 @@ "--readline-timeout=1200", "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -117,7 +117,7 @@ "io_timeout": 7200, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -131,7 +131,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -158,7 +158,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -172,7 +172,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -199,7 +199,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -212,7 +212,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -239,7 +239,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -252,7 +252,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -279,7 +279,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -292,7 +292,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -319,7 +319,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -332,7 +332,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -359,7 +359,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -372,7 +372,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -399,7 +399,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -472,7 +472,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -499,7 +499,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -512,7 +512,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -539,7 +539,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -553,7 +553,7 @@ "--readline-timeout=1200", "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -582,7 +582,7 @@ "io_timeout": 7200, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -596,7 +596,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -623,7 +623,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -637,7 +637,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -664,7 +664,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -677,7 +677,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -704,7 +704,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -717,7 +717,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -744,7 +744,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -757,7 +757,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -784,7 +784,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -797,7 +797,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -824,7 +824,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], @@ -837,7 +837,7 @@ "args": [ "--xctest", "--xcode-build-version", - "15a507", + "15c500b", "--out-dir", "${ISOLATED_OUTDIR}" ], @@ -864,7 +864,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" } ], diff --git a/infra/specs/mixins.pyl b/infra/specs/mixins.pyl index 8520002df6..806881aeac 100644 --- a/infra/specs/mixins.pyl +++ b/infra/specs/mixins.pyl @@ -94,11 +94,11 @@ }] } }, - 'ios_runtime_cache_17_0': { + 'ios_runtime_cache_17_4': { 'swarming': { 'named_caches': [{ - 'name': 'runtime_ios_17_0', - 'path': 'Runtime-ios-17.0' + 'name': 'runtime_ios_17_4', + 'path': 'Runtime-ios-17.4' }] } }, @@ -320,10 +320,10 @@ } }, 'xcode_15_main': { - 'args': ['--xcode-build-version', '15a507'], + 'args': ['--xcode-build-version', '15c500b'], 'swarming': { 'named_caches': [{ - 'name': 'xcode_ios_15a507', + 'name': 'xcode_ios_15c500b', 'path': 'Xcode.app' }] } diff --git a/infra/specs/tryserver.webrtc.json b/infra/specs/tryserver.webrtc.json index 3ab538b02c..1324bbba7f 100644 --- a/infra/specs/tryserver.webrtc.json +++ b/infra/specs/tryserver.webrtc.json @@ -2327,7 +2327,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2351,12 +2351,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2376,7 +2376,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2400,7 +2400,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2425,7 +2425,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2449,7 +2449,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2473,7 +2473,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2497,12 +2497,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2521,7 +2521,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2545,7 +2545,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2569,7 +2569,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2593,7 +2593,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2617,7 +2617,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2641,12 +2641,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2665,7 +2665,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2689,7 +2689,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2713,7 +2713,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2737,7 +2737,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2761,7 +2761,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2785,12 +2785,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2809,7 +2809,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2833,7 +2833,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2857,7 +2857,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2881,7 +2881,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -2905,7 +2905,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2929,12 +2929,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -2953,7 +2953,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -2977,7 +2977,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3001,7 +3001,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3025,7 +3025,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3049,7 +3049,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3073,12 +3073,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -3098,7 +3098,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3122,7 +3122,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3147,7 +3147,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3171,7 +3171,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3196,7 +3196,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3221,12 +3221,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -3246,7 +3246,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3271,7 +3271,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3296,7 +3296,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3321,7 +3321,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3346,7 +3346,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3370,12 +3370,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3394,7 +3394,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3418,7 +3418,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3442,7 +3442,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3466,7 +3466,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3490,7 +3490,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3514,12 +3514,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3538,7 +3538,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3562,7 +3562,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3586,7 +3586,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3610,7 +3610,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3634,7 +3634,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3658,12 +3658,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3682,7 +3682,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3706,7 +3706,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3730,7 +3730,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3754,7 +3754,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3778,7 +3778,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3802,12 +3802,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -3827,7 +3827,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3851,7 +3851,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3876,7 +3876,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3900,7 +3900,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -3926,7 +3926,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3950,12 +3950,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -3975,7 +3975,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -3999,7 +3999,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4024,7 +4024,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4048,7 +4048,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4073,7 +4073,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4097,12 +4097,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -4122,7 +4122,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4146,7 +4146,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4171,7 +4171,7 @@ "--xctest", "--xcodebuild-sim-runner", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4195,7 +4195,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4219,7 +4219,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4244,12 +4244,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -4269,7 +4269,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4294,7 +4294,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4319,7 +4319,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4344,7 +4344,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4369,7 +4369,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4393,12 +4393,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -4417,7 +4417,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4441,7 +4441,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4465,7 +4465,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4489,7 +4489,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4513,7 +4513,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4537,12 +4537,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -4561,7 +4561,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4585,7 +4585,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4609,7 +4609,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4633,7 +4633,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4657,7 +4657,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4681,12 +4681,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -4705,7 +4705,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4729,7 +4729,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4753,7 +4753,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4777,7 +4777,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4801,7 +4801,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4825,12 +4825,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", @@ -4850,7 +4850,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4874,7 +4874,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4899,7 +4899,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4923,7 +4923,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -4948,7 +4948,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4972,12 +4972,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -4996,7 +4996,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5020,7 +5020,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -5044,7 +5044,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5068,7 +5068,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -5092,7 +5092,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5116,12 +5116,12 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { - "name": "runtime_ios_17_0", - "path": "Runtime-ios-17.0" + "name": "runtime_ios_17_4", + "path": "Runtime-ios-17.4" } ], "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" @@ -5140,7 +5140,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5164,7 +5164,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { @@ -5188,7 +5188,7 @@ "${ISOLATED_OUTDIR}", "--xctest", "--xcode-build-version", - "15a507" + "15c500b" ], "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5212,7 +5212,7 @@ }, "named_caches": [ { - "name": "xcode_ios_15a507", + "name": "xcode_ios_15c500b", "path": "Xcode.app" }, { diff --git a/infra/specs/variants.pyl b/infra/specs/variants.pyl index c97bdc5468..1554446155 100644 --- a/infra/specs/variants.pyl +++ b/infra/specs/variants.pyl @@ -35,6 +35,6 @@ '17.0', ], 'identifier': 'iPhone 14 17.0', - 'mixins': ['xcode_15_main', 'ios_runtime_cache_17_0'], + 'mixins': ['xcode_15_main', 'ios_runtime_cache_17_4'], }, } From 85b405b7989b49becdc41aa5813a90aedc23f534 Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Fri, 16 Feb 2024 09:03:53 +0000 Subject: [PATCH 156/170] Switch all Linux tasks from Focal to Jammy (except *san). Bug: b/325441006 Change-Id: I761a84b8e3570d107b82280c1c7870b982bbc3f0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339865 Reviewed-by: Jeremy Leconte Commit-Queue: Mirko Bonadei Commit-Queue: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41752} --- infra/specs/client.webrtc.json | 180 ++++++++++---------- infra/specs/mixins.pyl | 7 + infra/specs/tryserver.webrtc.json | 268 +++++++++++++++--------------- infra/specs/waterfalls.pyl | 28 ++-- 4 files changed, 245 insertions(+), 238 deletions(-) diff --git a/infra/specs/client.webrtc.json b/infra/specs/client.webrtc.json index 53b75da569..a41c566bd8 100644 --- a/infra/specs/client.webrtc.json +++ b/infra/specs/client.webrtc.json @@ -1864,7 +1864,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -1888,7 +1888,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -1912,7 +1912,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -1936,7 +1936,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -1960,7 +1960,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -1984,7 +1984,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -2008,7 +2008,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -2033,7 +2033,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -2057,7 +2057,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -2082,7 +2082,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -2106,7 +2106,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -2127,7 +2127,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -3865,7 +3865,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -3882,7 +3882,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -3899,7 +3899,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -3916,7 +3916,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -3933,7 +3933,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -3951,7 +3951,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -3969,7 +3969,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -3987,7 +3987,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -4004,7 +4004,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -4021,7 +4021,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -4038,7 +4038,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -4056,7 +4056,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -4073,7 +4073,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4091,7 +4091,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -4108,7 +4108,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -4125,7 +4125,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -4142,7 +4142,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4160,7 +4160,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -4177,7 +4177,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -4199,7 +4199,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -4216,7 +4216,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -4233,7 +4233,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -4250,7 +4250,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -4267,7 +4267,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -4285,7 +4285,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -4303,7 +4303,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4321,7 +4321,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -4338,7 +4338,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -4355,7 +4355,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -4372,7 +4372,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -4390,7 +4390,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -4407,7 +4407,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4425,7 +4425,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -4442,7 +4442,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -4459,7 +4459,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -4476,7 +4476,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4494,7 +4494,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -4511,7 +4511,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -4534,7 +4534,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -4551,7 +4551,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -4568,7 +4568,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -4585,7 +4585,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -4602,7 +4602,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -4620,7 +4620,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -4638,7 +4638,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4656,7 +4656,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -4673,7 +4673,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -4690,7 +4690,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -4707,7 +4707,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -4725,7 +4725,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "shared_screencast_stream_test", @@ -4742,7 +4742,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -4759,7 +4759,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4777,7 +4777,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -4794,7 +4794,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -4811,7 +4811,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -4828,7 +4828,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -4846,7 +4846,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -4863,7 +4863,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -4885,7 +4885,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -4902,7 +4902,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -4919,7 +4919,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -4936,7 +4936,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -4953,7 +4953,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -4971,7 +4971,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -4989,7 +4989,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -5007,7 +5007,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -5024,7 +5024,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -5041,7 +5041,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -5058,7 +5058,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -5076,7 +5076,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "shared_screencast_stream_test", @@ -5093,7 +5093,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -5110,7 +5110,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -5128,7 +5128,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -5145,7 +5145,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -5162,7 +5162,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -5179,7 +5179,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -5197,7 +5197,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -5214,7 +5214,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", diff --git a/infra/specs/mixins.pyl b/infra/specs/mixins.pyl index 806881aeac..fd54de90fa 100644 --- a/infra/specs/mixins.pyl +++ b/infra/specs/mixins.pyl @@ -124,6 +124,13 @@ } } }, + 'linux-jammy': { + 'swarming': { + 'dimensions': { + 'os': 'Ubuntu-22.04' + } + } + }, 'mac-m1-cpu': { 'swarming': { 'dimensions': { diff --git a/infra/specs/tryserver.webrtc.json b/infra/specs/tryserver.webrtc.json index 1324bbba7f..a4f33da2ef 100644 --- a/infra/specs/tryserver.webrtc.json +++ b/infra/specs/tryserver.webrtc.json @@ -2062,7 +2062,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -2086,7 +2086,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -2110,7 +2110,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -2134,7 +2134,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -2158,7 +2158,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -2182,7 +2182,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -2206,7 +2206,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -2231,7 +2231,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -2255,7 +2255,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -2280,7 +2280,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -2304,7 +2304,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -5598,7 +5598,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -5616,7 +5616,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -5634,7 +5634,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -5652,7 +5652,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -5670,7 +5670,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -5689,7 +5689,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -5708,7 +5708,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -5727,7 +5727,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -5745,7 +5745,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -5763,7 +5763,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -5781,7 +5781,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -5800,7 +5800,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "shared_screencast_stream_test", @@ -5818,7 +5818,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -5836,7 +5836,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -5855,7 +5855,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -5873,7 +5873,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -5891,7 +5891,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -5915,7 +5915,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "video_codec_perf_tests", @@ -5933,7 +5933,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -5952,7 +5952,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -5970,7 +5970,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -5994,7 +5994,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_perf_tests", @@ -6015,7 +6015,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -6032,7 +6032,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -6049,7 +6049,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -6066,7 +6066,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -6083,7 +6083,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -6101,7 +6101,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -6119,7 +6119,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -6137,7 +6137,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -6154,7 +6154,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -6171,7 +6171,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -6188,7 +6188,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -6206,7 +6206,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "shared_screencast_stream_test", @@ -6223,7 +6223,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -6240,7 +6240,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -6258,7 +6258,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -6275,7 +6275,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -6292,7 +6292,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -6309,7 +6309,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -6327,7 +6327,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -6344,7 +6344,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -6366,7 +6366,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -6383,7 +6383,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -6400,7 +6400,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -6417,7 +6417,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -6434,7 +6434,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -6452,7 +6452,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -6470,7 +6470,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -6488,7 +6488,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -6505,7 +6505,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -6522,7 +6522,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -6539,7 +6539,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -6557,7 +6557,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "shared_screencast_stream_test", @@ -6574,7 +6574,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -6591,7 +6591,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -6609,7 +6609,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -6626,7 +6626,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -6643,7 +6643,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -6660,7 +6660,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -6678,7 +6678,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -6695,7 +6695,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -6716,7 +6716,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -7071,7 +7071,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -7088,7 +7088,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -7105,7 +7105,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -7122,7 +7122,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -7139,7 +7139,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -7157,7 +7157,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -7175,7 +7175,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -7193,7 +7193,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -7210,7 +7210,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -7227,7 +7227,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -7244,7 +7244,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -7262,7 +7262,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "shared_screencast_stream_test", @@ -7279,7 +7279,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -7296,7 +7296,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -7314,7 +7314,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -7331,7 +7331,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -7348,7 +7348,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -7371,7 +7371,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "video_codec_perf_tests", @@ -7388,7 +7388,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -7406,7 +7406,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -7423,7 +7423,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -7446,7 +7446,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_perf_tests", @@ -8500,7 +8500,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -8517,7 +8517,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -8534,7 +8534,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -8551,7 +8551,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -8568,7 +8568,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -8586,7 +8586,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -8604,7 +8604,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -8622,7 +8622,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -8639,7 +8639,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -8656,7 +8656,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -8673,7 +8673,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -8691,7 +8691,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -8708,7 +8708,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -8726,7 +8726,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -8743,7 +8743,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -8760,7 +8760,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -8777,7 +8777,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -8795,7 +8795,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -8812,7 +8812,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", @@ -8833,7 +8833,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "audio_decoder_unittests", @@ -8850,7 +8850,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_audio_unittests", @@ -8867,7 +8867,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "common_video_unittests", @@ -8884,7 +8884,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "dcsctp_unittests", @@ -8901,7 +8901,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 2 }, @@ -8919,7 +8919,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -8937,7 +8937,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -8955,7 +8955,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_media_unittests", @@ -8972,7 +8972,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_pc_unittests", @@ -8989,7 +8989,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "rtc_stats_unittests", @@ -9006,7 +9006,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 6 }, @@ -9024,7 +9024,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "slow_peer_connection_unittests", @@ -9041,7 +9041,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -9059,7 +9059,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "system_wrappers_unittests", @@ -9076,7 +9076,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "test_support_unittests", @@ -9093,7 +9093,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "tools_unittests", @@ -9110,7 +9110,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" }, "shards": 4 }, @@ -9128,7 +9128,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "voip_unittests", @@ -9145,7 +9145,7 @@ "swarming": { "dimensions": { "cpu": "x86-64", - "os": "Ubuntu-20.04" + "os": "Ubuntu-22.04" } }, "test": "webrtc_nonparallel_tests", diff --git a/infra/specs/waterfalls.pyl b/infra/specs/waterfalls.pyl index 3521a9fee3..d41d761c40 100644 --- a/infra/specs/waterfalls.pyl +++ b/infra/specs/waterfalls.pyl @@ -70,7 +70,7 @@ 'os_type': 'linux', 'mixins': [ - 'linux-focal', 'x86-64', 'fuchsia-gtest-output', + 'linux-jammy', 'x86-64', 'fuchsia-gtest-output', 'resultdb-gtest-json-format' ], 'test_suites': { @@ -79,7 +79,7 @@ }, 'Linux (more configs)': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'more_configs_tests', }, @@ -127,7 +127,7 @@ }, 'Linux32 Debug': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, @@ -135,7 +135,7 @@ 'Linux32 Debug (ARM)': {}, 'Linux32 Release': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, @@ -144,7 +144,7 @@ 'Linux64 Builder': {}, 'Linux64 Debug': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'linux_tests', }, @@ -152,7 +152,7 @@ 'Linux64 Debug (ARM)': {}, 'Linux64 Release': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'linux_tests', }, @@ -420,7 +420,7 @@ 'os_type': 'linux', 'mixins': [ - 'linux-focal', 'x86-64', 'fuchsia-gtest-output', + 'linux-jammy', 'x86-64', 'fuchsia-gtest-output', 'resultdb-gtest-json-format' ], 'test_suites': { @@ -455,7 +455,7 @@ 'os_type': 'linux', 'mixins': [ - 'linux-focal', 'x86-64', 'resultdb-json-format', + 'linux-jammy', 'x86-64', 'resultdb-json-format', 'isolate_profile_data' ], 'test_suites': { @@ -464,7 +464,7 @@ }, 'linux_dbg': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'linux_tests', }, @@ -472,14 +472,14 @@ 'linux_libfuzzer_rel': {}, 'linux_memcheck': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'linux_tests', }, }, 'linux_more_configs': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'more_configs_tests', }, @@ -496,7 +496,7 @@ }, 'linux_rel': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'linux_desktop_tests_tryserver', }, @@ -527,14 +527,14 @@ }, 'linux_x86_dbg': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, }, 'linux_x86_rel': { 'os_type': 'linux', - 'mixins': ['linux-focal', 'x86-64', 'resultdb-json-format'], + 'mixins': ['linux-jammy', 'x86-64', 'resultdb-json-format'], 'test_suites': { 'isolated_scripts': 'desktop_tests', }, From 8bfc3e99a6bac2e9c0f9c5db620c177164e417fb Mon Sep 17 00:00:00 2001 From: Jeremy Leconte Date: Fri, 16 Feb 2024 10:45:53 +0100 Subject: [PATCH 157/170] Fix variant name for iOS simulator 17.4. Change-Id: I66b00b360d8eace858046d73f40c7eac57375e7d Bug: None Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339843 Reviewed-by: Mirko Bonadei Commit-Queue: Jeremy Leconte Cr-Commit-Position: refs/heads/main@{#41753} --- infra/specs/client.webrtc.json | 120 +++++++++++++++--------------- infra/specs/test_suites.pyl | 2 +- infra/specs/tryserver.webrtc.json | 120 +++++++++++++++--------------- infra/specs/variants.pyl | 6 +- 4 files changed, 124 insertions(+), 124 deletions(-) diff --git a/infra/specs/client.webrtc.json b/infra/specs/client.webrtc.json index a41c566bd8..c38b68b0d3 100644 --- a/infra/specs/client.webrtc.json +++ b/infra/specs/client.webrtc.json @@ -7959,7 +7959,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -7970,7 +7970,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "apprtcmobile_tests iPhone 14 17.0", + "name": "apprtcmobile_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -8001,7 +8001,7 @@ }, "test": "apprtcmobile_tests", "test_id_prefix": "ninja://examples:apprtcmobile_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -8106,7 +8106,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -8116,7 +8116,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "audio_decoder_unittests iPhone 14 17.0", + "name": "audio_decoder_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -8147,7 +8147,7 @@ }, "test": "audio_decoder_unittests", "test_id_prefix": "ninja://modules/audio_coding:audio_decoder_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -8250,7 +8250,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -8260,7 +8260,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "common_audio_unittests iPhone 14 17.0", + "name": "common_audio_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -8291,7 +8291,7 @@ }, "test": "common_audio_unittests", "test_id_prefix": "ninja://common_audio:common_audio_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -8394,7 +8394,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -8404,7 +8404,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "common_video_unittests iPhone 14 17.0", + "name": "common_video_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -8435,7 +8435,7 @@ }, "test": "common_video_unittests", "test_id_prefix": "ninja://common_video:common_video_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -8538,7 +8538,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -8548,7 +8548,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "dcsctp_unittests iPhone 14 17.0", + "name": "dcsctp_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -8579,7 +8579,7 @@ }, "test": "dcsctp_unittests", "test_id_prefix": "ninja://net/dcsctp:dcsctp_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -8682,7 +8682,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -8692,7 +8692,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "modules_tests iPhone 14 17.0", + "name": "modules_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -8724,7 +8724,7 @@ }, "test": "modules_tests", "test_id_prefix": "ninja://modules:modules_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -8829,7 +8829,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -8839,7 +8839,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "modules_unittests iPhone 14 17.0", + "name": "modules_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -8872,7 +8872,7 @@ }, "test": "modules_unittests", "test_id_prefix": "ninja://modules:modules_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -8979,7 +8979,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -8989,7 +8989,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_media_unittests iPhone 14 17.0", + "name": "rtc_media_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -9020,7 +9020,7 @@ }, "test": "rtc_media_unittests", "test_id_prefix": "ninja://media:rtc_media_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -9123,7 +9123,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -9133,7 +9133,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_pc_unittests iPhone 14 17.0", + "name": "rtc_pc_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -9164,7 +9164,7 @@ }, "test": "rtc_pc_unittests", "test_id_prefix": "ninja://pc:rtc_pc_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -9267,7 +9267,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -9277,7 +9277,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_stats_unittests iPhone 14 17.0", + "name": "rtc_stats_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -9308,7 +9308,7 @@ }, "test": "rtc_stats_unittests", "test_id_prefix": "ninja://stats:rtc_stats_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -9411,7 +9411,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -9421,7 +9421,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_unittests iPhone 14 17.0", + "name": "rtc_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -9453,7 +9453,7 @@ }, "test": "rtc_unittests", "test_id_prefix": "ninja://:rtc_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -9558,7 +9558,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -9569,7 +9569,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "sdk_framework_unittests iPhone 14 17.0", + "name": "sdk_framework_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -9600,7 +9600,7 @@ }, "test": "sdk_framework_unittests", "test_id_prefix": "ninja://sdk:sdk_framework_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -9705,7 +9705,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -9716,7 +9716,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "sdk_unittests iPhone 14 17.0", + "name": "sdk_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -9747,7 +9747,7 @@ }, "test": "sdk_unittests", "test_id_prefix": "ninja://sdk:sdk_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -9852,7 +9852,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -9862,7 +9862,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "svc_tests iPhone 14 17.0", + "name": "svc_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -9895,7 +9895,7 @@ }, "test": "svc_tests", "test_id_prefix": "ninja://pc:svc_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -10002,7 +10002,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -10012,7 +10012,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "system_wrappers_unittests iPhone 14 17.0", + "name": "system_wrappers_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -10043,7 +10043,7 @@ }, "test": "system_wrappers_unittests", "test_id_prefix": "ninja://system_wrappers:system_wrappers_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -10146,7 +10146,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -10156,7 +10156,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "test_support_unittests iPhone 14 17.0", + "name": "test_support_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -10187,7 +10187,7 @@ }, "test": "test_support_unittests", "test_id_prefix": "ninja://test:test_support_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -10290,7 +10290,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -10300,7 +10300,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "tools_unittests iPhone 14 17.0", + "name": "tools_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -10331,7 +10331,7 @@ }, "test": "tools_unittests", "test_id_prefix": "ninja://rtc_tools:tools_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -10434,7 +10434,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -10444,7 +10444,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "video_engine_tests iPhone 14 17.0", + "name": "video_engine_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -10476,7 +10476,7 @@ }, "test": "video_engine_tests", "test_id_prefix": "ninja://:video_engine_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -10581,7 +10581,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -10591,7 +10591,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "voip_unittests iPhone 14 17.0", + "name": "voip_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -10622,7 +10622,7 @@ }, "test": "voip_unittests", "test_id_prefix": "ninja://:voip_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -10725,7 +10725,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -10735,7 +10735,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "webrtc_nonparallel_tests iPhone 14 17.0", + "name": "webrtc_nonparallel_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -10766,7 +10766,7 @@ }, "test": "webrtc_nonparallel_tests", "test_id_prefix": "ninja://:webrtc_nonparallel_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ diff --git a/infra/specs/test_suites.pyl b/infra/specs/test_suites.pyl index e6d98748c7..b292fc11fe 100644 --- a/infra/specs/test_suites.pyl +++ b/infra/specs/test_suites.pyl @@ -263,7 +263,7 @@ 'variants': [ 'SIM_IPHONE_X_15_5', 'SIM_IPHONE_X_16_4', - 'SIM_IPHONE_14_17_0', + 'SIM_IPHONE_14_17_4', ], }, }, diff --git a/infra/specs/tryserver.webrtc.json b/infra/specs/tryserver.webrtc.json index a4f33da2ef..41af426aeb 100644 --- a/infra/specs/tryserver.webrtc.json +++ b/infra/specs/tryserver.webrtc.json @@ -2321,7 +2321,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -2332,7 +2332,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "apprtcmobile_tests iPhone 14 17.0", + "name": "apprtcmobile_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -2363,7 +2363,7 @@ }, "test": "apprtcmobile_tests", "test_id_prefix": "ninja://examples:apprtcmobile_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -2468,7 +2468,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -2478,7 +2478,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "audio_decoder_unittests iPhone 14 17.0", + "name": "audio_decoder_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -2509,7 +2509,7 @@ }, "test": "audio_decoder_unittests", "test_id_prefix": "ninja://modules/audio_coding:audio_decoder_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -2612,7 +2612,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -2622,7 +2622,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "common_audio_unittests iPhone 14 17.0", + "name": "common_audio_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -2653,7 +2653,7 @@ }, "test": "common_audio_unittests", "test_id_prefix": "ninja://common_audio:common_audio_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -2756,7 +2756,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -2766,7 +2766,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "common_video_unittests iPhone 14 17.0", + "name": "common_video_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -2797,7 +2797,7 @@ }, "test": "common_video_unittests", "test_id_prefix": "ninja://common_video:common_video_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -2900,7 +2900,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -2910,7 +2910,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "dcsctp_unittests iPhone 14 17.0", + "name": "dcsctp_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -2941,7 +2941,7 @@ }, "test": "dcsctp_unittests", "test_id_prefix": "ninja://net/dcsctp:dcsctp_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -3044,7 +3044,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -3054,7 +3054,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "modules_tests iPhone 14 17.0", + "name": "modules_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -3086,7 +3086,7 @@ }, "test": "modules_tests", "test_id_prefix": "ninja://modules:modules_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -3191,7 +3191,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -3201,7 +3201,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "modules_unittests iPhone 14 17.0", + "name": "modules_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -3234,7 +3234,7 @@ }, "test": "modules_unittests", "test_id_prefix": "ninja://modules:modules_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -3341,7 +3341,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -3351,7 +3351,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_media_unittests iPhone 14 17.0", + "name": "rtc_media_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -3382,7 +3382,7 @@ }, "test": "rtc_media_unittests", "test_id_prefix": "ninja://media:rtc_media_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -3485,7 +3485,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -3495,7 +3495,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_pc_unittests iPhone 14 17.0", + "name": "rtc_pc_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -3526,7 +3526,7 @@ }, "test": "rtc_pc_unittests", "test_id_prefix": "ninja://pc:rtc_pc_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -3629,7 +3629,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -3639,7 +3639,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_stats_unittests iPhone 14 17.0", + "name": "rtc_stats_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -3670,7 +3670,7 @@ }, "test": "rtc_stats_unittests", "test_id_prefix": "ninja://stats:rtc_stats_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -3773,7 +3773,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -3783,7 +3783,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "rtc_unittests iPhone 14 17.0", + "name": "rtc_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -3815,7 +3815,7 @@ }, "test": "rtc_unittests", "test_id_prefix": "ninja://:rtc_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -3920,7 +3920,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -3931,7 +3931,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "sdk_framework_unittests iPhone 14 17.0", + "name": "sdk_framework_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -3962,7 +3962,7 @@ }, "test": "sdk_framework_unittests", "test_id_prefix": "ninja://sdk:sdk_framework_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -4067,7 +4067,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -4078,7 +4078,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "sdk_unittests iPhone 14 17.0", + "name": "sdk_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -4109,7 +4109,7 @@ }, "test": "sdk_unittests", "test_id_prefix": "ninja://sdk:sdk_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -4214,7 +4214,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -4224,7 +4224,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "svc_tests iPhone 14 17.0", + "name": "svc_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -4257,7 +4257,7 @@ }, "test": "svc_tests", "test_id_prefix": "ninja://pc:svc_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -4364,7 +4364,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -4374,7 +4374,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "system_wrappers_unittests iPhone 14 17.0", + "name": "system_wrappers_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -4405,7 +4405,7 @@ }, "test": "system_wrappers_unittests", "test_id_prefix": "ninja://system_wrappers:system_wrappers_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -4508,7 +4508,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -4518,7 +4518,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "test_support_unittests iPhone 14 17.0", + "name": "test_support_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -4549,7 +4549,7 @@ }, "test": "test_support_unittests", "test_id_prefix": "ninja://test:test_support_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -4652,7 +4652,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -4662,7 +4662,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "tools_unittests iPhone 14 17.0", + "name": "tools_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -4693,7 +4693,7 @@ }, "test": "tools_unittests", "test_id_prefix": "ninja://rtc_tools:tools_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -4796,7 +4796,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -4806,7 +4806,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "video_engine_tests iPhone 14 17.0", + "name": "video_engine_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -4838,7 +4838,7 @@ }, "test": "video_engine_tests", "test_id_prefix": "ninja://:video_engine_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -4943,7 +4943,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -4953,7 +4953,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "voip_unittests iPhone 14 17.0", + "name": "voip_unittests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -4984,7 +4984,7 @@ }, "test": "voip_unittests", "test_id_prefix": "ninja://:voip_unittests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ @@ -5087,7 +5087,7 @@ "--platform", "iPhone 14", "--version", - "17.0", + "17.4", "--out-dir", "${ISOLATED_OUTDIR}", "--xctest", @@ -5097,7 +5097,7 @@ "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" }, - "name": "webrtc_nonparallel_tests iPhone 14 17.0", + "name": "webrtc_nonparallel_tests iPhone 14 17.4", "resultdb": { "enable": true, "has_native_resultdb_integration": true @@ -5128,7 +5128,7 @@ }, "test": "webrtc_nonparallel_tests", "test_id_prefix": "ninja://:webrtc_nonparallel_tests/", - "variant_id": "iPhone 14 17.0" + "variant_id": "iPhone 14 17.4" }, { "args": [ diff --git a/infra/specs/variants.pyl b/infra/specs/variants.pyl index 1554446155..690829c2b1 100644 --- a/infra/specs/variants.pyl +++ b/infra/specs/variants.pyl @@ -27,14 +27,14 @@ 'identifier': 'iPhone X 16.4', 'mixins': ['xcode_15_main', 'ios_runtime_cache_16_4'], }, - 'SIM_IPHONE_14_17_0': { + 'SIM_IPHONE_14_17_4': { 'args': [ '--platform', 'iPhone 14', '--version', - '17.0', + '17.4', ], - 'identifier': 'iPhone 14 17.0', + 'identifier': 'iPhone 14 17.4', 'mixins': ['xcode_15_main', 'ios_runtime_cache_17_4'], }, } From 54d9cd002cef2cc0401831ef22bc79d38f2d7548 Mon Sep 17 00:00:00 2001 From: Jeremy Leconte Date: Fri, 16 Feb 2024 12:30:00 +0100 Subject: [PATCH 158/170] Update iOS dimension to have more machines available. https://chrome-swarming.appspot.com/botlist?c=id&c=task&c=os&c=status&d=asc&f=pool%3Achrome.tests&f=device_status%3Aavailable&f=os%3AiOS-16.7.1&k=os&s=id Change-Id: I418dcb61d7661ef98122cdea6c691c4994e6afab Bug: None Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339866 Reviewed-by: Manashi Sarkar Reviewed-by: Jeremy Leconte Commit-Queue: Jeremy Leconte Cr-Commit-Position: refs/heads/main@{#41754} --- infra/specs/internal.client.webrtc.json | 40 ++++++++++++------------- infra/specs/mixins.pyl | 4 +-- infra/specs/mixins_webrtc.pyl | 4 +-- infra/specs/waterfalls.pyl | 4 +-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/infra/specs/internal.client.webrtc.json b/infra/specs/internal.client.webrtc.json index 3560abfacf..95d0caa8b2 100644 --- a/infra/specs/internal.client.webrtc.json +++ b/infra/specs/internal.client.webrtc.json @@ -29,7 +29,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -69,7 +69,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -110,7 +110,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "hard_timeout": 7200, @@ -153,7 +153,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -194,7 +194,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -234,7 +234,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -274,7 +274,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -314,7 +314,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -354,7 +354,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -394,7 +394,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -494,7 +494,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -534,7 +534,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -575,7 +575,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "hard_timeout": 7200, @@ -618,7 +618,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -659,7 +659,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -699,7 +699,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -739,7 +739,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -779,7 +779,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -819,7 +819,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ @@ -859,7 +859,7 @@ ], "dimensions": { "device_status": "available", - "os": "iOS-16.6", + "os": "iOS-16.7.1", "pool": "chrome.tests" }, "named_caches": [ diff --git a/infra/specs/mixins.pyl b/infra/specs/mixins.pyl index fd54de90fa..135621c3ea 100644 --- a/infra/specs/mixins.pyl +++ b/infra/specs/mixins.pyl @@ -58,10 +58,10 @@ 'has_native_resultdb_integration': True } }, - 'ios-device-16.6': { + 'ios-device-16.7': { 'swarming': { 'dimensions': { - 'os': 'iOS-16.6', + 'os': 'iOS-16.7.1', 'pool': 'chrome.tests', 'device_status': 'available' } diff --git a/infra/specs/mixins_webrtc.pyl b/infra/specs/mixins_webrtc.pyl index cd83ad2d9b..6ef5b41ffa 100644 --- a/infra/specs/mixins_webrtc.pyl +++ b/infra/specs/mixins_webrtc.pyl @@ -38,10 +38,10 @@ '--test-arg=--undefok=test_launcher_summary_output' ], }, - 'ios-device-16.6': { + 'ios-device-16.7': { 'swarming': { 'dimensions': { - 'os': 'iOS-16.6', + 'os': 'iOS-16.7.1', 'pool': 'chrome.tests', 'device_status': 'available' } diff --git a/infra/specs/waterfalls.pyl b/infra/specs/waterfalls.pyl index d41d761c40..3459541a96 100644 --- a/infra/specs/waterfalls.pyl +++ b/infra/specs/waterfalls.pyl @@ -322,7 +322,7 @@ 'machines': { 'iOS64 Debug': { 'mixins': [ - 'ios-device-16.6', 'webrtc-xctest', 'chrome-tester-service-account', + 'ios-device-16.7', 'webrtc-xctest', 'chrome-tester-service-account', 'xcode_15_main', 'mac_toolchain', 'has_native_resultdb_integration', 'out_dir_arg' ], @@ -345,7 +345,7 @@ }, 'iOS64 Release': { 'mixins': [ - 'ios-device-16.6', 'webrtc-xctest', 'chrome-tester-service-account', + 'ios-device-16.7', 'webrtc-xctest', 'chrome-tester-service-account', 'xcode_15_main', 'mac_toolchain', 'has_native_resultdb_integration', 'out_dir_arg' ], From 052bc3af924057df8e67e31893968f35f3c4ac30 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Fri, 16 Feb 2024 11:42:33 +0100 Subject: [PATCH 159/170] Field trial to control SVC frame dropping mode in libvpx VP9 encoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example: "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/Enabled,layer_drop_mode:1,max_consec_drop:7/" It is only possible to enable LAYER_DROP (layer_drop_mode=1) for now. All other modes are ignored. Max consecutive frame drops (max_consec_drop) value from the field is always applied if the field trial is enabled. LAYER_DROP requires flexible mode (is_flexible_mode_=true) which can be enabled by means of WebRTC-Vp9InterLayerPred: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/media/engine/webrtc_video_engine.cc;l=976 Bug: webrtc:15827, b/320629637 Change-Id: I9c4d4838b11547e608d863198b109cb1485902d6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/335041 Commit-Queue: Sergey Silkin Reviewed-by: Erik Språng Cr-Commit-Position: refs/heads/main@{#41755} --- experiments/field_trials.py | 3 + .../codecs/vp9/libvpx_vp9_encoder.cc | 46 +++++++- .../codecs/vp9/libvpx_vp9_encoder.h | 8 ++ .../codecs/vp9/test/vp9_impl_unittest.cc | 109 ++++++++++++++++++ 4 files changed, 160 insertions(+), 6 deletions(-) diff --git a/experiments/field_trials.py b/experiments/field_trials.py index 86066ec764..0273f89057 100755 --- a/experiments/field_trials.py +++ b/experiments/field_trials.py @@ -95,6 +95,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-LibaomAv1Encoder-MaxConsecFrameDrop', 'webrtc:15821', date(2024, 4, 1)), + FieldTrial('WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig', + 'webrtc:15827', + date(2024, 9, 1)), FieldTrial('WebRTC-Pacer-FastRetransmissions', 'chromium:1354491', date(2024, 4, 1)), diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc index b73fd100cf..20c29abc7c 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.cc @@ -266,7 +266,8 @@ LibvpxVp9Encoder::LibvpxVp9Encoder(const cricket::VideoCodec& codec, "Disabled")), performance_flags_(ParsePerformanceFlagsFromTrials(trials)), num_steady_state_frames_(0), - config_changed_(true) { + config_changed_(true), + svc_frame_drop_config_(ParseSvcFrameDropConfig(trials)) { codec_ = {}; memset(&svc_params_, 0, sizeof(vpx_svc_extra_cfg_t)); } @@ -924,11 +925,24 @@ int LibvpxVp9Encoder::InitAndSetControlSettings(const VideoCodec* inst) { svc_drop_frame_.framedrop_thresh[i] = config_->rc_dropframe_thresh; } } else { - // Configure encoder to drop entire superframe whenever it needs to drop - // a layer. This mode is preferred over per-layer dropping which causes - // quality flickering and is not compatible with RTP non-flexible mode. - svc_drop_frame_.framedrop_mode = FULL_SUPERFRAME_DROP; - svc_drop_frame_.max_consec_drop = std::numeric_limits::max(); + if (svc_frame_drop_config_.enabled && + svc_frame_drop_config_.layer_drop_mode == LAYER_DROP && + is_flexible_mode_ && svc_controller_ && + (inter_layer_pred_ == InterLayerPredMode::kOff || + inter_layer_pred_ == InterLayerPredMode::kOnKeyPic)) { + // SVC controller is required since it properly accounts for dropped + // refs (unlike SetReferences(), which assumes full superframe drop). + svc_drop_frame_.framedrop_mode = LAYER_DROP; + } else { + // Configure encoder to drop entire superframe whenever it needs to drop + // a layer. This mode is preferred over per-layer dropping which causes + // quality flickering and is not compatible with RTP non-flexible mode. + svc_drop_frame_.framedrop_mode = FULL_SUPERFRAME_DROP; + } + svc_drop_frame_.max_consec_drop = + svc_frame_drop_config_.enabled + ? svc_frame_drop_config_.max_consec_drop + : std::numeric_limits::max(); for (size_t i = 0; i < num_spatial_layers_; ++i) { svc_drop_frame_.framedrop_thresh[i] = config_->rc_dropframe_thresh; } @@ -1910,6 +1924,26 @@ LibvpxVp9Encoder::ParseQualityScalerConfig(const FieldTrialsView& trials) { return config; } +LibvpxVp9Encoder::SvcFrameDropConfig LibvpxVp9Encoder::ParseSvcFrameDropConfig( + const FieldTrialsView& trials) { + FieldTrialFlag enabled = FieldTrialFlag("Enabled"); + FieldTrialParameter layer_drop_mode("layer_drop_mode", + FULL_SUPERFRAME_DROP); + FieldTrialParameter max_consec_drop("max_consec_drop", + std::numeric_limits::max()); + ParseFieldTrial({&enabled, &layer_drop_mode, &max_consec_drop}, + trials.Lookup("WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig")); + SvcFrameDropConfig config; + config.enabled = enabled.Get(); + config.layer_drop_mode = layer_drop_mode.Get(); + config.max_consec_drop = max_consec_drop.Get(); + RTC_LOG(LS_INFO) << "Libvpx VP9 encoder SVC frame drop config: " + << (config.enabled ? "enabled" : "disabled") + << " layer_drop_mode " << config.layer_drop_mode + << " max_consec_drop " << config.max_consec_drop; + return config; +} + void LibvpxVp9Encoder::UpdatePerformanceFlags() { flat_map params_by_resolution; if (codec_.GetVideoEncoderComplexity() == diff --git a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h index 0474e7bc17..3ccaa5fa52 100644 --- a/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h +++ b/modules/video_coding/codecs/vp9/libvpx_vp9_encoder.h @@ -236,6 +236,14 @@ class LibvpxVp9Encoder : public VP9Encoder { bool config_changed_; const LibvpxVp9EncoderInfoSettings encoder_info_override_; + + const struct SvcFrameDropConfig { + bool enabled; + int layer_drop_mode; // SVC_LAYER_DROP_MODE + int max_consec_drop; + } svc_frame_drop_config_; + static SvcFrameDropConfig ParseSvcFrameDropConfig( + const FieldTrialsView& trials); }; } // namespace webrtc diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc index 993fd245ad..50e9cf2369 100644 --- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc +++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc @@ -2459,4 +2459,113 @@ TEST(Vp9SpeedSettingsTrialsTest, DefaultPerLayerFlagsWithSvc) { } } +struct SvcFrameDropConfigTestParameters { + bool flexible_mode; + absl::optional scalability_mode; + std::string field_trial; + int expected_framedrop_mode; + int expected_max_consec_drop; +}; + +class TestVp9ImplSvcFrameDropConfig + : public ::testing::TestWithParam {}; + +TEST_P(TestVp9ImplSvcFrameDropConfig, SvcFrameDropConfig) { + SvcFrameDropConfigTestParameters test_params = GetParam(); + auto* const vpx = new NiceMock(); + LibvpxVp9Encoder encoder( + cricket::CreateVideoCodec(cricket::kVp9CodecName), + absl::WrapUnique(vpx), + test::ExplicitKeyValueConfig(test_params.field_trial)); + + vpx_image_t img; + ON_CALL(*vpx, img_wrap).WillByDefault(GetWrapImageFunction(&img)); + + EXPECT_CALL(*vpx, + codec_control(_, VP9E_SET_SVC_FRAME_DROP_LAYER, + SafeMatcherCast(AllOf( + Field(&vpx_svc_frame_drop_t::framedrop_mode, + test_params.expected_framedrop_mode), + Field(&vpx_svc_frame_drop_t::max_consec_drop, + test_params.expected_max_consec_drop))))); + + VideoCodec settings = DefaultCodecSettings(); + settings.VP9()->flexibleMode = test_params.flexible_mode; + if (test_params.scalability_mode.has_value()) { + settings.SetScalabilityMode(*test_params.scalability_mode); + } + settings.VP9()->numberOfSpatialLayers = + 3; // to execute SVC code paths even when scalability_mode is not set. + + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder.InitEncode(&settings, kSettings)); +} + +INSTANTIATE_TEST_SUITE_P( + All, + TestVp9ImplSvcFrameDropConfig, + ::testing::Values( + // Flexible mode is disabled. Layer drop is not allowed. Ignore + // layer_drop_mode from field trial. + SvcFrameDropConfigTestParameters{ + .flexible_mode = false, + .scalability_mode = ScalabilityMode::kL3T3_KEY, + .field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/" + "Enabled,layer_drop_mode:1,max_consec_drop:7/", + .expected_framedrop_mode = FULL_SUPERFRAME_DROP, + .expected_max_consec_drop = 7}, + // Flexible mode is enabled but the field trial is not set. Use default + // settings. + SvcFrameDropConfigTestParameters{ + .flexible_mode = true, + .scalability_mode = ScalabilityMode::kL3T3_KEY, + .field_trial = "", + .expected_framedrop_mode = FULL_SUPERFRAME_DROP, + .expected_max_consec_drop = std::numeric_limits::max()}, + // Flexible mode is enabled but the field trial is disabled. Use default + // settings. + SvcFrameDropConfigTestParameters{ + .flexible_mode = true, + .scalability_mode = ScalabilityMode::kL3T3_KEY, + .field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/" + "Disabled,layer_drop_mode:1,max_consec_drop:7/", + .expected_framedrop_mode = FULL_SUPERFRAME_DROP, + .expected_max_consec_drop = std::numeric_limits::max()}, + // Flexible mode is enabled, layer drop is enabled, KSVC. Apply config + // from field trial. + SvcFrameDropConfigTestParameters{ + .flexible_mode = true, + .scalability_mode = ScalabilityMode::kL3T3_KEY, + .field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/" + "Enabled,layer_drop_mode:1,max_consec_drop:7/", + .expected_framedrop_mode = LAYER_DROP, + .expected_max_consec_drop = 7}, + // Flexible mode is enabled, layer drop is enabled, simulcast. Apply + // config from field trial. + SvcFrameDropConfigTestParameters{ + .flexible_mode = true, + .scalability_mode = ScalabilityMode::kS3T3, + .field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/" + "Enabled,layer_drop_mode:1,max_consec_drop:7/", + .expected_framedrop_mode = LAYER_DROP, + .expected_max_consec_drop = 7}, + // Flexible mode is enabled, layer drop is enabled, full SVC. Apply + // config from field trial. + SvcFrameDropConfigTestParameters{ + .flexible_mode = false, + .scalability_mode = ScalabilityMode::kL3T3, + .field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/" + "Enabled,layer_drop_mode:1,max_consec_drop:7/", + .expected_framedrop_mode = FULL_SUPERFRAME_DROP, + .expected_max_consec_drop = 7}, + // Flexible mode is enabled, layer-drop is enabled, scalability mode is + // not set (i.e., SVC controller is not enabled). Ignore layer_drop_mode + // from field trial. + SvcFrameDropConfigTestParameters{ + .flexible_mode = true, + .scalability_mode = absl::nullopt, + .field_trial = "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig/" + "Enabled,layer_drop_mode:1,max_consec_drop:7/", + .expected_framedrop_mode = FULL_SUPERFRAME_DROP, + .expected_max_consec_drop = 7})); + } // namespace webrtc From 600503ae26ae8bd4aed4dc85e39f0b3ba34d36dc Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Fri, 16 Feb 2024 20:11:13 -0800 Subject: [PATCH 160/170] Update WebRTC code version (2024-02-17T04:11:12). Bug: None Change-Id: I0c27fb3042201bfc36f9be003515f79303aa0d63 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339890 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41756} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index a30166bb11..8d7037d41d 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-16T04:14:44"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-17T04:11:12"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 0ba663c245d336997dc912ba11dd3add0c310e0c Mon Sep 17 00:00:00 2001 From: Tommi Date: Sat, 17 Feb 2024 12:41:42 +0100 Subject: [PATCH 161/170] Change a few uses of Candidate::type() to Candidate::type_name() Switch to type_name() for things like logging since `type()` will change to returning an enumeration value. The functional change that this has is that log statements and Connection::ToString() (used for logging) will contain "host" instead of "local" and "srflx" instead of "stun". Bug: webrtc:15846 Change-Id: I35c50d026e4578a25d51765d59c6f2e01b850c94 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339180 Reviewed-by: Harald Alvestrand Commit-Queue: Tomas Gunnarsson Cr-Commit-Position: refs/heads/main@{#41757} --- api/candidate.cc | 7 ++++--- p2p/base/connection.cc | 8 ++++---- p2p/base/p2p_transport_channel.cc | 3 ++- p2p/base/p2p_transport_channel_unittest.cc | 16 ++++++++-------- pc/peer_connection_ice_unittest.cc | 2 +- pc/rtc_stats_collector.cc | 16 +--------------- pc/webrtc_sdp.cc | 2 +- 7 files changed, 21 insertions(+), 33 deletions(-) diff --git a/api/candidate.cc b/api/candidate.cc index 8969b06583..0a1c359002 100644 --- a/api/candidate.cc +++ b/api/candidate.cc @@ -112,9 +112,10 @@ std::string Candidate::ToStringInternal(bool sensitive) const { std::string related_address = sensitive ? related_address_.ToSensitiveString() : related_address_.ToString(); ost << "Cand[" << transport_name_ << ":" << foundation_ << ":" << component_ - << ":" << protocol_ << ":" << priority_ << ":" << address << ":" << type_ - << ":" << related_address << ":" << username_ << ":" << password_ << ":" - << network_id_ << ":" << network_cost_ << ":" << generation_ << "]"; + << ":" << protocol_ << ":" << priority_ << ":" << address << ":" + << type_name() << ":" << related_address << ":" << username_ << ":" + << password_ << ":" << network_id_ << ":" << network_cost_ << ":" + << generation_ << "]"; return ost.Release(); } diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc index 3809f12232..3f0c9c20b2 100644 --- a/p2p/base/connection.cc +++ b/p2p/base/connection.cc @@ -1330,11 +1330,11 @@ std::string Connection::ToString() const { const Candidate& local = local_candidate(); const Candidate& remote = remote_candidate(); ss << local.id() << ":" << local.component() << ":" << local.generation() - << ":" << local.type() << ":" << local.protocol() << ":" + << ":" << local.type_name() << ":" << local.protocol() << ":" << local.address().ToSensitiveString() << "->" << remote.id() << ":" - << remote.component() << ":" << remote.priority() << ":" << remote.type() - << ":" << remote.protocol() << ":" << remote.address().ToSensitiveString() - << "|"; + << remote.component() << ":" << remote.priority() << ":" + << remote.type_name() << ":" << remote.protocol() << ":" + << remote.address().ToSensitiveString() << "|"; ss << CONNECT_STATE_ABBREV[connected_] << RECEIVE_STATE_ABBREV[receiving_] << WRITE_STATE_ABBREV[write_state_] << ICESTATE[static_cast(state_)] diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc index 2f18f1dbb9..eb3553b52a 100644 --- a/p2p/base/p2p_transport_channel.cc +++ b/p2p/base/p2p_transport_channel.cc @@ -1416,7 +1416,8 @@ bool P2PTransportChannel::CreateConnection(PortInterface* port, if ((port->Type() != remote_candidate.type()) && (port->Type() == RELAY_PORT_TYPE || remote_candidate.is_relay())) { RTC_LOG(LS_INFO) << ToString() << ": skip creating connection " - << port->Type() << " to " << remote_candidate.type(); + << port->Type() << " to " + << remote_candidate.type_name(); return false; } } diff --git a/p2p/base/p2p_transport_channel_unittest.cc b/p2p/base/p2p_transport_channel_unittest.cc index 79e984cfec..b180ab8d2b 100644 --- a/p2p/base/p2p_transport_channel_unittest.cc +++ b/p2p/base/p2p_transport_channel_unittest.cc @@ -589,9 +589,9 @@ class P2PTransportChannelTestBase : public ::testing::Test, // on the local and remote candidate of ep1_ch1, match. This can be // used in an EXPECT_TRUE_WAIT. bool CheckCandidate1(const Result& expected) { - const std::string& local_type = LocalCandidate(ep1_ch1())->type(); + auto local_type = LocalCandidate(ep1_ch1())->type(); const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol(); - const std::string& remote_type = RemoteCandidate(ep1_ch1())->type(); + auto remote_type = RemoteCandidate(ep1_ch1())->type(); const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol(); return (local_protocol == expected.controlling_protocol && remote_protocol == expected.controlled_protocol && @@ -608,9 +608,9 @@ class P2PTransportChannelTestBase : public ::testing::Test, return; } - const std::string& local_type = LocalCandidate(ep1_ch1())->type(); + auto local_type = LocalCandidate(ep1_ch1())->type(); const std::string& local_protocol = LocalCandidate(ep1_ch1())->protocol(); - const std::string& remote_type = RemoteCandidate(ep1_ch1())->type(); + auto remote_type = RemoteCandidate(ep1_ch1())->type(); const std::string& remote_protocol = RemoteCandidate(ep1_ch1())->protocol(); EXPECT_EQ(expected.controlling_type, local_type); EXPECT_EQ(expected.controlled_type, remote_type); @@ -622,9 +622,9 @@ class P2PTransportChannelTestBase : public ::testing::Test, // on the local and remote candidate of ep2_ch1, match. This can be // used in an EXPECT_TRUE_WAIT. bool CheckCandidate2(const Result& expected) { - const std::string& local_type = LocalCandidate(ep2_ch1())->type(); + auto local_type = LocalCandidate(ep2_ch1())->type(); const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol(); - const std::string& remote_type = RemoteCandidate(ep2_ch1())->type(); + auto remote_type = RemoteCandidate(ep2_ch1())->type(); const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol(); return (local_protocol == expected.controlled_protocol && remote_protocol == expected.controlling_protocol && @@ -641,9 +641,9 @@ class P2PTransportChannelTestBase : public ::testing::Test, return; } - const std::string& local_type = LocalCandidate(ep2_ch1())->type(); + auto local_type = LocalCandidate(ep2_ch1())->type(); const std::string& local_protocol = LocalCandidate(ep2_ch1())->protocol(); - const std::string& remote_type = RemoteCandidate(ep2_ch1())->type(); + auto remote_type = RemoteCandidate(ep2_ch1())->type(); const std::string& remote_protocol = RemoteCandidate(ep2_ch1())->protocol(); EXPECT_EQ(expected.controlled_type, local_type); EXPECT_EQ(expected.controlling_type, remote_type); diff --git a/pc/peer_connection_ice_unittest.cc b/pc/peer_connection_ice_unittest.cc index bd4848cf8b..267cca4959 100644 --- a/pc/peer_connection_ice_unittest.cc +++ b/pc/peer_connection_ice_unittest.cc @@ -361,7 +361,7 @@ class PeerConnectionIceTest << " != " << b.address().ToString(); } if (a.type() != b.type()) { - failure_info << "\ntype: " << a.type() << " != " << b.type(); + failure_info << "\ntype: " << a.type_name() << " != " << b.type_name(); } std::string failure_info_str = failure_info.str(); if (failure_info_str.empty()) { diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index b9492c904b..a49e8ef0b2 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -164,19 +164,6 @@ std::string RTCMediaSourceStatsIDFromKindAndAttachment( return sb.str(); } -const char* CandidateTypeToRTCIceCandidateType(const cricket::Candidate& c) { - if (c.is_local()) - return "host"; - if (c.is_stun()) - return "srflx"; - if (c.is_prflx()) - return "prflx"; - if (c.is_relay()) - return "relay"; - RTC_DCHECK_NOTREACHED(); - return nullptr; -} - const char* DataStateToRTCDataChannelState( DataChannelInterface::DataState state) { switch (state) { @@ -998,8 +985,7 @@ const std::string& ProduceIceCandidateStats(Timestamp timestamp, candidate_stats->address = candidate.address().ipaddr().ToString(); candidate_stats->port = static_cast(candidate.address().port()); candidate_stats->protocol = candidate.protocol(); - candidate_stats->candidate_type = - CandidateTypeToRTCIceCandidateType(candidate); + candidate_stats->candidate_type = candidate.type_name(); candidate_stats->priority = static_cast(candidate.priority()); candidate_stats->foundation = candidate.foundation(); auto related_address = candidate.related_address(); diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc index 1069a18391..ea9c8580cd 100644 --- a/pc/webrtc_sdp.cc +++ b/pc/webrtc_sdp.cc @@ -1120,7 +1120,7 @@ bool ParseCandidate(absl::string_view message, return ParseFailed(first_line, "Unsupported transport type.", error); } - std::string candidate_type; + absl::string_view candidate_type; const absl::string_view type = fields[7]; if (type == kCandidateHost) { candidate_type = cricket::LOCAL_PORT_TYPE; From c49da7a58be7a9e96dbb61805b3bfa7cb7387fbd Mon Sep 17 00:00:00 2001 From: webrtc-version-updater Date: Sat, 17 Feb 2024 20:06:35 -0800 Subject: [PATCH 162/170] Update WebRTC code version (2024-02-18T04:06:34). Bug: None Change-Id: I870b164cf955e97a1d999f0cdad393ad5a2425c3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339925 Bot-Commit: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Commit-Queue: webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com Cr-Commit-Position: refs/heads/main@{#41758} --- call/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/call/version.cc b/call/version.cc index 8d7037d41d..9b1f88ad87 100644 --- a/call/version.cc +++ b/call/version.cc @@ -13,7 +13,7 @@ namespace webrtc { // The timestamp is always in UTC. -const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-17T04:11:12"; +const char* const kSourceTimestamp = "WebRTC source stamp 2024-02-18T04:06:34"; void LoadWebRTCVersionInRegister() { // Using volatile to instruct the compiler to not optimize `p` away even From 2bfb5db548f1576ba0de5b4f495621ec18d314fd Mon Sep 17 00:00:00 2001 From: Victor Boivie Date: Fri, 26 Jan 2024 15:19:41 +0100 Subject: [PATCH 163/170] dcsctp: Update zero checksum option to v-06 draft https://datatracker.ietf.org/doc/draft-ietf-tsvwg-sctp-zero-checksum/06/ The previous implementation was for version 00, and since then changes have been made. The chunk that is used to negotiate this capability has now grown to include an additional property - the sender's alternate error detection method. Bug: webrtc:14997 Change-Id: I78043d187b79f40bbadbcba02eae6eedf54f30f9 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336380 Reviewed-by: Harald Alvestrand Commit-Queue: Victor Boivie Cr-Commit-Position: refs/heads/main@{#41759} --- ...ero_checksum_acceptable_chunk_parameter.cc | 28 ++++++++++----- ...zero_checksum_acceptable_chunk_parameter.h | 16 +++++++-- ...hecksum_acceptable_chunk_parameter_test.cc | 19 +++++++--- net/dcsctp/packet/sctp_packet.cc | 4 ++- net/dcsctp/packet/sctp_packet_test.cc | 26 +++++++++----- net/dcsctp/public/dcsctp_options.h | 15 ++++---- net/dcsctp/public/types.h | 21 +++++++++++ net/dcsctp/socket/capabilities.h | 2 +- net/dcsctp/socket/dcsctp_socket.cc | 25 +++++++++---- net/dcsctp/socket/dcsctp_socket_test.cc | 36 ++++++++++++++----- net/dcsctp/socket/heartbeat_handler_test.cc | 3 +- 11 files changed, 146 insertions(+), 49 deletions(-) diff --git a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc index 75f7d3c487..a846d6dff3 100644 --- a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc +++ b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.cc @@ -15,32 +15,44 @@ #include "absl/types/optional.h" #include "api/array_view.h" +#include "rtc_base/strings/string_builder.h" namespace dcsctp { // https://www.ietf.org/archive/id/draft-tuexen-tsvwg-sctp-zero-checksum-00.html#section-3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | Type = 0x8001 | Length = 4 | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Type = 0x8001 (suggested) | Length = 8 | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +// | Error Detection Method Identifier (EDMID) | +// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ constexpr int ZeroChecksumAcceptableChunkParameter::kType; absl::optional ZeroChecksumAcceptableChunkParameter::Parse( rtc::ArrayView data) { - if (!ParseTLV(data).has_value()) { + absl::optional> reader = ParseTLV(data); + if (!reader.has_value()) { return absl::nullopt; } - return ZeroChecksumAcceptableChunkParameter(); + + ZeroChecksumAlternateErrorDetectionMethod method(reader->Load32<4>()); + if (method == ZeroChecksumAlternateErrorDetectionMethod::None()) { + return absl::nullopt; + } + return ZeroChecksumAcceptableChunkParameter(method); } void ZeroChecksumAcceptableChunkParameter::SerializeTo( std::vector& out) const { - AllocateTLV(out); + BoundedByteWriter writer = AllocateTLV(out); + writer.Store32<4>(*error_detection_method_); } std::string ZeroChecksumAcceptableChunkParameter::ToString() const { - return "Zero Checksum Acceptable"; + rtc::StringBuilder sb; + sb << "Zero Checksum Acceptable (" << *error_detection_method_ << ")"; + return sb.Release(); } } // namespace dcsctp diff --git a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h index 9ae2ec8280..18c98c95c6 100644 --- a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h +++ b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter.h @@ -19,13 +19,14 @@ #include "api/array_view.h" #include "net/dcsctp/packet/parameter/parameter.h" #include "net/dcsctp/packet/tlv_trait.h" +#include "net/dcsctp/public/types.h" namespace dcsctp { -// https://datatracker.ietf.org/doc/draft-tuexen-tsvwg-sctp-zero-checksum/ +// https://datatracker.ietf.org/doc/draft-ietf-tsvwg-sctp-zero-checksum/ struct ZeroChecksumAcceptableChunkParameterConfig : ParameterConfig { static constexpr int kType = 0x8001; - static constexpr size_t kHeaderSize = 4; + static constexpr size_t kHeaderSize = 8; static constexpr size_t kVariableLengthAlignment = 0; }; @@ -36,13 +37,22 @@ class ZeroChecksumAcceptableChunkParameter static constexpr int kType = ZeroChecksumAcceptableChunkParameterConfig::kType; - ZeroChecksumAcceptableChunkParameter() {} + explicit ZeroChecksumAcceptableChunkParameter( + ZeroChecksumAlternateErrorDetectionMethod error_detection_method) + : error_detection_method_(error_detection_method) {} static absl::optional Parse( rtc::ArrayView data); void SerializeTo(std::vector& out) const override; std::string ToString() const override; + + ZeroChecksumAlternateErrorDetectionMethod error_detection_method() const { + return error_detection_method_; + } + + private: + ZeroChecksumAlternateErrorDetectionMethod error_detection_method_; }; } // namespace dcsctp diff --git a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter_test.cc b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter_test.cc index 8a004e1788..861fa4d785 100644 --- a/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter_test.cc +++ b/net/dcsctp/packet/parameter/zero_checksum_acceptable_chunk_parameter_test.cc @@ -24,18 +24,28 @@ namespace { using ::testing::ElementsAre; TEST(ZeroChecksumAcceptableChunkParameterTest, SerializeAndDeserialize) { - ZeroChecksumAcceptableChunkParameter parameter; + ZeroChecksumAcceptableChunkParameter parameter( + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()); std::vector serialized; parameter.SerializeTo(serialized); - EXPECT_THAT(serialized, ElementsAre(0x80, 0x01, 0x00, 0x04)); + EXPECT_THAT(serialized, + ElementsAre(0x80, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01)); ASSERT_HAS_VALUE_AND_ASSIGN( ZeroChecksumAcceptableChunkParameter deserialized, ZeroChecksumAcceptableChunkParameter::Parse(serialized)); } +TEST(ZeroChecksumAcceptableChunkParameterTest, FailToDeserializePrevVersion) { + // This is how the draft described the chunk as, in version 00. + std::vector invalid = {0x80, 0x01, 0x00, 0x04}; + + EXPECT_FALSE( + ZeroChecksumAcceptableChunkParameter::Parse(invalid).has_value()); +} + TEST(ZeroChecksumAcceptableChunkParameterTest, FailToDeserialize) { std::vector invalid = {0x00, 0x00, 0x00, 0x00}; @@ -44,9 +54,10 @@ TEST(ZeroChecksumAcceptableChunkParameterTest, FailToDeserialize) { } TEST(ZeroChecksumAcceptableChunkParameterTest, HasToString) { - ZeroChecksumAcceptableChunkParameter parameter; + ZeroChecksumAcceptableChunkParameter parameter( + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()); - EXPECT_EQ(parameter.ToString(), "Zero Checksum Acceptable"); + EXPECT_EQ(parameter.ToString(), "Zero Checksum Acceptable (1)"); } } // namespace diff --git a/net/dcsctp/packet/sctp_packet.cc b/net/dcsctp/packet/sctp_packet.cc index de407bb4c7..978181fc2a 100644 --- a/net/dcsctp/packet/sctp_packet.cc +++ b/net/dcsctp/packet/sctp_packet.cc @@ -126,7 +126,9 @@ absl::optional SctpPacket::Parse(rtc::ArrayView data, std::vector(data.begin(), data.end()); if (options.disable_checksum_verification || - (options.enable_zero_checksum && common_header.checksum == 0u)) { + (options.zero_checksum_alternate_error_detection_method != + ZeroChecksumAlternateErrorDetectionMethod::None() && + common_header.checksum == 0u)) { // https://www.ietf.org/archive/id/draft-tuexen-tsvwg-sctp-zero-checksum-01.html#section-4.3: // If an end point has sent the Zero Checksum Acceptable Chunk Parameter in // an INIT or INIT ACK chunk, it MUST accept SCTP packets using an incorrect diff --git a/net/dcsctp/packet/sctp_packet_test.cc b/net/dcsctp/packet/sctp_packet_test.cc index fcdd161c0d..aab01df19c 100644 --- a/net/dcsctp/packet/sctp_packet_test.cc +++ b/net/dcsctp/packet/sctp_packet_test.cc @@ -38,7 +38,8 @@ using ::testing::SizeIs; constexpr VerificationTag kVerificationTag = VerificationTag(0x12345678); constexpr DcSctpOptions kVerifyChecksumOptions = DcSctpOptions{.disable_checksum_verification = false, - .enable_zero_checksum = false}; + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::None()}; TEST(SctpPacketTest, DeserializeSimplePacketFromCapture) { /* @@ -208,8 +209,10 @@ TEST(SctpPacketTest, DeserializePacketDontValidateChecksum) { ASSERT_HAS_VALUE_AND_ASSIGN( SctpPacket packet, - SctpPacket::Parse(data, {.disable_checksum_verification = true, - .enable_zero_checksum = false})); + SctpPacket::Parse( + data, {.disable_checksum_verification = true, + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::None()})); EXPECT_EQ(packet.common_header().source_port, 5000); EXPECT_EQ(packet.common_header().destination_port, 5000); EXPECT_EQ(packet.common_header().verification_tag, @@ -375,8 +378,11 @@ TEST(SctpPacketTest, AcceptsZeroSetZeroChecksum) { ASSERT_HAS_VALUE_AND_ASSIGN( SctpPacket packet, - SctpPacket::Parse(data, {.disable_checksum_verification = false, - .enable_zero_checksum = true})); + SctpPacket::Parse( + data, + {.disable_checksum_verification = false, + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()})); EXPECT_EQ(packet.common_header().source_port, 5000); EXPECT_EQ(packet.common_header().destination_port, 5000); EXPECT_EQ(packet.common_header().verification_tag, @@ -409,9 +415,13 @@ TEST(SctpPacketTest, RejectsNonZeroIncorrectChecksumWhenZeroChecksumIsActive) { 0x00, 0x00, 0x03, 0x00, 0x00, 0x10, 0x55, 0x08, 0x36, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - EXPECT_FALSE(SctpPacket::Parse(data, {.disable_checksum_verification = false, - .enable_zero_checksum = true}) - .has_value()); + EXPECT_FALSE( + SctpPacket::Parse( + data, + {.disable_checksum_verification = false, + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()}) + .has_value()); } TEST(SctpPacketTest, WritePacketWithCalculatedChecksum) { diff --git a/net/dcsctp/public/dcsctp_options.h b/net/dcsctp/public/dcsctp_options.h index d19798054c..600e8a362e 100644 --- a/net/dcsctp/public/dcsctp_options.h +++ b/net/dcsctp/public/dcsctp_options.h @@ -196,14 +196,13 @@ struct DcSctpOptions { // Disables SCTP packet crc32 verification. For fuzzers only! bool disable_checksum_verification = false; - // Controls the acceptance of zero checksum, as defined in - // https://datatracker.ietf.org/doc/draft-tuexen-tsvwg-sctp-zero-checksum/ - // This should only be enabled if the packet integrity can be ensured by lower - // layers, which DTLS will do in WebRTC, as defined by RFC8261. - // - // This will also enable sending packets without a checksum value (set to 0) - // once both peers have negotiated this feature. - bool enable_zero_checksum = false; + // Controls the "zero checksum option" feature, as defined in + // https://www.ietf.org/archive/id/draft-ietf-tsvwg-sctp-zero-checksum-06.html. + // To have this feature enabled, both peers must be configured to use the + // same (defined, not "none") alternate error detection method. + ZeroChecksumAlternateErrorDetectionMethod + zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::None(); }; } // namespace dcsctp diff --git a/net/dcsctp/public/types.h b/net/dcsctp/public/types.h index 02e2ce1e5e..1565cd7b58 100644 --- a/net/dcsctp/public/types.h +++ b/net/dcsctp/public/types.h @@ -151,6 +151,27 @@ class LifecycleId : public webrtc::StrongAlias { static constexpr LifecycleId NotSet() { return LifecycleId(0); } }; + +// To enable zero checksum feature, both peers must agree on which alternate +// error detection method that is used. See +// https://www.ietf.org/archive/id/draft-ietf-tsvwg-sctp-zero-checksum-06.html. +class ZeroChecksumAlternateErrorDetectionMethod + : public webrtc::StrongAlias< + class ZeroChecksumAlternateErrorDetectionMethodTag, + uint32_t> { + public: + constexpr explicit ZeroChecksumAlternateErrorDetectionMethod( + const UnderlyingType& v) + : webrtc::StrongAlias(v) {} + + static constexpr ZeroChecksumAlternateErrorDetectionMethod None() { + return ZeroChecksumAlternateErrorDetectionMethod(0); + } + static constexpr ZeroChecksumAlternateErrorDetectionMethod LowerLayerDtls() { + return ZeroChecksumAlternateErrorDetectionMethod(1); + } +}; } // namespace dcsctp #endif // NET_DCSCTP_PUBLIC_TYPES_H_ diff --git a/net/dcsctp/socket/capabilities.h b/net/dcsctp/socket/capabilities.h index 286509a40a..9b1bff0a90 100644 --- a/net/dcsctp/socket/capabilities.h +++ b/net/dcsctp/socket/capabilities.h @@ -21,7 +21,7 @@ struct Capabilities { bool message_interleaving = false; // RFC6525 Stream Reconfiguration bool reconfig = false; - // https://datatracker.ietf.org/doc/draft-tuexen-tsvwg-sctp-zero-checksum/ + // https://datatracker.ietf.org/doc/draft-ietf-tsvwg-sctp-zero-checksum/ bool zero_checksum = false; // Negotiated maximum incoming and outgoing stream count. uint16_t negotiated_maximum_incoming_streams = 0; diff --git a/net/dcsctp/socket/dcsctp_socket.cc b/net/dcsctp/socket/dcsctp_socket.cc index 98cd34a111..0667e6f899 100644 --- a/net/dcsctp/socket/dcsctp_socket.cc +++ b/net/dcsctp/socket/dcsctp_socket.cc @@ -22,7 +22,6 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" -#include "api/task_queue/task_queue_base.h" #include "net/dcsctp/packet/chunk/abort_chunk.h" #include "net/dcsctp/packet/chunk/chunk.h" #include "net/dcsctp/packet/chunk/cookie_ack_chunk.h" @@ -120,8 +119,12 @@ Capabilities ComputeCapabilities(const DcSctpOptions& options, capabilities.reconfig = true; } - if (options.enable_zero_checksum && - parameters.get().has_value()) { + if (options.zero_checksum_alternate_error_detection_method != + ZeroChecksumAlternateErrorDetectionMethod::None() && + parameters.get().has_value() && + parameters.get() + ->error_detection_method() == + options.zero_checksum_alternate_error_detection_method) { capabilities.zero_checksum = true; } @@ -134,6 +137,7 @@ Capabilities ComputeCapabilities(const DcSctpOptions& options, } void AddCapabilityParameters(const DcSctpOptions& options, + bool support_zero_checksum, Parameters::Builder& builder) { std::vector chunk_types = {ReConfigChunk::kType}; @@ -145,8 +149,11 @@ void AddCapabilityParameters(const DcSctpOptions& options, chunk_types.push_back(IDataChunk::kType); chunk_types.push_back(IForwardTsnChunk::kType); } - if (options.enable_zero_checksum) { - builder.Add(ZeroChecksumAcceptableChunkParameter()); + if (support_zero_checksum) { + RTC_DCHECK(options.zero_checksum_alternate_error_detection_method != + ZeroChecksumAlternateErrorDetectionMethod::None()); + builder.Add(ZeroChecksumAcceptableChunkParameter( + options.zero_checksum_alternate_error_detection_method)); } builder.Add(SupportedExtensionsParameter(std::move(chunk_types))); } @@ -282,7 +289,11 @@ void DcSctpSocket::SetState(State state, absl::string_view reason) { void DcSctpSocket::SendInit() { Parameters::Builder params_builder; - AddCapabilityParameters(options_, params_builder); + AddCapabilityParameters( + options_, /*support_zero_checksum=*/ + options_.zero_checksum_alternate_error_detection_method != + ZeroChecksumAlternateErrorDetectionMethod::None(), + params_builder); InitChunk init(/*initiate_tag=*/connect_params_.verification_tag, /*a_rwnd=*/options_.max_receiver_window_buffer_size, options_.announced_maximum_outgoing_streams, @@ -1227,7 +1238,7 @@ void DcSctpSocket::HandleInit(const CommonHeader& header, chunk->initial_tsn(), my_initial_tsn, chunk->a_rwnd(), tie_tag, capabilities) .Serialize())); - AddCapabilityParameters(options_, params_builder); + AddCapabilityParameters(options_, capabilities.zero_checksum, params_builder); InitAckChunk init_ack(/*initiate_tag=*/my_verification_tag, options_.max_receiver_window_buffer_size, diff --git a/net/dcsctp/socket/dcsctp_socket_test.cc b/net/dcsctp/socket/dcsctp_socket_test.cc index 413516bae0..dfe8ba60fe 100644 --- a/net/dcsctp/socket/dcsctp_socket_test.cc +++ b/net/dcsctp/socket/dcsctp_socket_test.cc @@ -2887,8 +2887,16 @@ TEST_P(DcSctpSocketParametrizedTest, ZeroChecksumMetricsAreSet) { std::vector> combinations = { {false, false}, {false, true}, {true, false}, {true, true}}; for (const auto& [a_enable, z_enable] : combinations) { - DcSctpOptions a_options = {.enable_zero_checksum = a_enable}; - DcSctpOptions z_options = {.enable_zero_checksum = z_enable}; + DcSctpOptions a_options = { + .zero_checksum_alternate_error_detection_method = + a_enable + ? ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls() + : ZeroChecksumAlternateErrorDetectionMethod::None()}; + DcSctpOptions z_options = { + .zero_checksum_alternate_error_detection_method = + z_enable + ? ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls() + : ZeroChecksumAlternateErrorDetectionMethod::None()}; SocketUnderTest a("A", a_options); auto z = std::make_unique("Z", z_options); @@ -2902,7 +2910,9 @@ TEST_P(DcSctpSocketParametrizedTest, ZeroChecksumMetricsAreSet) { } TEST(DcSctpSocketTest, AlwaysSendsInitWithNonZeroChecksum) { - DcSctpOptions options = {.enable_zero_checksum = true}; + DcSctpOptions options = { + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()}; SocketUnderTest a("A", options); a.socket.Connect(); @@ -2916,7 +2926,9 @@ TEST(DcSctpSocketTest, AlwaysSendsInitWithNonZeroChecksum) { } TEST(DcSctpSocketTest, MaySendInitAckWithZeroChecksum) { - DcSctpOptions options = {.enable_zero_checksum = true}; + DcSctpOptions options = { + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()}; SocketUnderTest a("A", options); SocketUnderTest z("Z", options); @@ -2933,7 +2945,9 @@ TEST(DcSctpSocketTest, MaySendInitAckWithZeroChecksum) { } TEST(DcSctpSocketTest, AlwaysSendsCookieEchoWithNonZeroChecksum) { - DcSctpOptions options = {.enable_zero_checksum = true}; + DcSctpOptions options = { + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()}; SocketUnderTest a("A", options); SocketUnderTest z("Z", options); @@ -2951,7 +2965,9 @@ TEST(DcSctpSocketTest, AlwaysSendsCookieEchoWithNonZeroChecksum) { } TEST(DcSctpSocketTest, SendsCookieAckWithZeroChecksum) { - DcSctpOptions options = {.enable_zero_checksum = true}; + DcSctpOptions options = { + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()}; SocketUnderTest a("A", options); SocketUnderTest z("Z", options); @@ -2970,7 +2986,9 @@ TEST(DcSctpSocketTest, SendsCookieAckWithZeroChecksum) { } TEST_P(DcSctpSocketParametrizedTest, SendsDataWithZeroChecksum) { - DcSctpOptions options = {.enable_zero_checksum = true}; + DcSctpOptions options = { + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()}; SocketUnderTest a("A", options); auto z = std::make_unique("Z", options); @@ -2993,7 +3011,9 @@ TEST_P(DcSctpSocketParametrizedTest, SendsDataWithZeroChecksum) { } TEST_P(DcSctpSocketParametrizedTest, AllPacketsAfterConnectHaveZeroChecksum) { - DcSctpOptions options = {.enable_zero_checksum = true}; + DcSctpOptions options = { + .zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::LowerLayerDtls()}; SocketUnderTest a("A", options); auto z = std::make_unique("Z", options); diff --git a/net/dcsctp/socket/heartbeat_handler_test.cc b/net/dcsctp/socket/heartbeat_handler_test.cc index 4475527322..b7f3a60d39 100644 --- a/net/dcsctp/socket/heartbeat_handler_test.cc +++ b/net/dcsctp/socket/heartbeat_handler_test.cc @@ -38,7 +38,8 @@ DcSctpOptions MakeOptions(DurationMs heartbeat_interval) { DcSctpOptions options; options.heartbeat_interval_include_rtt = false; options.heartbeat_interval = heartbeat_interval; - options.enable_zero_checksum = false; + options.zero_checksum_alternate_error_detection_method = + ZeroChecksumAlternateErrorDetectionMethod::None(); return options; } From d99da2c5f870c6677dfd43e008e670a3067aef8d Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Thu, 15 Feb 2024 16:29:52 +0100 Subject: [PATCH 164/170] Allow to use propagated field trials in VideoDecoderSoftwareFallbackWrapper Bug: webrtc:15791 Change-Id: Ida5e1c6f46e5aa9530af441b345abb80d2a5349e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339862 Commit-Queue: Danil Chapovalov Reviewed-by: Philip Eliasson Cr-Commit-Position: refs/heads/main@{#41760} --- api/video_codecs/BUILD.gn | 2 ++ api/video_codecs/test/BUILD.gn | 2 +- ...oder_software_fallback_wrapper_unittest.cc | 11 +++++---- ...video_decoder_software_fallback_wrapper.cc | 23 +++++++++++++++---- .../video_decoder_software_fallback_wrapper.h | 8 +++++++ 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn index 5bdd514a65..9f7022ca67 100644 --- a/api/video_codecs/BUILD.gn +++ b/api/video_codecs/BUILD.gn @@ -305,6 +305,8 @@ rtc_library("rtc_software_fallback_wrappers") { deps = [ ":video_codecs_api", "..:fec_controller_api", + "../../api:field_trials_view", + "../../api/environment", "../../api/transport:field_trial_based_config", "../../api/video:video_frame", "../../media:rtc_media_base", diff --git a/api/video_codecs/test/BUILD.gn b/api/video_codecs/test/BUILD.gn index d338406bc4..be897ae124 100644 --- a/api/video_codecs/test/BUILD.gn +++ b/api/video_codecs/test/BUILD.gn @@ -39,9 +39,9 @@ if (rtc_include_tests) { "../../../modules/video_coding:webrtc_vp8", "../../../rtc_base:checks", "../../../rtc_base:rtc_base_tests_utils", + "../../../test:explicit_key_value_config", "../../../test:fake_video_codecs", "../../../test:field_trial", - "../../../test:scoped_key_value_config", "../../../test:test_support", "../../../test:video_test_common", "../../environment", diff --git a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc index de9293bbe0..bd837605b0 100644 --- a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc +++ b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc @@ -22,8 +22,8 @@ #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_error_codes.h" #include "rtc_base/checks.h" +#include "test/explicit_key_value_config.h" #include "test/gtest.h" -#include "test/scoped_key_value_config.h" namespace webrtc { @@ -33,10 +33,11 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test { : VideoDecoderSoftwareFallbackWrapperTest("") {} explicit VideoDecoderSoftwareFallbackWrapperTest( const std::string& field_trials) - : override_field_trials_(field_trials), - env_(CreateEnvironment(&override_field_trials_)), + : field_trials_(field_trials), + env_(CreateEnvironment(&field_trials_)), fake_decoder_(new CountingFakeDecoder()), fallback_wrapper_(CreateVideoDecoderSoftwareFallbackWrapper( + env_, CreateVp8Decoder(env_), std::unique_ptr(fake_decoder_))) {} @@ -74,7 +75,7 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test { int release_count_ = 0; int reset_count_ = 0; }; - test::ScopedKeyValueConfig override_field_trials_; + test::ExplicitKeyValueConfig field_trials_; const Environment env_; // `fake_decoder_` is owned and released by `fallback_wrapper_`. CountingFakeDecoder* fake_decoder_; @@ -279,7 +280,7 @@ class ForcedSoftwareDecoderFallbackTest fake_decoder_ = new CountingFakeDecoder(); sw_fallback_decoder_ = new CountingFakeDecoder(); fallback_wrapper_ = CreateVideoDecoderSoftwareFallbackWrapper( - std::unique_ptr(sw_fallback_decoder_), + env_, std::unique_ptr(sw_fallback_decoder_), std::unique_ptr(fake_decoder_)); } diff --git a/api/video_codecs/video_decoder_software_fallback_wrapper.cc b/api/video_codecs/video_decoder_software_fallback_wrapper.cc index 2af4d39b3a..623888b9e2 100644 --- a/api/video_codecs/video_decoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_decoder_software_fallback_wrapper.cc @@ -16,6 +16,7 @@ #include #include +#include "api/field_trials_view.h" #include "api/video/encoded_image.h" #include "api/video_codecs/video_decoder.h" #include "modules/video_coding/include/video_error_codes.h" @@ -35,7 +36,8 @@ class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder { public: VideoDecoderSoftwareFallbackWrapper( std::unique_ptr sw_fallback_decoder, - std::unique_ptr hw_decoder); + std::unique_ptr hw_decoder, + bool force_sw_decoder_fallback); ~VideoDecoderSoftwareFallbackWrapper() override; bool Configure(const Settings& settings) override; @@ -67,6 +69,7 @@ class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder { } decoder_type_; std::unique_ptr hw_decoder_; + const bool force_sw_decoder_fallback_; Settings decoder_settings_; const std::unique_ptr fallback_decoder_; const std::string fallback_implementation_name_; @@ -77,9 +80,11 @@ class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder { VideoDecoderSoftwareFallbackWrapper::VideoDecoderSoftwareFallbackWrapper( std::unique_ptr sw_fallback_decoder, - std::unique_ptr hw_decoder) + std::unique_ptr hw_decoder, + bool force_sw_decoder_fallback) : decoder_type_(DecoderType::kNone), hw_decoder_(std::move(hw_decoder)), + force_sw_decoder_fallback_(force_sw_decoder_fallback), fallback_decoder_(std::move(sw_fallback_decoder)), fallback_implementation_name_( fallback_decoder_->GetDecoderInfo().implementation_name + @@ -94,7 +99,7 @@ VideoDecoderSoftwareFallbackWrapper::~VideoDecoderSoftwareFallbackWrapper() = bool VideoDecoderSoftwareFallbackWrapper::Configure(const Settings& settings) { decoder_settings_ = settings; - if (webrtc::field_trial::IsEnabled("WebRTC-Video-ForcedSwDecoderFallback")) { + if (force_sw_decoder_fallback_) { RTC_LOG(LS_INFO) << "Forced software decoder fallback enabled."; RTC_DCHECK(decoder_type_ == DecoderType::kNone); return InitFallbackDecoder(); @@ -276,10 +281,20 @@ VideoDecoder& VideoDecoderSoftwareFallbackWrapper::active_decoder() const { } // namespace std::unique_ptr CreateVideoDecoderSoftwareFallbackWrapper( + const Environment& env, std::unique_ptr sw_fallback_decoder, std::unique_ptr hw_decoder) { return std::make_unique( - std::move(sw_fallback_decoder), std::move(hw_decoder)); + std::move(sw_fallback_decoder), std::move(hw_decoder), + env.field_trials().IsEnabled("WebRTC-Video-ForcedSwDecoderFallback")); +} + +std::unique_ptr CreateVideoDecoderSoftwareFallbackWrapper( + std::unique_ptr sw_fallback_decoder, + std::unique_ptr hw_decoder) { + return std::make_unique( + std::move(sw_fallback_decoder), std::move(hw_decoder), + webrtc::field_trial::IsEnabled("WebRTC-Video-ForcedSwDecoderFallback")); } } // namespace webrtc diff --git a/api/video_codecs/video_decoder_software_fallback_wrapper.h b/api/video_codecs/video_decoder_software_fallback_wrapper.h index 3f44e02b26..4fbc9a0048 100644 --- a/api/video_codecs/video_decoder_software_fallback_wrapper.h +++ b/api/video_codecs/video_decoder_software_fallback_wrapper.h @@ -13,6 +13,7 @@ #include +#include "api/environment/environment.h" #include "api/video_codecs/video_decoder.h" #include "rtc_base/system/rtc_export.h" @@ -22,6 +23,13 @@ namespace webrtc { // software decoding when a hardware decoder fails to decode a stream due to // hardware restrictions, such as max resolution. RTC_EXPORT std::unique_ptr +CreateVideoDecoderSoftwareFallbackWrapper( + const Environment& env, + std::unique_ptr sw_fallback_decoder, + std::unique_ptr hw_decoder); + +// TODO: bugs.webrtc.org/15791 - Deprecated, remove when not used by chromium. +RTC_EXPORT std::unique_ptr CreateVideoDecoderSoftwareFallbackWrapper( std::unique_ptr sw_fallback_decoder, std::unique_ptr hw_decoder); From a75459d122c0ce8bec137107159e7d85ba57eff8 Mon Sep 17 00:00:00 2001 From: Mirko Bonadei Date: Mon, 19 Feb 2024 13:30:07 +0000 Subject: [PATCH 165/170] Add google-java-format to DEPS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: None Change-Id: Ib7e586e76ac91880930b9c9170a11e9daba6df64 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/340060 Commit-Queue: Mirko Bonadei Reviewed-by: Zoé Lepaul Commit-Queue: Zoé Lepaul Auto-Submit: Mirko Bonadei Cr-Commit-Position: refs/heads/main@{#41761} --- DEPS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/DEPS b/DEPS index 074d19ef94..84e12c12aa 100644 --- a/DEPS +++ b/DEPS @@ -379,6 +379,17 @@ deps = { 'dep_type': 'cipd', }, + 'src/third_party/google-java-format': { + 'packages': [ + { + 'package': 'chromium/third_party/google-java-format', + 'version': 'AQn4F5NfPAs_GKX-z3OW_Q7-yJ9N6tPrDnmnDScjkTEC', + }, + ], + 'condition': 'checkout_android or checkout_linux', + 'dep_type': 'cipd', + }, + 'src/third_party/hamcrest': { 'packages': [ { From bde80e3c0ec2be96189087cf36e254f9c4bfb144 Mon Sep 17 00:00:00 2001 From: Tommi Date: Sat, 17 Feb 2024 15:52:57 +0100 Subject: [PATCH 166/170] Deprecate Candidate::set_id(), offer generate_id() instead Bug: none Change-Id: I68df28a24446667c1bcde04120795fce54252feb Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339940 Commit-Queue: Tomas Gunnarsson Reviewed-by: Per Kjellander Cr-Commit-Position: refs/heads/main@{#41762} --- api/candidate.cc | 4 ++++ api/candidate.h | 6 +++++- api/candidate_unittest.cc | 8 +++++--- p2p/base/connection.cc | 3 +-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/api/candidate.cc b/api/candidate.cc index 0a1c359002..7718f94076 100644 --- a/api/candidate.cc +++ b/api/candidate.cc @@ -64,6 +64,10 @@ Candidate::Candidate(const Candidate&) = default; Candidate::~Candidate() = default; +void Candidate::generate_id() { + id_ = rtc::CreateRandomString(8); +} + bool Candidate::is_local() const { return type_ == LOCAL_PORT_TYPE; } diff --git a/api/candidate.h b/api/candidate.h index 101a3bd0a4..0aa75aa192 100644 --- a/api/candidate.h +++ b/api/candidate.h @@ -63,8 +63,12 @@ class RTC_EXPORT Candidate { Candidate(const Candidate&); ~Candidate(); + // 8 character long randomized ID string for logging purposes. const std::string& id() const { return id_; } - void set_id(absl::string_view id) { Assign(id_, id); } + // Generates a new, 8 character long, id. + void generate_id(); + // TODO(tommi): Callers should use generate_id(). Remove. + [[deprecated]] void set_id(absl::string_view id) { Assign(id_, id); } int component() const { return component_; } void set_component(int component) { component_ = component; } diff --git a/api/candidate_unittest.cc b/api/candidate_unittest.cc index fa512d6220..e52d448e72 100644 --- a/api/candidate_unittest.cc +++ b/api/candidate_unittest.cc @@ -20,9 +20,11 @@ namespace cricket { TEST(CandidateTest, Id) { Candidate c; EXPECT_EQ(c.id().size(), 8u); - std::string new_id = "12345678"; - c.set_id(new_id); - EXPECT_EQ(new_id, c.id()); + std::string current_id = c.id(); + // Generate a new ID. + c.generate_id(); + EXPECT_EQ(c.id().size(), 8u); + EXPECT_NE(current_id, c.id()); } TEST(CandidateTest, Component) { diff --git a/p2p/base/connection.cc b/p2p/base/connection.cc index 3f0c9c20b2..93a9a3f791 100644 --- a/p2p/base/connection.cc +++ b/p2p/base/connection.cc @@ -1689,10 +1689,9 @@ void Connection::MaybeUpdateLocalCandidate(StunRequest* request, return; } const uint32_t priority = priority_attr->value(); - std::string id = rtc::CreateRandomString(8); // Create a peer-reflexive candidate based on the local candidate. - local_candidate_.set_id(id); + local_candidate_.generate_id(); local_candidate_.set_type(PRFLX_PORT_TYPE); // Set the related address and foundation attributes before changing the // address. From 0355f455a48b141a8277442825ec776a74d66fb7 Mon Sep 17 00:00:00 2001 From: Danil Chapovalov Date: Mon, 19 Feb 2024 14:05:27 +0100 Subject: [PATCH 167/170] Use Environment propagated through android sdk This way VP8Decoder and DecoderFallback would use propagated instead of global field trials. Bug: webrtc:15791, webrtc:10335 Change-Id: I5ad5fae38f5b9379bc6376334562c154fbc56e39 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/340040 Reviewed-by: Sergey Silkin Auto-Submit: Danil Chapovalov Commit-Queue: Sergey Silkin Cr-Commit-Position: refs/heads/main@{#41763} --- sdk/android/BUILD.gn | 1 + sdk/android/api/org/webrtc/LibvpxVp8Decoder.java | 4 ++-- sdk/android/src/jni/video_decoder_fallback.cc | 6 ++++-- sdk/android/src/jni/vp8_codec.cc | 8 ++++++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index 13c27c0a44..87e76235ee 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -858,6 +858,7 @@ if (current_os == "linux" || is_android) { ":base_jni", ":generated_libvpx_vp8_jni", ":video_jni", + "../../api/environment", "../../modules/video_coding:webrtc_vp8", ] } diff --git a/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java b/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java index b3846f20fb..7d3e95973d 100644 --- a/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java +++ b/sdk/android/api/org/webrtc/LibvpxVp8Decoder.java @@ -13,8 +13,8 @@ package org.webrtc; public class LibvpxVp8Decoder extends WrappedNativeVideoDecoder { @Override public long createNative(long webrtcEnvRef) { - return nativeCreateDecoder(); + return nativeCreateDecoder(webrtcEnvRef); } - static native long nativeCreateDecoder(); + static native long nativeCreateDecoder(long webrtcEnvRef); } diff --git a/sdk/android/src/jni/video_decoder_fallback.cc b/sdk/android/src/jni/video_decoder_fallback.cc index 2688c59d0f..86d643de64 100644 --- a/sdk/android/src/jni/video_decoder_fallback.cc +++ b/sdk/android/src/jni/video_decoder_fallback.cc @@ -10,6 +10,7 @@ #include +#include "api/environment/environment.h" #include "api/video_codecs/video_decoder_software_fallback_wrapper.h" #include "sdk/android/generated_video_jni/VideoDecoderFallback_jni.h" #include "sdk/android/src/jni/jni_helpers.h" @@ -29,8 +30,9 @@ static jlong JNI_VideoDecoderFallback_Create( JavaToNativeVideoDecoder(jni, j_primary_decoder, j_webrtc_env_ref); VideoDecoder* native_wrapper = - CreateVideoDecoderSoftwareFallbackWrapper(std::move(fallback_decoder), - std::move(primary_decoder)) + CreateVideoDecoderSoftwareFallbackWrapper( + *reinterpret_cast(j_webrtc_env_ref), + std::move(fallback_decoder), std::move(primary_decoder)) .release(); return NativeToJavaPointer(native_wrapper); diff --git a/sdk/android/src/jni/vp8_codec.cc b/sdk/android/src/jni/vp8_codec.cc index 8b34495dc2..b33fece26e 100644 --- a/sdk/android/src/jni/vp8_codec.cc +++ b/sdk/android/src/jni/vp8_codec.cc @@ -10,6 +10,7 @@ #include +#include "api/environment/environment.h" #include "modules/video_coding/codecs/vp8/include/vp8.h" #include "sdk/android/generated_libvpx_vp8_jni/LibvpxVp8Decoder_jni.h" #include "sdk/android/generated_libvpx_vp8_jni/LibvpxVp8Encoder_jni.h" @@ -22,8 +23,11 @@ static jlong JNI_LibvpxVp8Encoder_CreateEncoder(JNIEnv* jni) { return jlongFromPointer(VP8Encoder::Create().release()); } -static jlong JNI_LibvpxVp8Decoder_CreateDecoder(JNIEnv* jni) { - return jlongFromPointer(VP8Decoder::Create().release()); +static jlong JNI_LibvpxVp8Decoder_CreateDecoder(JNIEnv* jni, + jlong j_webrtc_env_ref) { + return NativeToJavaPointer( + CreateVp8Decoder(*reinterpret_cast(j_webrtc_env_ref)) + .release()); } } // namespace jni From c026167f59bcf4b438d2235e452a76593d62c4e3 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Wed, 21 Feb 2024 10:35:54 +0100 Subject: [PATCH 168/170] [M123 merge] Limit max frame size in DAV1D decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 74a4038eaddcac773b9fc172ad446df6eb704b11) Bug: chromium:325284120 Change-Id: Iea0aea0a17bb0b1f73b3c1cbd408b7a6cd2b216e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/340180 Commit-Queue: Sergey Silkin Reviewed-by: Erik Språng Cr-Original-Commit-Position: refs/heads/main@{#41776} Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/340600 Reviewed-by: Philip Eliasson Commit-Queue: Erik Språng Cr-Commit-Position: refs/branch-heads/6312@{#1} Cr-Branched-From: 0355f455a48b141a8277442825ec776a74d66fb7-refs/heads/main@{#41763} --- modules/video_coding/codecs/av1/dav1d_decoder.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/video_coding/codecs/av1/dav1d_decoder.cc b/modules/video_coding/codecs/av1/dav1d_decoder.cc index 6a787ff935..d658e401e8 100644 --- a/modules/video_coding/codecs/av1/dav1d_decoder.cc +++ b/modules/video_coding/codecs/av1/dav1d_decoder.cc @@ -87,6 +87,8 @@ bool Dav1dDecoder::Configure(const Settings& settings) { s.n_threads = std::max(2, settings.number_of_cores()); s.max_frame_delay = 1; // For low latency decoding. s.all_layers = 0; // Don't output a frame for every spatial layer. + // Limit max frame size to avoid OOM'ing fuzzers. crbug.com/325284120. + s.frame_size_limit = 16384 * 16384; s.operating_point = 31; // Decode all operating points. return dav1d_open(&context_, &s) == 0; From 45e49ef5371ed67ee3278244248133bf9783d65c Mon Sep 17 00:00:00 2001 From: Philipp Hancke Date: Fri, 23 Feb 2024 08:11:56 +0100 Subject: [PATCH 169/170] [M123] Fix handling of rejected m-lines without transport description A fingerprint should not be required for m-lines which are rejected. BUG=chromium:326493639,webrtc:11066 (cherry picked from commit 845d6bef52ec08dfd9c87d3eff5ae5c07c3fe55d) Change-Id: I7428c91a144ca46650e13d72868f160652a98339 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/340322 Reviewed-by: Harald Alvestrand Reviewed-by: Florent Castelli Commit-Queue: Philipp Hancke Cr-Original-Commit-Position: refs/heads/main@{#41794} Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/341023 Cr-Commit-Position: refs/branch-heads/6312@{#2} Cr-Branched-From: 0355f455a48b141a8277442825ec776a74d66fb7-refs/heads/main@{#41763} --- pc/media_session.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pc/media_session.cc b/pc/media_session.cc index 4f63f3088f..3928088c7f 100644 --- a/pc/media_session.cc +++ b/pc/media_session.cc @@ -2174,12 +2174,12 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( } // If this section is part of a bundle, bundle_transport is non-null. // Then require_transport_attributes is false - we can handle sections - // without the DTLS parameters. Otherwise, transport attributes MUST - // be present. + // without the DTLS parameters. For rejected m-lines it does not matter. + // Otherwise, transport attributes MUST be present. std::unique_ptr transport = CreateTransportAnswer( media_description_options.mid, offer_description, media_description_options.transport_options, current_description, - bundle_transport == nullptr, ice_credentials); + !offer_content->rejected && bundle_transport == nullptr, ice_credentials); if (!transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, @@ -2272,7 +2272,7 @@ RTCError MediaSessionDescriptionFactory::AddDataContentForAnswer( std::unique_ptr data_transport = CreateTransportAnswer( media_description_options.mid, offer_description, media_description_options.transport_options, current_description, - bundle_transport != nullptr, ice_credentials); + !offer_content->rejected && bundle_transport == nullptr, ice_credentials); if (!data_transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, @@ -2344,10 +2344,11 @@ RTCError MediaSessionDescriptionFactory::AddUnsupportedContentForAnswer( SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { std::unique_ptr unsupported_transport = - CreateTransportAnswer(media_description_options.mid, offer_description, - media_description_options.transport_options, - current_description, bundle_transport != nullptr, - ice_credentials); + CreateTransportAnswer( + media_description_options.mid, offer_description, + media_description_options.transport_options, current_description, + !offer_content->rejected && bundle_transport == nullptr, + ice_credentials); if (!unsupported_transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, From 41b1493ddb5d98e9125d5cb002fd57ce76ebd8a7 Mon Sep 17 00:00:00 2001 From: Tommi Date: Fri, 23 Feb 2024 14:49:05 +0100 Subject: [PATCH 170/170] [M123 MERGE] Demote RTC_CHECK for sctp_mid() to RTC_LOG(LS_ERROR) if unavailable (cherry picked from commit efbfc40029b6986137f9179476955c263da7052a) Bug: chromium:326275823, chromium:325900490 Change-Id: Icfb8850867d1e39f23661422693da4f2829ecc57 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/340460 Reviewed-by: Evan Shrubsole Commit-Queue: Tomas Gunnarsson Cr-Original-Commit-Position: refs/heads/main@{#41793} No-Try: True Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/342560 Reviewed-by: Guido Urdaneta Commit-Queue: Florent Castelli Cr-Commit-Position: refs/branch-heads/6312@{#3} Cr-Branched-From: 0355f455a48b141a8277442825ec776a74d66fb7-refs/heads/main@{#41763} --- pc/sdp_offer_answer.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc index d75606ab4e..95d54978c7 100644 --- a/pc/sdp_offer_answer.cc +++ b/pc/sdp_offer_answer.cc @@ -4297,11 +4297,13 @@ void SdpOfferAnswerHandler::GetOptionsForUnifiedPlanOffer( GetMediaDescriptionOptionsForRejectedData(mid)); } else { const auto data_mid = pc_->sctp_mid(); - RTC_CHECK(data_mid); - if (mid == data_mid.value()) { + if (data_mid.has_value() && mid == data_mid.value()) { session_options->media_description_options.push_back( GetMediaDescriptionOptionsForActiveData(mid)); } else { + if (!data_mid.has_value()) { + RTC_LOG(LS_ERROR) << "Datachannel transport not available: " << mid; + } session_options->media_description_options.push_back( GetMediaDescriptionOptionsForRejectedData(mid)); }